⚡ DynamoDB Capacity Cost

A DynamoDB bill is decided by two numbers that never appear next to each other in the console: how many kilobytes each request actually touches, and how much of the capacity you paid for is in use. Rounding happens before pricing, not after, so a 4.1 KB item costs twice what a 4.0 KB item does on a strongly consistent read. This page converts an item size and a request rate into capacity units, then prices the identical workload both ways.

📐 Workload

Enter the peak request rate, not the average. Provisioned capacity is bought at the peak, while on-demand is billed at whatever the traffic actually does, so the utilization field is what connects the two models.

Storage is priced once and added to both models, so the comparison isolates throughput. Write capacity covers the base table plus one copy per GSI; read capacity is estimated from the base table only, because index read traffic depends on which queries you route to it.

Capacity units round up before they multiply

DynamoDB does not bill bytes. It bills the number of capacity units a request consumes, and a unit is a fixed block of data. Writes are counted in 1 KB blocks and reads in 4 KB blocks, and the block count is rounded up per request, not amortised across a batch. Two requests that touch 0.6 KB each cost two write units, not 1.2.

WCU per write = ceil(item KB ÷ 1) × (2 if transactional) RCU per read = ceil(item KB ÷ 4) × (1 strong | 0.5 eventual | 2 transactional) 1 WCU = 1 write/sec of 1 KB 1 RCU = 1 strongly consistent read/sec of 4 KB

The read block is four times the write block because a read unit buys four times the throughput, which is why the two unit prices differ by exactly 5× in the published table and why a mixed workload cannot be costed with a single blended number.

Item sizeWCU per writeRCU, eventually consistentRCU, strongly consistent
0.4 KB10.51
1.0 KB10.51
1.1 KB20.51
4.0 KB40.51
4.1 KB512
10 KB101.53
40 KB40510
Crossing 4.0 KB by one byte doubles the read cost of every access to that item, forever. Crossing 1.0 KB doubles the write cost. Neither boundary shows up in a latency graph, which is why size-driven bills are so often discovered late.

Item size is usually not the lever

A typical record — a user row with an id, a status, an amount and a timestamp — lands somewhere between 60 and 300 bytes. That is one write unit and half a read unit, and no amount of JSON trimming moves it down, because the floor is one unit. For the majority of tables, the bill is set by the number of requests, and the largest available saving is removing a request pattern rather than shrinking an item.

The patterns that multiply request counts are boring and well known: a list screen that issues one query per row, a poll loop that re-reads the same item every second, a scan used as a query. One thousand eventually consistent reads per second of a 200-byte item costs 500 RCU, which is about $164 a month on demand. The same screen served by a single query that returns 20 rows costs a twentieth of that, and the item size never entered the calculation.

Size becomes the dominant term in three situations, and they are worth recognising because each has a different fix. Items over 1 KB, where every write pays the multiplier. Wide collections stored as a single item, which is the classic way to break the 400 KB limit and to burn write units on partial updates. And anything that stores a document blob in the item instead of in S3, where the read cost per page view is exact and unavoidable.

On-demand versus provisioned: the 28.9% line

The two models price the same unit differently, and the difference is a constant. One WCU-hour costs $0.00065; a 730-hour month of it costs $0.4745, and that month delivers 2.628 million writes if the capacity is fully used. On-demand charges $0.625 per million writes. Divide one by the other and provisioned capacity is 3.46× cheaper, if you use all of it.

provisioned per million = $0.4745 ÷ 2.628 = $0.1806 on-demand per million = $0.6250 breakeven = 0.4745 ÷ 1.6425 = 28.9% utilization

The same 28.9% applies to reads, because the read prices sit in the same 5:1 ratio and one RCU-hour delivers one read per second just as a WCU-hour delivers one write per second. A read-heavy table and a write-heavy table cross the line at the identical point, which is a useful thing to know when someone argues that provisioned capacity "only makes sense for writes".

Average use of 200 WCUOn-demand / monthProvisioned / monthDifference
10%$32.85$94.90On-demand saves $62.05
25%$82.13$94.90On-demand saves $12.78
28.9%$94.90$94.90Dead heat
40%$131.40$94.90Provisioned saves $36.50
60%$197.10$94.90Provisioned saves $102.20
100%$328.50$94.90Provisioned saves $233.60

