
こんにちは。UPSIDERでエンジニアをしているkonnです。
2026年4月27日(月)に株式会社LayerX 東銀座オフィスおよびオンラインのハイブリッド形式で開催された「Background Job Talk 〜 Temporal 活用と独自実装の舞台裏編〜」に登壇しました。
このイベントは、UPSIDER / LayerX / メルカリの3社合同で開催された、非同期処理・バッチ・ワークフロー基盤をテーマにした勉強会です。
プロダクトが成長していくにつれて、非同期処理やバッチ処理はだんだん複雑になります。最初は単純なジョブキューや定期実行で十分だったものも、扱う業務が増え、処理の順序や失敗時のリカバリー、長期間にわたる状態管理が必要になると、設計・運用の難易度が一気に上がります。
今回はその中でも、UPSIDERの請求基盤チームで取り組んでいる「お金に関わるLong Running Processをどう安全に扱うか」というテーマで、「Temporalで実践するSagaとプロセスモデリング」というタイトルで発表しました。
発表の背景
UPSIDERの請求基盤チームでは、債権・入金・消込・帳簿といった複数のモジュールにまたがる処理を扱っています。
これらの処理は、単に「Aの次にBを実行する」というだけではありません。
たとえば、請求が作成され、支払期日を迎え、入金が行われ、消込が完了し、必要に応じて督促や通知が発生する。こうした一連の流れは、数秒で終わる処理ではなく、数日から数週間にわたって状態が変化し続ける業務プロセスです。
さらに、お金に関わる領域では、処理の抜け漏れや二重実行がユーザー影響に直結します。
「途中で失敗したらどう戻すのか」
「どこまで完了しているとみなすのか」
「再実行しても安全なのか」
「後から業務イベントが発生したとき、どの状態に遷移させるべきか」
こうした論点に向き合う必要がありました。
そこで、単なるバックグラウンドジョブとして処理を積むのではなく、業務プロセスそのものを明示的にモデリングし、SagaパターンとTemporalを組み合わせて扱うアプローチを採用しています。
なぜTemporalなのか
非同期処理の実装にはさまざまな選択肢があります。
メッセージキュー、バッチ、cron、独自の状態管理テーブル、ワーカーによるポーリングなど、これまでも多くのシステムで使われてきた手法があります。
一方で、請求や入金のような長期間続く業務プロセスでは、以下のような課題が出てきます。
- 処理がどこまで進んだのかを追跡しづらい
- リトライや補償処理の責務が各所に散らばる
- 状態遷移の意図がコードから読み取りづらい
- 障害復旧時に、何を再実行してよいのか判断が難しい
- 業務要件の変更に伴って分岐や例外処理が増え続ける
Temporalを使うことで、こうしたLong Running ProcessをWorkflowとして表現できます。
Workflowの中に、業務上の状態遷移、待機、シグナル受信、Activity実行、リトライ、補償処理を明示的に書けるため、「この業務プロセスが何をしているのか」をコードとして追いやすくなります。
もちろん、Temporalを導入すればすべてが自動的に解決するわけではありません。
むしろ重要なのは、「どの単位をWorkflowにするのか」「何をActivityとして切り出すのか」「どこで冪等性を担保するのか」「失敗時にどのような補償を行うのか」といった設計判断です。
今回の発表では、そのあたりの実戦的な設計論点を中心にお話ししました。
Sagaパターンをどう捉えたか
Sagaパターンは、分散トランザクションを扱うための考え方のひとつです。
複数の処理をまたいで一貫性を保ちたい場合、本来であればすべてを1つのトランザクションで扱えるとシンプルです。しかし、マイクロサービスや複数モジュールにまたがる処理では、単一のDBトランザクションで完結できないことが多くあります。
そのため、各ステップを小さなローカルトランザクションとして実行し、途中で失敗した場合には、必要に応じて補償処理を行うという考え方が必要になります。
請求・入金・消込・督促といった業務では、単純なロールバックでは表現できないケースが多くあります。
たとえば、一度外部に通知したものを「なかったこと」にするのは難しいですし、入金や消込の状態によっては、後続処理のキャンセルではなく、別の状態へ遷移させるほうが自然な場合もあります。
そのため、Sagaを「失敗したら逆順に戻す仕組み」としてだけ捉えるのではなく、「業務上、どの状態からどの状態へ遷移できるのか」「その遷移に対して、どの補償や後続処理が必要なのか」を整理するための設計手法として扱いました。
プロセスモデリングで意識したこと
今回特に意識したのは、技術的な処理フローではなく、業務プロセスを中心にモデリングすることです。
たとえば、単に「ジョブAを実行して、成功したらジョブBを実行する」と考えるのではなく、
- この債権は今どの状態なのか
- 次に発生しうる業務イベントは何か
- そのイベントが来たとき、どの状態へ遷移すべきか
- その遷移に伴って、どの副作用を発生させるべきか
- 途中で失敗した場合、再実行してよいのか、補償が必要なのか
といった観点で整理していきました。
TemporalのWorkflowは、こうした業務プロセスを表現するうえで相性がよいと感じています。
特に、一定時刻まで待機する、外部からのSignalを受け取る、処理を再開する、必要に応じてContinue-As-Newする、といったLong Running Process特有の要件を、Workflowの中で自然に扱える点が大きなメリットでした。
一方で、Workflowに何でも詰め込めばよいわけではありません。
業務判断としてWorkflowに書くべきことと、DB更新や外部API呼び出しとしてActivityに切り出すべきことを分ける必要があります。また、Activityは失敗やリトライを前提に設計する必要があるため、冪等性の担保も非常に重要です。
実装・運用で見えてきた論点
Temporalを使うことで、Long Running Processの見通しはかなり良くなりました。
一方で、実装・運用を進める中では、いくつかの論点も見えてきました。
まず、Workflowの責務をどう切るかです。 業務プロセスを素直に表現しようとすると、Workflowが大きくなりすぎることがあります。どこまでを1つのWorkflowとして扱い、どこからを別のWorkflowやActivityに分けるのかは、今でも悩みながら設計しています。
次に、冪等性です。
TemporalではActivityがリトライされることを前提に考える必要があります。つまり、同じActivityが複数回実行されても、結果として不整合が起きないように設計しなければなりません。特にお金に関わる処理では、二重実行や二重通知を防ぐための設計が欠かせません。
また、Event Historyの肥大化も考慮が必要です。
長期間動き続けるWorkflowでは、履歴が増え続けるため、Continue-As-Newをどこで使うかも設計上のポイントになります。ただし、Continue-As-Newを入れることで、Workflowの先頭処理が再実行されるように見えるケースもあるため、送信済み管理や状態管理の設計とセットで考える必要があります。
最後に、業務要件の変化への対応です。
支払期日の変更、消込の完了、通知タイミングの変更など、現実の業務では後からイベントが発生したり、状態が変わったりします。こうした変化をSignalや状態遷移としてどう扱うかは、Temporalらしい設計の面白さでもあり、難しさでもありました。
発表を通じて伝えたかったこと
今回の発表で一番伝えたかったのは、Temporalは「便利なジョブ実行基盤」ではなく、「業務プロセスをコードとして表現するための道具」として捉えると価値が出やすい、ということです。
もちろん、リトライやタイマー、ワーカー管理などの機能も強力です。
しかし、それ以上に重要なのは、複雑な業務プロセスをどう分解し、どの状態を明示し、どの失敗にどう備えるかを考えることだと思っています。
請求・入金・消込・督促のような領域では、技術的な正しさだけでなく、業務上の正しさが求められます。
「処理が成功した」とは何を意味するのか。
「失敗した」とき、何を取り消すべきなのか。
「再実行してよい」と判断できる条件は何か。
「ユーザーに影響を出さない」とは、具体的にどの状態を守ることなのか。
こうした問いを、WorkflowやActivity、Signal、補償処理という形で一つひとつコードに落としていくことが、Temporalを使ったプロセスモデリングの本質なのではないかと感じています。
当日のイベントについて
当日はUPSIDER、LayerX、メルカリの3社から、それぞれワークフロー基盤や非同期処理に関する発表がありました。
自分の発表ではSagaパターンとTemporalを使った請求基盤のプロセスモデリングについて話しましたが、他社の発表では、メッセージキュー型の非同期処理からTemporalへ移行する話や、内製ワークフローエンジンの設計・活用事例なども共有されました。
同じ「バックグラウンドジョブ」や「ワークフロー基盤」というテーマでも、各社の事業ドメインや組織フェーズによって、課題の出方や設計判断が異なるのが面白かったです。
懇親会でも、Temporalの導入判断、既存システムとの統合、監視や運用、冪等性の担保など、かなり実践的な話ができました。
こうしたリアルな設計・運用の話を、会社をまたいで共有できる場はとても貴重だと感じました。
PRチームへの感謝
最後に、今回のイベント開催にあたって尽力してくれたUPSIDERのPRチームに感謝を伝えたいです。
もともとは自分が「Temporalをテーマにしたイベントをやりたい」と話したことがきっかけでした。そこからPRチームが共催企業の皆さまとの調整や企画づくりを進めてくれて、今回のような3社合同イベントとして形にしてくれました。
自分ひとりでは、登壇資料を作って発表するところまでしかできなかったと思います。イベントとして成立させ、社外の方々にも参加していただける場にしてくれたのは、PRチームの皆さんのおかげです。本当にありがとうございました。
発表資料
当日の発表資料はこちらです。
おわりに
今回の登壇を通じて、TemporalやSagaパターンそのものだけでなく、「業務プロセスをどう捉え、どうコードに落とし込むか」について改めて整理するよい機会になりました。
UPSIDERでは、事業の成長に伴って、請求・債権・入金・消込・帳簿といった領域の複雑性もどんどん高まっています。
その中で、ユーザーに安心して使っていただける基盤を作るためには、単に処理を非同期化するだけではなく、失敗や再実行、長期的な状態遷移まで含めて設計する必要があります。
まだまだ試行錯誤中ですが、同じようにTemporalやワークフロー基盤、バックグラウンドジョブの設計に取り組んでいる方がいれば、ぜひ情報交換できるとうれしいです。
We Are Hiring !!
UPSIDERでは、複雑なお金のドメインに向き合いながら、堅牢でスケーラブルなプロダクト基盤を一緒につくる仲間を募集しています。
請求基盤、ワークフロー基盤、非同期処理、ドメインモデリング、Fintech領域のプロダクト開発に興味がある方は、ぜひお気軽にお話ししましょう。
UPSIDER Engineering Deckはこちら📣