DynamoDB on-demand vs provisioned (2026)

Akal Cloud Updated 7 min read

Quick answer

AWS publishes the threshold outright: on-demand mode costs less for workloads with average provisioned capacity utilisation below 35%, and it adds that on-demand can still win above 35% where activity is spiky. Its own test for choosing on-demand is whether hourly traffic drops to zero or below 30% of peak. You can switch provisioned to on-demand only four times in a rolling 24 hours, and switching in the console deletes every auto scaling setting while the CLI preserves them.

AWS publishes the break-even for this decision and almost nobody quotes it. On-demand costs less below 35% average provisioned capacity utilisation, and often above it. That single sentence settles most of the arguments this question generates.

What is the difference between on-demand and provisioned capacity?

One bills requests, the other bills reserved throughput whether you use it or not. The AWS guidance on evaluating your table's capacity mode puts it as: with provisioned capacity, "billing is based off of the total capacity provisioned rather than the number of requests consumed", while on-demand "offers pay-per-request pricing for read and write requests so that you only pay for what you use."

On-demandProvisioned
Billed onRead and write request units consumedCapacity units provisioned, used or not
Idle table"If you are driving zero traffic to your table, then with on-demand, you are not charged for any throughput"Full provisioned rate, 24 hours a day
Throttling riskOnly past double the previous peakAny time demand exceeds provisioned capacity
Commitment discountNoneReserved capacity available
Operational loadNone"requires constant monitoring"

The unit definitions matter for estimating either one. From the on-demand capacity mode documentation: "One read request unit represents one strongly consistent read operation per second, or two eventually consistent read operations per second, for an item up to 4 KB in size. One write request unit represents one write operation per second, for an item up to 1 KB in size."

Note the asymmetry. Reads are metered in 4 KB units and writes in 1 KB units, so a 4 KB item costs one read unit and four write units. Item size is a cost decision, not just a schema decision, and it is the lever most teams never pull. Current per-unit rates are on the DynamoDB pricing page; read them there rather than from an article.

Which capacity mode is cheaper?

AWS answers this with a number, in the "Additional factors" section of the cost optimization page:

On-demand mode costs less for workloads with average provisioned capacity utilization below 35%. In many cases, even for workloads with provisioned capacity utilization higher than 35%, it can be more cost-effective to use on-demand mode especially if the workload has periods of low activity mixed with occasional peaks.

Two things are notable about that. The threshold is 35%, not 50%, which is lower than most people guess. And AWS immediately widens it: above 35% is not automatically a provisioned win. The burden of proof sits on provisioned mode.

The measurement is straightforward, and the important part is to do it against consumed capacity rather than against request counts:

aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ConsumedReadCapacityUnits \
  --dimensions Name=TableName,Value=my-table \
  --start-time 2026-06-01T00:00:00Z --end-time 2026-06-15T00:00:00Z \
  --period 3600 --statistics Sum \
  --query 'Datapoints[].[Timestamp,Sum]' --output text | sort

Divide each hourly sum by 3600 to get average consumed capacity per second, then divide by provisioned capacity. AWS recommends a fortnight of data before acting: "We recommend reviewing metrics at a fine-grained period, such as 14 days, before taking action on your provisioned capacity."

One number to have ready before switching in either direction is warm throughput, which AWS defines as "the number of read and write operations that your table can instantaneously support" and describes as "available by default for all tables and global secondary indexes". The warm throughput documentation explains what a table can absorb without pre-warming, and pre-warming is the documented way to raise it ahead of a known spike rather than discovering the ceiling during one.

When should you use on-demand capacity mode?

AWS lists four workload characteristics, and the fourth is a usable test rather than a description:

  • "Traffic pattern that evolves over time"
  • "Variable volume of requests (resulting from batch workloads)"
  • "Unpredictable request timing (resulting in traffic spikes)"
  • "Drops to zero or below 30% of the peak for a given hour"

That last line is the one to check. If your hourly consumed capacity ever falls below 30% of your peak, provisioned mode is buying capacity for the trough that only the peak needs, and auto scaling does not fully rescue it: AWS notes that "When using auto scaling, your table will be over-provisioned", by design, because target utilisation is set below 100% on purpose.