The table hides the part that actually decides the migration: a provisioned table that gets the peak wrong is not slower, it is throttled. On-demand absorbs a spike by design, at a price. Provisioned capacity is a bet that next month looks like this month, and the 28.9% line is the size of the reward for being right.

Auto scaling narrows the gap rather than closing it. It adjusts the provisioned level on a schedule measured in minutes against a target utilization that defaults to 70%, which is comfortably above the breakeven line, so a well-tuned auto-scaled table usually beats on-demand. But the floor never goes below one unit, the ceiling is whatever you configured, and a table that doubles in ten seconds will throttle while the policy is still deciding. Reserved capacity goes further in the same direction: one-year terms discount provisioned throughput by up to 54%, three-year terms by up to 77%, and both require a commitment that on-demand never asks for.

Every index is a second write bill

A global secondary index is a copy of your table, maintained by the service. When you write to the base table, DynamoDB writes the same change into every GSI whose keys are affected, and charges that write to the index's own capacity. Three GSIs means four write bills for one logical write, and the multiplier applies whether the index is queried or not.

DesignWCU per 2 KB writeAt 50 writes/secMonthly, provisioned
Base table only2100 WCU$47.45
Base + 1 GSI4200 WCU$94.90
Base + 3 GSIs8400 WCU$189.80
Base + 5 GSIs12600 WCU$284.70

Two details keep the arithmetic honest. A GSI item contains only the index keys and the projected attributes, so it is usually smaller than the base item — but the write is still rounded up to at least one WCU, so a 200-byte index still costs a full unit per write. And index reads are eventually consistent only, which halves their cost relative to a strongly consistent base read but rules out the pattern entirely inside a transaction.

The practical consequence is that index count belongs in the design review next to query count. An index added for one ad-hoc report keeps charging for every write for as long as it exists, and dropping an unused index is one of the few optimisations on this page that has no downside at all.

The ceiling that capacity does not remove

A single partition supports up to 3,000 RCU and 1,000 WCU. Buying more capacity adds partitions, not throughput per key: a table provisioned at 10,000 WCU spreads that across at least ten partitions, and a single hot partition key still stops at 1,000 WCU. This is the most common reason a table with generous provisioned capacity throttles anyway, and it is invisible in every capacity calculator that stops at the total.

The related hard limits are worth keeping in view while sizing. An item cannot exceed 400 KB including attribute names. A transactional write costs double the units of the same write performed normally. And on-demand tables start a new table at 4,000 WCU and 12,000 RCU, then allow the ceiling to double once the previous peak is established, which is why the first hour of a launch is the one that throttles.

What this page does not price

Several DynamoDB charges sit outside the capacity model, and each has a habit of appearing on a bill that was "fully modelled".

Streams. Stream read requests are billed separately from table capacity, per 100,000 requests. A consumer that polls aggressively can exceed the table's own throughput cost.

Backups and point-in-time recovery. Both are priced per GB-month on top of storage, and PITR applies to the whole table whether or not a restore is ever performed.

Global tables. A replicated write is billed as a write in every region that receives it, so a three-region table pays three write bills for the same operation, plus cross-region replication traffic.

Table class. The Standard-IA class trades a higher per-request price for a lower storage price, which moves the breakeven point and is worth a separate model rather than a footnote.

The free tier. 25 GB of storage and 25 WCU / 25 RCU are included per account per region, which covers small tables entirely and is deliberately not subtracted here, because a projection that assumes the free tier stops being a projection the moment the table grows.

Pricing Basis, Sources & Assumptions

Every rate on this page is a published vendor list price — no negotiated discounts, private pricing, savings plans, credits or enterprise agreements. Totals are in USD and exclude tax. Rates were last checked against the sources below on .

Pricing inputBasis used on this page
SourceAmazon DynamoDB on-demand pricing for $0.625 per million write request units, $0.125 per million read request units and $0.25 per GB-month of Standard table class storage; provisioned capacity pricing for $0.00065 per WCU-hour and $0.00013 per RCU-hour.
RegionUS East (N. Virginia), us-east-1, DynamoDB Standard table class. Other regions are priced higher and the difference is not modelled here.
CurrencyUSD — on-demand and provisioned list price, tax excluded
Last checked — all five rates plus the 1 KB write and 4 KB read increment definitions were re-read from the two pages on this date.

Modelling assumptions