Lambda API設計ガイド
画面 API は Lambda で始めてよい。ただし「重い処理を同期で抱えない」が鉄則。処理時間・接続方式・トラフィック量で Lambda / ECS / Batch を切り分ける。
要約
結論 — 画面 API の CRUD は Lambda で問題ないことが多い。重い処理だけ SQS → Worker へ逃がす。
- Lambda 上限は 900 秒(15 分)。安全ラインは 10〜12 分(p95/p99 で見る)。
- 画面 API でユーザー待ちは 30 秒超を避ける(理想は数秒)。
- CRUD・Webhook・「受付だけ」の API → Lambda 向き。
- 長時間・常時接続・RDS 大量接続 → ECS / Batch 寄り。
- 定番パターン:
API Lambda→SQS→Worker(Lambda / ECS)
Lambda 実行時間の判断
次の表はバックグラウンド処理の目安です。
| 想定処理時間 | 判断 |
|---|---|
| 〜1 分 | Lambda と相性がよい |
| 1〜5 分 | Lambda で OK なことが多い |
| 5〜10 分 | Lambda でも可(要注意) |
| 10〜12 分 | ECS / AWS Batch / Step Functions を検討 |
| 12〜15 分 | Lambda は危険 |
| 15 分超 | Lambda 単体は不可 |
10〜12 分で切る理由
- データ量増・外部 API 遅延・DB 負荷で 15 分超えが起きやすい
- タイムアウト時のリトライ・途中結果の扱いが面倒
- p95 / p99・最大ケースで判断する(平均だけでは見落としやすい)
日次集計バッチの p99 が 11 分なら Lambda 継続は危険 — 日次集計バッチの p99 が 11 分なら Lambda 継続は危険。CloudWatch の Duration p99 を見て ECS RunTask へ移行し、ADR に「15 分上限回避」を残す。
同期 API vs バックグラウンド
画面で待たせる同期 API
ユーザーがスピナーを見ている時間の目安です。
| 処理時間 | 推奨 |
|---|---|
| 〜3 秒 | 同期 API で OK |
| 3〜10 秒 | 同期 API でも可 |
| 10〜30 秒 | 非同期ジョブ化を検討 |
| 30 秒超 | SQS 等へ非同期化 |
| 数分以上 | ECS / Batch / Step Functions |
バックグラウンド(CSV 取込・集計・画像処理など)
ユーザーは待たない処理。Lambda 15 分の枠内かどうかが論点になります。
| 処理時間 | 推奨 |
|---|---|
| 〜5 分 | Lambda で OK |
| 5〜10 分 | Lambda でも可 |
| 10 分超 | ECS Task / AWS Batch を検討 |
| 15 分超 | ECS / AWS Batch 確定 |
分超の用途別候補
| 用途 | おすすめ |
|---|---|
| 単発の重い処理 | ECS RunTask |
| 定期バッチ | EventBridge Scheduler → ECS RunTask |
| 大量データ処理 | AWS Batch |
| 複数ステップ | Step Functions + ECS/Lambda |
| キュー処理 | SQS → ECS Worker |
| 長時間常駐ワーカー | ECS Service |
画面 API の基本方針
次のような REST は Lambda 向きの典型です。
GET /me、GET /items、GET /items/{id}POST /items、PATCH /items/{id}、DELETE /items/{id}
画面 API の時間目安
| 処理時間 | 判断 |
|---|---|
| 〜1 秒 | 理想 |
| 1〜3 秒 | 普通に OK |
| 3〜10 秒 | やや重い。改善検討 |
| 10〜30 秒 | 非同期化を検討 |
| 30 秒超 | 画面 API として避けたい |
Lambda で注意する点
- RDS 中心 — 同時実行で接続が増える → RDS Proxy、接続再利用、同時実行上限
- 低遅延必須 — コールドスタートが効く → Provisioned Concurrency or コンテナ
- WebSocket / SSE / AI ストリーミング — 常時接続は ECS が自然
まず N+1 とインデックスを直す — まず N+1 とインデックスを直す。それでも 3 秒超ならキャッシュ(ElastiCache)または読み取り専用レプリカ。10 秒超なら同期 API として設計を見直す。
重い処理の非同期パターン
「エクスポート」「一括更新」ボタンは、この形にすると Lambda 単体の限界を避けられます。
flowchart LR
UI[画面] --> API[API Lambda 受付]
API --> DB1[(DB status=queued)]
API --> SQS[SQS]
SQS --> Worker[Worker Lambda/ECS]
Worker --> DB2[(DB status=done/failed)]
UI --> Poll[ポーリング or 通知]
Poll --> DB2
- API はジョブ受付だけ(
job_id発行) - DB に
status=queuedを保存 - SQS にメッセージを積む
- Worker が非同期処理
- フロントはポーリング or 通知で結果確認
{
"job_id": "job_123",
"status": "queued"
}
API 比較表(◯ / ✗)
ざっくり分類用です。境界ケースは Phase 3 の設計 docs で ADR に残してください。
| API の種類 | Lambda でよい | Lambda にしない方がよい | 理由 |
|---|---|---|---|
| GET /me | ◯ | ✗ | 短時間・ステートレス |
| CRUD 全般 | ◯ | ✗ | 数秒以内なら十分 |
| Webhook 受信 | ◯ | ✗ | 受付後に非同期化しやすい |
| CSV インポート受付 | ◯ | ✗ | 受付のみ Lambda、実処理は Worker |
| AI 処理の受付 | ◯ | ✗ | 推論本体は Worker へ |
| 30 秒以上の同期 API | ✗ | ◯ | ユーザーを待たせすぎる |
| 10 分以上の処理 | ✗ | ◯ | Lambda 上限に近い |
| 15 分超の処理 | ✗ | ◯ | Lambda 単体では不可 |
| 大量 CSV 同期処理 | ✗ | ◯ | データ量で時間が伸びる |
| RDS 大量接続 API | ✗ | ◯ | 同時実行で接続数が増える |
| WebSocket / SSE | ✗ | ◯ | 常時接続はコンテナ向き |
| Rails 本体 API | ✗ | ◯ | 常時起動コンテナが自然 |
| 大規模 FastAPI | △ | △ | 小〜中規模は Lambda 可、大規模は ECS |
判断軸まとめ
| 判断軸 | Lambda でよい | Lambda にしない方がよい |
|---|---|---|
| 処理時間 | 数秒以内 | 30 秒以上同期、10 分以上 |
| 状態 | ステートレス | 常時接続・長時間セッション |
| DB | DynamoDB 中心、軽い RDS | RDS 大量接続・複雑 TX |
| トラフィック | 低〜中、スパイクあり | 常時高トラフィック |
| 開発段階 | MVP / PoC / 管理画面 | 本格 SaaS 中核 API |
段階別アーキテクチャ
MVP / 初期プロダクト
- 画面 API の大半 → Lambda
- 重い処理 → SQS + Lambda Worker
- 15 分超 → ECS Task / AWS Batch
本格 SaaS / 業務システム
- 本体 API → ECS / Fargate
- 周辺処理 → Lambda
- 非同期処理 → SQS + Lambda/ECS Worker
MAU 10 万で RDS 接続が逼迫したら本体 REST は ECS Fargate… — MAU 10 万で RDS 接続が逼迫したら本体 REST は ECS Fargate へ移行。Webhook・夜間バッチは Lambda のまま、15 分超処理のみ Batch に切り出す。
設計思想 — 画面 API は Lambda で始める。重い処理は同期で抱えない。
Phase 2: 全部 Lambda + SQS Worker — Phase 2: 全部 Lambda + SQS Worker。MAU 10万で RDS 接続が逼迫 → 本体 API だけ ECS Fargate、Webhook・バッチは Lambda のまま、15分超バッチだけ Batch。