TL;DR: DynamoDB On-Demand bills per request — no provisioning, no capacity spreadsheets, and it scales up (and to zero) automatically. On bursty or unpredictable traffic that's quiet most of the day, it's routinely ~4× cheaper than provisioning for peak and removes throttling risk. The break-even is clean: if you'd run provisioned capacity consistently above ~27% utilization, provisioned (especially with reserved capacity) is cheaper. Below that, On-Demand wins.
The numbers
- On-Demand pricing (us-east-1): $1.25 per million write request units (WRU = 1 write ≤ 1 KB), $0.25 per million read request units (RRU = 1 strongly-consistent read ≤ 4 KB, or 2 eventually-consistent).
- Break-even ≈ 27% provisioned utilization — bursty workloads almost always sit below it.
- Worked example — 1M writes + 5M reads/day, bursty: On-Demand = 30M × $1.25/M + 150M × $0.25/M = $75/mo; provisioned for peak (300 WCU + 1,500 RCU 24/7) ≈ $284/mo — On-Demand is nearly 4× cheaper.
- No throttling within the default 40,000 WRU/RRU-per-second table limits; handles double your previous peak instantly.
- Mode switch: once per 24 hours per table — enough to flip around a known event.
Do this
- Default to On-Demand unless you have a specific reason not to — it kills over-provisioning waste, throttling surprises, and capacity planning in one move.
- Measure utilization before choosing provisioned — CloudWatch consumed vs provisioned capacity over 30 days; only go provisioned if you're sustainably above ~27%.
- Use the seasonal switch — run provisioned most of the year, flip to On-Demand a few days before a Black Friday-style surge, flip back after.
- Go hybrid per table — steady core user table on provisioned (add Reserved Capacity for up to ~76% off), unpredictable promotions/events table on On-Demand.
- Pre-request a limit increase if you'll exceed 40K RRU/WRU per second — On-Demand isn't literally unlimited.
Gotchas
- On-Demand only changes request pricing — storage is $0.25/GB-mo either way, and cold data still bills; tier it with DynamoDB Standard-IA.
- Global Tables roughly double On-Demand write cost for replicated writes — factor it for globally distributed apps.
- Batch operations count per item — 25 items in a BatchGetItem/BatchWriteItem = 25 units, not 1.
- Steady high-volume writes favor provisioned — an IoT platform doing billions of steady writes/month should provision at high utilization and add reserved capacity.
Skip this if
- Traffic is genuinely steady and predictable at high utilization — provisioned + DynamoDB Reserved Capacity is cheaper; On-Demand's flexibility is a premium you won't use.
- You've already confirmed sustained utilization well above ~27% — the break-even has passed. For everything variable, bursty, low-volume, or rapidly growing, On-Demand is the default.