# DynamoDB Auto Scaling Disabled

> ZopNight flags a provisioned-capacity DynamoDB table only when the discoverer explicitly recorded auto-scaling as disabled. On-demand tables are excluded by a billing-mode gate, because Application Auto Scaling does not exist for them. Remediation is to enable auto-scaling at a 70% target utilization, or to move unpredictable workloads to on-demand.

Source: https://zop.dev/integrations/aws/recommendations/dynamodb-auto-scaling-disabled
Updated: 2026-08-19

---

## Why on-demand tables never show up here

Application Auto Scaling is a Provisioned-capacity feature. An on-demand
(`PAY_PER_REQUEST`) table has no read or write capacity units to register a scalable
target against, so listing scalable targets legitimately returns zero results for every
on-demand table in the account. A naive "no scalable target means auto-scaling is
disabled" test would therefore stamp the entire on-demand fleet as misconfigured in one
sweep. This rule reads the discovered billing mode first and evaluates only tables that
are actually on Provisioned capacity, the only population the recommendation can apply
to.

## The two facts a finding rests on

The discoverer records two pieces of provider state for each table: the billing mode
(`PROVISIONED` or `PAY_PER_REQUEST`) and an explicit boolean for whether auto-scaling is
enabled, derived from the table's registered scalable targets. The finding fires only
when the mode resolves to Provisioned **and** the auto-scaling boolean is present and
false.

Both failure directions cost you. A provisioned table without auto-scaling is either
over-provisioned (paying every hour, [at the published provisioned-capacity rates](https://aws.amazon.com/dynamodb/pricing/), for capacity units the workload never consumes) or
under-provisioned, where a traffic increase surfaces as throttled requests instead of a
larger bill. Auto-scaling converts that static guess into a tracked target.

## Where the rule deliberately abstains

Three situations produce no finding, by design:

- **Billing mode was not discovered.** Without knowing the capacity mode, "enable
  auto-scaling" is not an actionable recommendation, so the rule fails closed.
- **The table is on-demand.** Auto-scaling does not exist for it; there is nothing to
  enable.
- **The auto-scaling attribute is absent.** Enrichment is best-effort and can be denied
  by IAM. An unknown state is never reported as a misconfigured one.

## Checking a table from your terminal

```bash
aws application-autoscaling describe-scalable-targets \
  --service-namespace dynamodb \
  --resource-ids table/my-table
```

An empty `ScalableTargets` list on a Provisioned table confirms the finding. The same
empty list on an on-demand table is normal and means nothing, which is exactly why the
billing-mode gate exists.

## Choosing between the two fixes

Enabling auto-scaling with a 70% target utilization is the default fix: capacity floats
with demand and the target leaves headroom for bursts. Workloads that are genuinely
unpredictable, with sharp, irregular spikes and long quiet stretches, are better served
by switching the table to on-demand than by auto-scaling chasing a moving target. After either
change, watch `ConsumedReadCapacityUnits` and `ConsumedWriteCapacityUnits`, [two of the table-level series DynamoDB publishes to CloudWatch](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/metrics-dimensions.html), to confirm
capacity now tracks consumption.
