DEV Community

Cover image for DynamoDB On-Demand vs Provisioned Capacity
DynoTable
DynoTable

Posted on • Edited on • Originally published at dynotable.com

DynamoDB On-Demand vs Provisioned Capacity

DynamoDB bills throughput two ways. On-Demand charges per request — you pay
for what you use, scaling to zero. Provisioned reserves a fixed read/write
rate you pay for whether you use it or not, at a much lower per-unit price. Picking
the wrong one is one of the easiest ways to overpay.

The audit log makes the choice concrete. Audit writes are spiky and
unpredictable
: quiet overnight, then a flood when a customer runs a bulk
operation or an incident generates thousands of events. That traffic shape is the
whole decision.

Should I use DynamoDB On-Demand or Provisioned capacity?

On-Demand charges per request and scales to zero, making it the safe default for
spiky, new, or unpredictable traffic. Provisioned reserves a fixed read/write rate
at a far lower per-unit price, winning only when sustained, steady traffic keeps
that reservation well-utilized. Pick On-Demand unless your volume is proven and
predictable.

  • On-Demand = pay per request, scales to zero. No capacity to plan; you pay a higher price per read/write but only when traffic happens.
  • Provisioned = reserve a steady rate, pay for it always. Much cheaper per unit if the rate is well-utilized; you eat the cost of idle capacity.
  • Spiky or unknown traffic calls for On-Demand. Steady, predictable, high-volume traffic calls for Provisioned (optionally with auto-scaling).
  • You can switch modes, but the limit is asymmetric: Provisioned to On-Demand is capped at four times per 24 hours, while On-Demand to Provisioned is unrestricted — it's not a per-request toggle.

The problem: paying for capacity you don't use

With Provisioned capacity you commit to, say, 1,000 write units per second. If the
audit log averages 50 writes/second but you provisioned for the incident-day peak,
you pay for 1,000 around the clock and use a twentieth of it. Provision for the
average instead and the incident-day flood throttles — writes get rejected.

So fixed capacity forces a bad trade on spiky traffic: overpay constantly, or
under-provision and drop writes when it matters most. On-Demand exists precisely to
remove that trade.

How the two modes work

On-Demand charges for the read and write request units you actually consume,
with no capacity to configure — it instantly accommodates spikes up to twice your
previous traffic peak and scales to zero
when idle. Beyond that 2x jump within a short window it can still throttle while it
ramps. You pay a premium per request for that elasticity.

Provisioned reserves a number of Read Capacity Units (RCU) and Write Capacity
Units (WCU) per second. The per-unit price is far lower, but you pay for the
reservation continuously, used or not. Exceed it and DynamoDB throttles unless
auto-scaling is enabled to grow capacity within configured bounds — though
auto-scaling reacts over minutes, so a sudden spike can still throttle before it
catches up.

The crossover is utilization. Roughly: if your sustained, predictable traffic
keeps Provisioned capacity well-utilized, Provisioned wins on price; if traffic is
spiky, bursty, or unknown, On-Demand wins by not charging for idle reservation.

DynamoDB On-Demand vs Provisioned Capacity

A worked example: the audit log's bill

The audit log writes ~50 events/second on average but bursts to thousands during
incidents, with read traffic far lower (compliance exports, the occasional
investigation). Each event is small — well under 1 KB.

On Provisioned, you'd have to reserve for the burst (paying for it 24/7) or risk
throttling the incident-day flood — the worst time to drop audit writes. On
On-Demand, the quiet hours cost almost nothing and a burst up to twice the recent
peak is absorbed without configuration; you pay for exactly the writes that
happened.

For this workload On-Demand is the right default. The general rule: start on
On-Demand for any new or spiky table, and only move to Provisioned once traffic is
proven steady enough to keep a reservation utilized.

Plug your own numbers in — reads/writes per second, item size, storage — to see
the two modes side by side for one region:

For the full multi-region picture with the free tier applied, use the
DynamoDB Pricing Calculator.

Do it in DynoTable

The capacity decision starts from real numbers: how big are the items, how many
are there, how fast are they being written. Guessing those is how tables end up
mis-provisioned.

To turn a sample event into the RCU/WCU it actually consumes, run it through the
item size calculator. Then ground the decision
in your real table: DynoTable surfaces its metadata — item count and size — and lets you
inspect representative items so you can size them accurately.

Browsing the audit-log table in DynoTable; the toolbar's item count and size are the inputs to a capacity-mode decision.

Pitfalls and next steps

  • Switching modes is rate-limited, and asymmetrically. Provisioned to On-Demand is capped at four switches per 24 hours; On-Demand to Provisioned is unrestricted. Treat it as a considered decision, not a dial you spin.
  • Auto-scaling isn't instant. It reacts over minutes, so a sharp spike on Provisioned can throttle before capacity grows. For genuinely bursty traffic, On-Demand handles the spike better — up to twice your previous peak instantly. If you know a spike will exceed that (a launch or sale), set warm throughput on the table ahead of time to pre-provision the burst headroom.
  • A hot partition throttles regardless of mode. Even On-Demand has per-partition limits — uneven keys can throttle while the table looks under capacity. See hot partitions.
  • GSIs have their own capacity. Each index is billed separately and can throttle base-table writes if under-provisioned — see why a GSI throttles base-table writes.

Capacity mode sets what you pay to run the table in one region. Next: replicating
it across regions with DynamoDB Global Tables.

Download DynoTable to read your table's real size and item count
before you commit to a capacity mode.

Top comments (0)