Skip to content

DynamoDB Tables

Amazon DynamoDB is a fully managed NoSQL database service. While it scales seamlessly, unused tables, forgotten Global Secondary Indexes (GSIs), and suboptimal table class configurations can silently accumulate costs.

Implementation Effort: Low - Estimated time: less than 30 minutes. Delete unused tables/GSIs or switch table class to Standard-IA via console or CLI.

The Problem

Organizations often accumulate DynamoDB waste due to:

  • Unused tables from decommissioned applications or abandoned experiments, still incurring storage and provisioned throughput charges
  • Orphaned GSIs created during development or for access patterns that no longer exist, consuming write replication costs and storage
  • Wrong table class -- tables storing large amounts of infrequently accessed data on the Standard class instead of Standard-IA, overpaying ~60% on storage

Each of these represents ongoing cost with zero business value.

Detection Method

unusd.cloud analyzes your DynamoDB tables using CloudWatch metrics and table metadata to identify three types of optimization opportunities:

1. Unused Tables

We query CloudWatch ConsumedReadCapacityUnits and ConsumedWriteCapacityUnits over a 30-day window. Tables with zero reads and zero writes are flagged as unused.

2. Unused Global Secondary Indexes (GSIs)

For each active GSI, we check ConsumedReadCapacityUnits over 30 days. Since DynamoDB automatically replicates writes from the base table to GSIs, an unused GSI will still have write activity -- but zero reads means no application is querying it.

3. Table Class Optimization (Standard to Standard-IA)

We compare storage cost versus throughput cost for each table. When storage represents more than 50% of total monthly cost and the table uses the Standard class, switching to Standard-IA can save ~60% on storage costs.

Based on AWS best practices:

Cost Implications

Storage Pricing

Table Class Storage Cost
Standard $0.25 per GB-month
Standard-IA $0.10 per GB-month

Throughput Pricing (Provisioned Mode)

Capacity Type Cost per Unit per Hour
Write Capacity Unit (WCU) $0.00065
Read Capacity Unit (RCU) $0.00013

Provisioned tables with zero activity still pay for their configured WCU/RCU capacity. On-demand tables only pay for storage when idle.

GSI Costs

GSIs have their own provisioned throughput (in provisioned mode) and storage charges. An unused GSI still consumes write capacity as the base table replicates data to it, plus storage for the projected attributes.

Recommendations

  1. Unused tables -- Back up and delete the table, or switch to on-demand mode to eliminate throughput costs while retaining the data
  2. Unused GSIs -- Delete the index. GSI data is derived from the base table and can be recreated if needed later
  3. Table class optimization -- Switch to Standard-IA for storage-heavy tables. Note that read/write costs are ~25% higher with Standard-IA, so this is best for tables where storage dominates

How to Clean Up

Delete an Unused Table

# Optional: create a backup first
aws dynamodb create-backup \
    --table-name my-unused-table \
    --backup-name my-unused-table-backup \
    --region us-east-1

# Delete the table
aws dynamodb delete-table \
    --table-name my-unused-table \
    --region us-east-1

Delete an Unused GSI

aws dynamodb update-table \
    --table-name my-table \
    --global-secondary-index-updates \
    '[{"Delete":{"IndexName":"my-unused-gsi"}}]' \
    --region us-east-1

Switch Table Class to Standard-IA

aws dynamodb update-table \
    --table-name my-table \
    --table-class STANDARD_INFREQUENT_ACCESS \
    --region us-east-1

!!! warning "Before Deleting DynamoDB Tables" Before deleting a table:

1. **Verify no active consumers** -- Check application logs and CloudTrail for any API calls
2. **Create a backup** -- Use on-demand backup or export to S3 before deletion
3. **Check for DynamoDB Streams** -- Other services (Lambda triggers, Kinesis) may depend on the stream
4. **Review global table replicas** -- Deleting a replica table affects the global table setup

!!! info "Table Class Switching" Tables can be switched between Standard and Standard-IA twice per 30-day period with no downtime, data migration, or code changes. Reserved capacity is not supported for Standard-IA tables.

Exception Handling

To exclude a DynamoDB table from detection, add the configured exception tag:

aws dynamodb tag-resource \
    --resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/my-table \
    --tags Key=unusd,Value=true \
    --region us-east-1

Required Permissions

This feature uses the following IAM permissions (already included in the SecurityAudit managed policy attached to the spoke role):

- dynamodb:DescribeTable
- dynamodb:ListTables
- dynamodb:ListTagsOfResource
- cloudwatch:GetMetricStatistics  # Already in spoke role additional policy