DynamoDB オンデマンドスループットの実測
新規作成した DynamoDB オンデマンドテーブルはどれくらいのスループットを得られますか?
新規作成直後のオンデマンドテーブルは、秒間 4,000 回の書き込みを処理し続けます。これは AWS がドキュメントに記載している数値です。2026-08-27 に、数分前に作成したばかりのテーブルに対して実測したものです。
読み取りはスロットリングなしで秒間 12,762 回の結果整合性のある読み取りに達し、先に余力が尽きたのは負荷生成側でした。
これら 2 つの数値、そしてこのページのそれ以外すべては、実サービスに対するリクエストを数えた結果です。
手法、生データ、そして 3 回の失敗した試みはベンチマークの記事にまとめてあります。このページはその数値を収めたリファレンスです。
新規テーブルの書き込み上限
トラフィックを一度も受けたことのないテーブルに対し、30 秒単位のウィンドウで負荷を段階的に増やしました。以下の 2 つの表で、目標 は各ウィンドウに設定したレートです。
すべてのリクエストは一様ランダムなキーを持つ約 1 KB のアイテムだったので、ホットパーティションは関与していません:
| 目標 (書き込み/秒) | 達成 | スロットリングされたリクエスト |
|---|---|---|
| 1,000 | 1,000 | 0 |
| 2,000 | 2,000 | 0 |
| 3,000 | 3,000 | 0 |
| 4,000 | 4,000 | 0 |
| 5,000 | 4,132 | 25,992 |
| 6,000 | 4,131 | 55,966 |
| 8,000 | 4,134 | 115,922 |
書き込みでは、フリートはすべてのウィンドウで目標レートを全量送り、ドキュメントに書かれた秒間 4,000 回の書き込みというベースラインは成立しています。4,131~4,134 という達成レートは 30 秒間の平均値です。
9 月に 10 秒単位で再計測したところ、スロットリングが発生した各ステップは最初の 10 秒間が 4,400~4,480/秒で、その後は 4,000/秒前後でした。
10 秒間の 4,400~4,480 と 20 秒間の 4,000 を 30 秒で平均すると 4,133~4,160 になり、実測の 4,131~4,134 を挟む範囲になります。
レイテンシーは受け付けられた書き込みについてのみ計時しました。その p50 はリージョン内で 4~5 ms のままでした。例外は 8,000 のウィンドウでインフライト上限に達したランナー 1 台です(p50 78 ms、p99 1,327 ms)。
スロットリング時に返ってくるもの
最初の拒否は、5,000、6,000、8,000 の各ウィンドウの開始から 3.8 秒後、1.9 秒後、 0.9 秒後に発生しました。以下がそのままの内容です:
ThrottlingException: Throughput exceeds the current capacity of your table or index. DynamoDB is automatically scaling your table or index so please try again shortly. If exceptions persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.htmlこれは HTTP 400 であって 5xx ではありません。5xx だけを監視するリトライポリシーやアラームは、オンデマンドのスロットリングをまったく見逃します。SDK はデフォルトでこれをリトライします。指数バックオフを参照してください。
代わりに、テーブルの CloudWatch メトリクス ThrottledRequests、または
WriteThrottleEvents と ReadThrottleEvents にアラームを設定してください。どのメトリクスがどの原因を示すかはスロットリングのガイドで扱っています。
キーは一様ランダムだったので、ホットなキーは 1 つもありませんでした。ThrottlingException
では、AWS は発動した上限を示す throttlingReasons フィールドを付与しますが、今回の実行ではそれを記録していません。
読み取りの上限
読み取りは、1,000 件のアイテムをあらかじめ入れておいた別の新規テーブルに対して、結果整合性のある GetItem(約 1 KB、それぞれ 0.5 読み取りユニット)として実行しました:
| 目標 (読み取り/秒) | 達成 | スロットリングされたリクエスト |
|---|---|---|
| 4,000 | 4,000 | 0 |
| 8,000 | 7,941 | 0 |
| 12,000 | 11,119 | 0 |
| 16,000 | 12,762 | 0 |
どのレートでもスロットリングはゼロでした。DynamoDB はフリートが送ったすべての読み取りを受け付けました。
4,000/秒を超えると、ランナーがインフライト上限に達した(8 台のうち 1 台、2 台、そして 5 台)ため、フリートが送れたのは目標レートを下回る量でした。16,000 の設定でフリートが送り、DynamoDB が受け付けたのは秒間 12,762 回の読み取りです。
秒間 12,762 回の結果整合性のある読み取りは約 6,400 読み取りユニット/秒で、AWS が新規のオンデマンドテーブルに与える秒間 12,000 読み取りユニットのおよそ半分です(ウォームスループットのドキュメントは読み取りユニットで記載し、オンデマンドのページは "12,000 reads per second" と書いています)。
読み取りの上限には一度も到達しませんでした。上限に達していないランナーでは、読み取りの p50 はリージョン内で 2~10 ms でした。
持続負荷の下で上限はどう伸びるか
AWS は、オンデマンドは "instantly accommodates up to double the previous peak traffic on a table" とし、"throttling can occur if you exceed double your previous peak within 30 minutes." と述べています。
1 つの新規テーブルに秒間 8,000 回の書き込みを、8 分間のウェーブ 4 回で送りました。ウェーブ間の休止は 32~39 秒です:
| ウェーブ | 開始時刻 | 達成書き込み数/秒、1 分ごとの推移 |
|---|---|---|
| 1 | 06:06 UTC | 4,019 → 4,001 → 4,001 → 3,999 → 3,998 → 4,000 → 4,000 → 4,000 |
| 2 | 06:15 UTC | 5,046 → 5,000 → 4,996 → 4,990 → 4,991 → 4,998 → 4,992 → 4,993 |
| 3 | 06:24 UTC | 5,046 → 4,973 → 4,991 → 4,981 → 4,983 → 4,989 → 4,993 → 5,978 |
| 4 | 06:32 UTC | 7,006 → 6,991 → 6,979 → 6,996 → 6,991 → 6,988 → 7,002 → 6,990 |
タイムラインの読み方:
- 最初のウェーブは 4,000/秒にとどまりました。 ウェーブ 1 の 8 分間を通して、テーブルは開始時の 4,000/秒を処理しました。
- その後 3 回のステップが続きました。 経過分数はウェーブ 1 の開始から数えます。テーブルは 8.6 分(ウェーブ 2 の開始)で約 5,000/秒に、24.2 分(ウェーブ 3 の終盤)で約 6,000/秒に、25.8 分(ウェーブ 4 の開始)で約 7,000/秒に達しました。
- 3 回のステップのうち 2 回はウェーブの開始時、つまりアイドルの休止の直後に起きました。この 1 回の実行では、負荷下の時間と休止の影響を切り分けられません。
- 8,000/秒を処理することは一度もありませんでした。 実行は 33.8 分で終わり、その時点でテーブルは 7,000/秒でした。スロットリングされたリクエストはウェーブを追うごとに減り、190 万件から 50 万件になりました。
ローンチ当日のトラフィックが新規テーブルで秒間 4,000 回の書き込みを超えそうなら、先にそのテーブルの ウォームスループット(テーブルが即座に処理できるレート)を引き上げてください。
update-table に、新規テーブルなら create-table に、
--warm-throughput WriteUnitsPerSecond=N を渡します。AWS は増加したユニットごとに
1 回だけ課金します。
引き上げは非同期です。テーブルの WarmThroughput.Status が ACTIVE になるまで待ってください。一度引き上げたウォームスループットは下げられません。
各 GSI は独自のウォームスループットを持ちます。update-table では Update アクションを含む --global-secondary-index-updates、create-table では --global-secondary-indexes の各インデックスに WarmThroughput メンバーを指定します。
スロットリングされる GSI は、ベーステーブルへの書き込みもスロットリングさせます。
オンデマンドの最大スループットは別の設定です。AWS はベストエフォートでこれを適用し、バーストキャパシティが一時的にそれを超えることもあります。これはテーブルを事前にウォームアップするものではありません。
オンデマンド vs プロビジョンドのガイドではどちらのモードがどんなときに有利かを扱っており、オートスケーリングは、ここで自動的に起きるのを観察した現象の、プロビジョンドモード版の対応物です。
さらに 2 つの数値
- 新規テーブルは約 22 秒以内に
ACTIVEになりました。 待機処理は 20 秒ごとにポーリングしていたので、実際の時間はもっと短い可能性があります。 - 上限計測の実行コストは定価で約 0.49 ドルでした。 これは us-east-1 で受け付けられた 672,116 回の書き込みと 1,078,047 回の読み取りの分です。持続負荷の実行は約 6.33 ドルでした。Lambda、失敗した実行、事前の探りは別途かかります。このようなワークロードのコストは DynamoDB 料金計算ツールで見積もれます。
対象範囲と手法
以上はすべて、フェーズごとに 1 つのテーブルを 2026-08-27 または 28 に us-east-1 で 1 回計測したものに、10 秒間のバーストを確かめた 9 月の再計測 1 回を加えたもので、約 1 KB のアイテムと一様ランダムなキーを使っています。リトライはオフでした。SDK はデフォルトでスロットリングをリトライします。
パーティションごとの上限(秒間 3,000 読み取りユニット/1,000 書き込みユニット)には独自の失敗パターンがあります。アカウントレベルのクォータとハードなサービス上限は DynamoDB 上限リファレンスにあります。
DynamoDB を日常的に扱っているなら、DynoTable はそのために作られたデスクトップクライアントです。