Giselle の API に Rate Limit を実装するにあたり、PostgreSQL と Redis のどちらを使用すべきか検討しました。
前回の記事 Rate Limit アルゴリズムの比較と事例調査 では Fixed Window Counter アルゴリズムを採用することを決めました。今回は、そのストレージ層として PostgreSQL を選択した理由をご紹介します。
今回の PR feat(api/apps/run): add team-scoped rate limiting to App Run API · #2603 では、PostgreSQL を使用した Fixed Window Counter を実装しました。
| 観点 | PostgreSQL | Redis |
|---|---|---|
| レイテンシ | 1-10ms | 0.1-1ms |
| スループット | 数千 req/s | 数十万 req/s |
| 永続性 | デフォルトで永続 | 設定次第(揮発可能) |
| 運用コスト | 既存 DB を利用可能 | 追加インフラが必要 |
| 原子性 | トランザクション | シングルスレッド |
| スケール | 垂直スケール中心 | 水平スケール容易 |
| プラン | 制限 | 換算 |
|---|---|---|
| Pro | 300 req/min | 5 req/s |
| Team | 600 req/min | 10 req/s |
| Enterprise | 3000 req/min | 50 req/s |
この規模であれば PostgreSQL で十分処理可能です。
以下は概念的なサンプルコードです。
// 1 リクエストあたり既に複数の DB アクセスが発生
await authenticate() // DB: API キー検証
await enforceRateLimit() // DB: Rate Limit 適用 ← 今回追加
await loadApp() // DB: アプリ情報取得
await executeTask() // DB: タスク作成・実行このように、1 クエリ追加の影響は相対的に小さいと言えます。
現時点では PostgreSQL で問題ないと判断しました。
必要になってから最適化する(YAGNI 原則)のが適切なアプローチだと考えています。
以上、Rate Limit のストレージ選定で PostgreSQL と Redis を比較検討した、現場からお送りしました。