Back to Checks
aws

DynamoDB table uses on-demand capacity or has auto scaling enabled for read and write capacity units

dynamodb_table_autoscaling_enabled
Service: dynamodbSeverity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsDynamoDbTable

DynamoDB tables use automatic capacity scaling via on-demand mode or PROVISIONED mode with auto scaling enabled for both read and write capacity units.

Provisioned tables are evaluated for scaling on both dimensions.

Risk

Insufficient capacity scaling causes throttling that degrades availability and increases latency.

Sustained throttling can trigger retry storms, timeouts, and backlogs, risking missed writes or out-of-order processing that impacts data integrity and drives operational costs.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks dynamodb_table_autoscaling_enabled

Recommendation

Adopt elastic capacity: prefer on-demand for unpredictable traffic, or use PROVISIONED with auto scaling on both reads and writes.

Define safe utilization targets and bounds, monitor consumption, and plan for bursts to maintain availability and resilience over manual fixed throughput.

Remediation

CLI

aws dynamodb update-table --table-name <table-name> --billing-mode PAY_PER_REQUEST

Terraform

# DynamoDB table with on-demand capacity
resource "aws_dynamodb_table" "<example_resource_name>" {
  name     = "<example_resource_name>"
  hash_key = "id"

  attribute {
    name = "id"
    type = "S"
  }

  billing_mode = "PAY_PER_REQUEST" # Critical: enables on-demand capacity to pass the control
}

NativeIaC

# CloudFormation: Set table to on-demand capacity
Resources:
  <example_resource_name>:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST  # Critical: enables on-demand capacity to pass the control

Other

1Open the AWS console and go to DynamoDB
2Click Tables and select your table
3Open the Additional settings tab and click Edit in Read/write capacity
4Set Capacity mode to On-demand (PAY_PER_REQUEST)
5Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.autoscaling.applicationautoscaling_client import (
    applicationautoscaling_client,
)
from prowler.providers.aws.services.dynamodb.dynamodb_client import dynamodb_client


class dynamodb_table_autoscaling_enabled(Check):
    def execute(self):
        findings = []
        scalable_targets = applicationautoscaling_client.scalable_targets
        dynamodb_scalable_targets = [
            target
            for target in scalable_targets
            if target.service_namespace == "dynamodb"
            and target.resource_id.startswith("table/")
        ]
        autoscaling_mapping = {}
        for target in dynamodb_scalable_targets:
            table_name = target.resource_id.split("/")[1]
            if table_name not in autoscaling_mapping:
                autoscaling_mapping[table_name] = {}
            autoscaling_mapping[table_name][target.scalable_dimension] = target

        for table in dynamodb_client.tables.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=table)
            report.status = "PASS"
            report.status_extended = (
                f"DynamoDB table {table.name} automatically scales capacity on demand."
            )
            if table.billing_mode == "PROVISIONED":
                read_autoscaling = False
                write_autoscaling = False

                if table.name in autoscaling_mapping:
                    if (
                        "dynamodb:table:ReadCapacityUnits"
                        in autoscaling_mapping[table.name]
                    ):
                        read_autoscaling = True
                    if (
                        "dynamodb:table:WriteCapacityUnits"
                        in autoscaling_mapping[table.name]
                    ):
                        write_autoscaling = True

                if read_autoscaling and write_autoscaling:
                    report.status = "PASS"
                    report.status_extended = f"DynamoDB table {table.name} is in provisioned mode with auto scaling enabled for both read and write capacity units."
                else:
                    missing_autoscaling = []
                    if not read_autoscaling:
                        missing_autoscaling.append("read")
                    if not write_autoscaling:
                        missing_autoscaling.append("write")

                    if missing_autoscaling:
                        report.status = "FAIL"
                        report.status_extended = f"DynamoDB table {table.name} is in provisioned mode without auto scaling enabled for {', '.join(missing_autoscaling)}."

            findings.append(report)

        return findings