DynamoDB Read-Heavy Table -- Consider DAX
What does ZopNight detect here?
Read-heavy DynamoDB tables (80% or more of consumed capacity over 30 days) are DAX candidates, but ZopNight abstains on every one today. The net saving needs a cache-hit ratio, and a table without DAX has no AWS/DAX series to measure one from. Modeling it would be fabrication.
Signal and threshold
| Field | Value |
|---|---|
| Rule IDs | RC-1516 |
| Category | rightsizing |
| Severity | low |
| Metric | none — pure configuration read |
| Source | dynamodb_dax.go |
Where it applies
The read share that makes a table a DAX candidate
- metric-backed read-heaviness: read.Average/(read+write) ≥ 0.80 (replaces the dead read_heavy tag)
Why cache hit ratio cannot be derived here
concrete-or-abstain: it abstains (returns nil) even when read-heavy. DAX is a cost lever (offload read-through lookups to cut provisioned read capacity), so it must be concrete or abstain. The net saving of ADDING DAX is cache_hit_ratio × current_read_cost − DAX_cluster_ADD_cost. Both prices are authoritative: the DAX add-cost is priced (AmazonDAX serviceCode → dax.* node-hour × nodes × 730) and the DynamoDB read price is priced off the same per-request and per-RCU rates AWS publishes (dynamodb-rru $0.000000125 / dynamodb-rcu). The blocker is cache_hit_ratio, which is not authoritatively derivable for RC-1516’s candidate (a table with no DAX), for three structural reasons:
- No metric by construction: the only authoritative cache-hit source is the AWS/DAX CloudWatch series (ItemCacheHits/QueryCacheHits, harvested on the dax resource type, dim ClusterId). It exists only for a table that already fronts a DAX cluster; RC-1516’s candidate has none, so there are zero datapoints to read.
- No cluster→table join even when DAX exists: AWS/DAX metrics key on ClusterId (attach to the dax resource); the dynamodb set keys on TableName. DescribeClusters exposes no table association (DAX is a transparent read-through cache; the table↔cluster mapping lives only in app config), so a dynamodb rule cannot join any DAX series to the table it evaluates.
- Cannot be modeled from consumed-read volume: ConsumedReadCapacityUnits, one of the consumed-capacity series in the AWS/DynamoDB metric set, is read volume; cache effectiveness depends on key-access repetition (hot-key skew), which the volume series does not carry. Converting volume→hit-ratio assumes a cache-friendliness factor = fabrication (forbidden).
Trialling a single-node DAX cluster
- Review read/write ratio in CloudWatch (ConsumedReadCapacityUnits vs Write)
- Evaluate if read patterns are cache-friendly (repeated key lookups)
- Deploy a DAX cluster with 1 node (dax.t3.small) for testing
- Update application to use DAX SDK client
The read and write capacity series behind the ratio
ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits (30-day lookback, full-window coverage gate)