This describes almost every multi-tenant SaaS workload with a business-hours shape, and it describes ours. We run DynamoDB as the primary store for tenant-scoped state, and the traffic follows the working day of a small number of accounts. Consumed capacity spends most of the night at zero. Provisioned mode would be buying twenty-four hours of throughput to serve eight.

On-demand is also the default now. AWS states it is "the default and recommended throughput option because it simplifies building modern, serverless applications that can start small and scale to millions of requests per second."

When is provisioned capacity mode still right?

Steady traffic, and reserved capacity. AWS describes the fit as "Steady, predictable and cyclical traffic for a given hour or day" with "Limited short-term bursts of traffic", and frames the tuning problem honestly: "Cost optimizing a provisioned capacity table is ultimately an exercise in getting the provisioned capacity (blue line) as close to the consumed capacity (orange line) as possible without increasing ThrottledRequests on the table."

Reserved capacity is the argument that survives the 35% threshold. AWS notes it "offers significant discounts over standard provisioned capacity pricing" and concedes the consequence: "In some cases, it might cost less to run a relatively unpredictable workload ... on an overprovisioned provisioned capacity table with reserved capacity."

Two exclusions to check before pricing that: replicated write capacity units and Standard-IA tables "are currently not eligible". A global table's replication writes cannot be reserved.

There is also a third option that is neither: fix the workload. AWS's own suggestion is to smooth the spike rather than pay for it, aimed at batch imports, which AWS calls "One of the most common causes of these patterns". Its three remedies are to schedule an auto scaling increase ahead of a known batch, "extend the time it runs rather than executing as fast as possible", or add "a ramp up period to the import ... until auto scaling has had the opportunity to start adjusting table capacity". A batch job that finishes in twenty minutes instead of five can move a table below the threshold entirely.

Can you switch back and forth?

Not symmetrically, which is the constraint that ruins the obvious strategy of flipping modes around a nightly batch. From the considerations when switching capacity modes: "You can switch tables from provisioned capacity mode to on-demand mode up to four times in a 24-hour rolling window. You can switch tables from on-demand mode to provisioned capacity mode at any time."

Four switches a day in one direction, unlimited in the other. That is enough for a scheduled daily batch and not enough for anything reactive.

Two behaviours to plan around when you do switch. The first is that a table switched to on-demand carries its history with it: "If you recently switched an existing table to on-demand capacity mode for the first time, the table has the following previous peak settings", with the floor being that any table previously under 4,000 WCU and 12,000 RCU "will make sure it is scaled out to instantly sustain at least 4,000 write units/sec and 12,000 read units/sec".

The second is a genuine trap. Auto scaling settings survive or vanish depending on which tool you used: "If you're using the console, all of your auto scaling settings (if any) will be deleted. If you're using the AWS CLI or AWS SDK, all of your auto scaling settings will be preserved." Switch to on-demand in the console, switch back later, and the auto scaling configuration you spent a quarter tuning is gone with no warning. Do it from the CLI.

How do you cap on-demand spend?

On-demand's failure mode is a runaway loop or an unexpected traffic source billing without limit. Two controls exist, and only one is table-level.

The account-level default is a backstop rather than a budget: "By default, DynamoDB protects you from unintended, runaway usage. To scale beyond the 40,000 table-level read and write throughput limits for all tables in your account, you can request an increase for this quota." The full set of defaults is in the DynamoDB service quotas reference.

The one worth setting deliberately is per-table maximum throughput. AWS describes it as letting you "keep table-level usage and costs bounded, protect against an inadvertent surge in consumed resources, and prevent excessive use for predictable cost management", and it can be changed "at any time based on your application requirements". Requests above it are throttled, so it is a real ceiling and it will drop traffic. That is the trade, and it is the same trade as the per-query data scanned limit in Athena: the only control that stops spend is the one that fails your workload.

Nothing detects the spike for you. DynamoDB spend appears under its own service name, so a cost anomaly monitor rather than a budget is what catches a table whose request volume changed shape, subject to the detection lag documented there. And while Cost Optimization Hub does cover DynamoDB tables and reserved capacity, it recommends on the commitment rather than on the capacity mode, so the 35% test above is still yours to run.

See this on your own bill

Akal Cloud connects in about two minutes and shows the same numbers against your real AWS accounts.

Get started on AWS Marketplace

Related reading