Read-heavy DynamoDB tables where a DAX cache might cut read cost
What does ZopNight detect here?
ZopNight marks a DynamoDB table as read-heavy when `ConsumedReadCapacityUnits` make up at least 80% of consumed capacity over 30 days. Whether DAX saves money depends on its cache hit ratio, which cannot be measured for a table with no DAX cluster, so ZopNight raises no dollar finding and leaves the decision to a trial.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1516 |
| Category | rightsizing |
| Severity | low |
| Metric | ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits |
| Threshold | reads >= 80% of consumed capacity |
| Evaluation window | 30d |
| Source | ZopNight |
| Permissions used | dynamodb:ListTables · cloudwatch:GetMetricStatistics |
Where it applies
DAX only pays off when the same items are read again
DynamoDB Accelerator is an in-memory cache in front of a table. For eventually consistent reads it cuts response times from single-digit milliseconds to microseconds, and every read it serves from cache is one the table does not have to serve, which is where the cost angle comes from. AWS lists read-intensive, cost-sensitive applications as a good fit.
The same page lists where it is not: applications that need strongly consistent reads, applications
that are write-intensive, and applications without many repeated reads. DAX is also a cluster you pay
for by the node hour; the AWS price list shows a dax.t3.small node at $0.040 an hour and a
dax.r5.large at $0.255 in US East (N. Virginia). A cache that rarely hits adds that cost and saves
little.
Measuring how read-heavy a table is
aws cloudwatch get-metric-statistics --namespace AWS/DynamoDB \ --metric-name ConsumedReadCapacityUnits --dimensions Name=TableName,Value=catalog \ --statistics Sum --period 86400 \ --start-time 2026-08-26T00:00:00Z --end-time 2026-09-25T00:00:00ZRun it again with ConsumedWriteCapacityUnits and compare the totals. A high read share is
necessary for DAX to help, but it does not show whether reads repeat.
The read-share test ZopNight applies
ZopNight reads both consumed-capacity series over 30 days and requires each to carry at least 7 days of hourly data, so a table is never classed off a short history. A table counts as read-heavy when average reads divided by average reads plus writes is 0.80 or more.
Why the rule never produces a priced finding
A real saving would be the reads DAX absorbs minus the cluster’s cost, and the reads it absorbs
depend on the cache hit ratio. For a table with no DAX there are no DAX metrics to read, and
consumed read capacity is a volume figure that says nothing about how often the same keys come back.
Even where a DAX cluster exists,
its CloudWatch metrics
such as ItemCacheHits are reported per cluster or node, while the table a cluster fronts is chosen
in application code, so the two cannot be joined reliably. Guessing a hit
ratio would make up the one number the decision rests on, so the rule stays silent.
The calculation you can run after a trial
net saving = cache hit ratio x current monthly read cost - DAX cluster monthly costTake the hit ratio from the trial cluster’s own cache hit and miss metrics.
Trialling DAX on a read-heavy table
- Confirm the reads can be eventually consistent. DAX passes strongly consistent reads straight to DynamoDB and does not cache the results.
- Create a small cluster, for example
aws dax create-cluster --cluster-name catalog-cache --node-type dax.t3.small --replication-factor 1 --iam-role-arn ROLE_ARN. - Switch one read path to the DAX client and measure hit ratio and latency for a week.
- Keep it only if the read capacity you can release is worth more than the cluster.