Step Functions vs SQS の組み合わせ — ワークフローオーケストレーションの選択基準
注文処理のように複数のステップが連なるバックエンド処理を作るとき、構造の選択肢は大きく 2 つです。Step Functions が全体の流れを指揮するか、各ステップが SQS のキューで次のステップに渡しながらつながっていくか。結論を先に書くと、分岐・リトライ・補償処理のある業務フロー、そして流れ全体を一目で見る必要がある処理は Step Functions、ステップが 1〜2 個だけの単純な非同期処理と大量イベントの消費は SQS + Lambda です。 料金差が数十倍あるためお金の問題に見えがちですが、実際の決定要素は失敗処理を誰が責任を持つかです。メッセージングサービス自体の選択は SQS vs SNS vs EventBridge で扱いました。料金は us-east-1 基準です。
一目でわかる比較 #
| 項目 | Step Functions Standard | Step Functions Express | SQS + Lambda チェーン |
|---|---|---|---|
| 課金単位 | 状態遷移 100 万件あたり約 $25 | 100 万実行あたり約 $1 + 実行時間 | 100 万リクエストあたり約 $0.40 |
| 最長実行 | 1 年 | 5 分 | 制限なし(キュー単位の連結) |
| 実行保証 | 厳密に 1 回 | 少なくとも 1 回 | 少なくとも 1 回 |
| 実行履歴・可視化 | ステップ別履歴 90 日 | CloudWatch Logs 経由 | なし(自前で構築) |
| リトライ・分岐・並列 | 宣言的に定義 | 宣言的に定義 | 各コンシューマーのコードに分散 |
| サービス直接統合 | 200 以上(Lambda なしで呼び出し) | 同じ | Lambda 必須 |
| 向いている形 | 業務フロー、サーガ、人の承認待ち | 高頻度の短いパイプライン | 単純な非同期、負荷の平準化 |
構造の差 — 指揮者がいるかどうか #
Step Functions はオーケストレーションです。フローの定義が 1 か所(ステートマシン)にあり、各ステップの成功・失敗・リトライ・分岐をその定義が決めます。実行ごとにどのステップまで進みどこで失敗したかが履歴に残り、コンソールで視覚的に見えます。リトライポリシーと catch 節は宣言するだけで済むため、失敗処理のコードが業務コードから分離されます。
SQS + Lambda チェーンはコレオグラフィです。全体の流れを知る主体がなく、各ステップが自分の仕事を終えたら次のキューにメッセージを入れる方式でつながります。構成要素はキューと関数だけなので単純で料金も低いですが、フローという概念自体がコードの外に存在しません。「この注文はいまどのステップにあるのか?」に答えるには相関 ID のログと追跡を自前で作る必要があり、3 番目のステップで失敗した処理を巻き戻す補償ロジックも各コンシューマーに散らばります。
ステップが 2 個以下で、失敗処理が「DLQ に入れて再処理」で足りるなら、コレオグラフィの単純さが勝ちます。ステップが増え、分岐が生まれ、部分的な失敗の巻き戻し(サーガパターン)が必要になった瞬間から、散らばったフローは保守コストとして返ってきます。経験則としては、キューを挟んだステップが 3 個を超えたらステートマシンに移す合図です。
料金 — 数十倍の差の実体 #
Standard ワークフローは状態遷移ごとの課金です。100 万遷移あたり約 $25 なので、5 ステップのワークフローを月 100 万回実行すると遷移 500 万件で約 $125 です。同じ処理を SQS チェーンで作れば、キューのリクエスト数百万件で数ドル程度です。この差のため、高頻度の処理に Standard を使うと請求書が目に見えて育ちます。
その間を埋めるのが Express ワークフローです。100 万実行あたり約 $1 に実行時間・メモリの料金が加わる構造で、短い高頻度パイプラインなら Standard の数十分の 1 まで下がります。上の例なら実行料金を合わせても数ドル台です。対価は制約です。最長 5 分、少なくとも 1 回の実行保証(冪等性が必要)、履歴は CloudWatch Logs 経由で、Standard のステップ別コンソール履歴ほど便利ではありません。
整理すると、料金の軸での選択は 3 枠です。人の承認待ちや長時間処理を含む低頻度の業務フローは Standard、5 分以内に終わる高頻度の自動パイプラインは Express、オーケストレーション自体が要らない処理は SQS です。Standard の料金が重く感じられたときの最初の検討対象は、SQS への書き換えではなく Express への移行です。
併用 — 対立ではなく組み合わせ #
実務の構成はどちらか一方ではなく、組み合わせであることが多いです。
- 入口は SQS、処理は Step Functions: キューで流入のスパイクを平準化し、コンシューマーがキューから取り出してステートマシンの実行を開始します。キューのバッファリングとステートマシンの可視性を同時に得ます。
- ステートマシンの中から SQS を呼ぶ: Step Functions は SQS への送信を直接統合として呼び出せるため、他のシステムに仕事を渡すステップを Lambda なしで作れます。コールバックトークン(waitForTaskToken)を使えば「メッセージを送って外部の処理が終わるまで待つ」ステップにもなります。
- 本流はステートマシン、付随作業はキュー: 注文確定という本流は Step Functions で指揮し、通知の送信のような失敗しても本流に影響しない付随作業はキューに流す分離が、料金と複雑さを同時に下げます。
選択の手順 #
- フローのステップ数と分岐をまず数えます: 2 ステップ以下の直線的な処理なら SQS + Lambda で十分です。3 ステップ以上、分岐・並列・補償が見えたら Step Functions の候補です。
- 失敗シナリオを書き出します: 「どこまで進んだか追跡する必要があるか、部分的な失敗を巻き戻す必要があるか」のどちらかに当てはまるならオーケストレーションが合います。DLQ の再処理で足りるならキューのチェーンです。
- Standard と Express を実行時間・頻度で分けます: 5 分超か人の待ちがあるなら Standard、短時間高頻度なら Express です。冪等性が確保できるかもこのとき確認します。
- 料金は遷移数で検算します: ステップ数 × 月間実行数 × $0.000025 が Standard の料金です。高頻度なのに Standard を使っているなら、Express への移行が最初の削減です。
- 流入の平準化が必要なら前にキューを置きます: スパイクの吸収はキューの仕事で、フローの指揮はステートマシンの仕事です。役割を分ければ両方が小さくなります。
まとめ #
- 決定要素は料金より失敗処理の責任の所在です。リトライ・分岐・補償・追跡が必要なら Step Functions、DLQ で足りる単純な非同期は SQS + Lambda です。
- Standard は状態遷移 100 万件あたり約 $25 と高いものの、1 年の実行、厳密に 1 回、ステップ別履歴が得られます。低頻度の業務フローのための料金です。
- Express は 100 万実行あたり約 $1 で Standard の数十分の 1 です。5 分以内の高頻度パイプラインなら Standard ではなく Express が正解です。
- キューを挟んだステップが 3 個を超えるあたりが、コレオグラフィの単純さが保守コストに逆転する合図です。
- 実務の正解は併用です。キューで平準化してステートマシンで指揮し、本流と付随作業を分離します。