Reading25 min read·Module 4High exam weight

DynamoDB On-Demand vs Provisioned

Key concepts

  • On-demand pricing

  • Provisioned capacity

  • Auto scaling

  • Reserved capacity

  • Workload pattern analysis

Overview

Amazon DynamoDB offers two capacity modes that determine how you are charged for read and write throughput: On-Demand and Provisioned. Selecting the right capacity mode is critical for cost optimization and is a frequent topic on the SAA-C03 exam. Understanding when to use each mode, how auto-scaling works, and how to leverage reserved capacity can significantly impact your AWS bill.

Core Concept

DynamoDB capacity modes represent a fundamental trade-off: On-Demand offers instant scalability with pay-per-request pricing (higher per-request cost but zero capacity planning), while Provisioned offers lower per-unit costs but requires capacity planning and may result in throttling if misconfigured. The exam tests your ability to select the appropriate mode based on workload patterns.

Exam Tip

The exam frequently presents scenarios where you must choose between On-Demand and Provisioned capacity based on workload predictability, cost constraints, and traffic patterns. Remember: On-Demand is ideal for unpredictable or spiky workloads, while Provisioned with auto-scaling is better for predictable, steady traffic with cost optimization requirements.

Key Concepts

DynamoDB Capacity Units

DynamoDB Read and Write Capacity Units
Figure 1: Understanding DynamoDB Capacity Units

Read Capacity Units (RCUs)

Definition: One RCU represents the throughput for one strongly consistent read per second, or two eventually consistent reads per second, for items up to 4 KB in size.

Key Calculations:

  • Strongly Consistent Read: 1 RCU = 1 read/second for items up to 4 KB
  • Eventually Consistent Read: 1 RCU = 2 reads/second for items up to 4 KB
  • Transactional Read: 2 RCUs = 1 transactional read/second for items up to 4 KB

Size Calculation: Items larger than 4 KB require additional RCUs. Round up to the next 4 KB boundary.

Example: Reading a 6 KB item with strong consistency requires 2 RCUs (6 KB / 4 KB = 1.5, rounded up to 2)

Write Capacity Units (WCUs)

Definition: One WCU represents the throughput for one write per second for items up to 1 KB in size.

Key Calculations:

  • Standard Write: 1 WCU = 1 write/second for items up to 1 KB
  • Transactional Write: 2 WCUs = 1 transactional write/second for items up to 1 KB

Size Calculation: Items larger than 1 KB require additional WCUs. Round up to the next 1 KB boundary.

Example: Writing a 2.5 KB item requires 3 WCUs (2.5 KB / 1 KB = 2.5, rounded up to 3)

On-Demand Capacity Mode

DynamoDB On-Demand Mode Architecture
Figure 2: On-Demand Capacity Mode Flow

On-Demand Pricing Model

Purpose: Pay-per-request pricing with instant, automatic scaling for unpredictable workloads

Key Characteristics:

  • No capacity planning required - DynamoDB scales instantly
  • Charged per request: Read Request Units (RRUs) and Write Request Units (WRUs)
  • Can handle thousands of requests per second immediately
  • Tables can instantly accommodate up to 2x the previous peak traffic
  • No minimum fees or idle capacity charges
  • Switch from Provisioned to On-Demand once every 24 hours

Pricing (US-East-1, approximate):

  • Write Request Unit: $1.25 per million WRUs
  • Read Request Unit: $0.25 per million RRUs

Best For: New applications with unknown traffic, applications with unpredictable traffic, spiky or seasonal workloads, development/test environments

On-Demand Scaling Behavior

Initial Throughput: New tables start with capacity for up to 4,000 WRUs or 12,000 RRUs per second

Automatic Scaling:

  • DynamoDB automatically adapts to actual traffic patterns
  • Can instantly accommodate up to double the previous peak
  • If traffic exceeds 2x previous peak, DynamoDB continues to accommodate but may throttle briefly while scaling

Traffic Spikes:

  • Previous peak: The highest traffic level the table has experienced
  • If a spike exceeds 2x the previous peak, gradual increase is recommended
  • Use adaptive capacity to automatically isolate hot partitions

No Throttling (within limits): On-Demand mode virtually eliminates throttling for most workloads as long as traffic doesn't spike to more than double the previous peak instantly

Provisioned Capacity Mode

DynamoDB Provisioned Mode Architecture
Figure 3: Provisioned Capacity Mode Flow

Provisioned Capacity Overview

Purpose: Pre-allocate read and write capacity for predictable workloads at lower per-unit costs

Key Characteristics:

  • Specify expected reads/writes per second
  • Charged for provisioned capacity regardless of usage
  • Lower per-unit cost than On-Demand (~70% less expensive at scale)
  • Risk of throttling if actual traffic exceeds provisioned capacity
  • Can use burst capacity (unused capacity accumulates for up to 5 minutes)
  • Switch from On-Demand to Provisioned once every 24 hours

Pricing (US-East-1, approximate):

  • Write Capacity Unit: $0.00065 per WCU per hour ($0.47/month per WCU)
  • Read Capacity Unit: $0.00013 per RCU per hour ($0.09/month per RCU)

Best For: Predictable, consistent workloads; production applications with known traffic patterns; cost-sensitive applications with steady traffic

Burst Capacity

Purpose: Handle short-term traffic spikes without throttling

How It Works:

  • DynamoDB reserves unused read/write capacity
  • Accumulated over previous 5 minutes (300 seconds)
  • Can consume up to 300 seconds of unused capacity instantaneously
  • Provides a buffer for brief traffic spikes

Calculation Example:

  • Provisioned: 100 WCUs
  • If using 50 WCUs average, 50 unused WCUs accumulate
  • After 5 minutes: 50 x 300 = 15,000 burst write capacity available
  • Can handle spike of up to 15,000 writes instantly (plus ongoing 100 WCU)

Limitations:

  • Not designed for sustained high traffic
  • Once depleted, requests are throttled
  • Not guaranteed - shared resource pool

Auto Scaling Configuration

DynamoDB Auto Scaling Configuration
Figure 4: Auto Scaling Architecture

DynamoDB Auto Scaling

Purpose: Automatically adjust provisioned capacity based on actual utilization

Key Components:

  • Target Utilization: Percentage of provisioned capacity to maintain (20-90%, default 70%)
  • Minimum Capacity: Floor for scaling down
  • Maximum Capacity: Ceiling for scaling up
  • Scale-out Cooldown: Wait time after scaling up before next scale-out (default 60 seconds)
  • Scale-in Cooldown: Wait time after scaling down before next scale-in (default 60 seconds)

How It Works:

  1. CloudWatch monitors consumed capacity metrics
  2. Application Auto Scaling evaluates against target utilization
  3. When utilization exceeds/falls below target, scaling action triggers
  4. DynamoDB adjusts provisioned capacity within min/max bounds

Best For: Production workloads with variable but somewhat predictable patterns, applications with daily/weekly traffic cycles

Auto Scaling Policies

Target Tracking Scaling: Primary method for DynamoDB auto-scaling

Configuration Parameters:

  • TargetValue: Target utilization percentage (e.g., 70%)
  • ScaleInCooldown: Seconds to wait before scaling down
  • ScaleOutCooldown: Seconds to wait before scaling up
  • DisableScaleIn: Optional - prevent automatic scale-down

Important Considerations:

  • Auto-scaling reacts to changes, not predicts them
  • Lag time: 2-5 minutes to scale in response to traffic changes
  • For sudden spikes, provisioned capacity + burst may not be sufficient
  • Pre-scaling (scheduled scaling) recommended for known traffic events
  • GSIs can have independent auto-scaling policies

CloudWatch Metrics Used:

  • ConsumedReadCapacityUnits
  • ConsumedWriteCapacityUnits
  • ProvisionedReadCapacityUnits
  • ProvisionedWriteCapacityUnits

Reserved Capacity

Reserved Capacity Discounts

Purpose: Significant discounts for committed DynamoDB usage over 1 or 3 years

Key Characteristics:

  • Up to 77% discount compared to on-demand pricing
  • Requires upfront commitment (1-year or 3-year terms)
  • Applies to Provisioned capacity mode only
  • Reserved in specific AWS Region
  • 100 RCU minimum, 100 WCU minimum per reservation
  • Can purchase multiple reservations

Discount Levels (approximate): | Term | Payment Option | Discount vs Provisioned | |------|----------------|------------------------| | 1 Year | No Upfront | ~25% | | 1 Year | Partial Upfront | ~42% | | 1 Year | All Upfront | ~44% | | 3 Year | No Upfront | ~53% | | 3 Year | Partial Upfront | ~75% | | 3 Year | All Upfront | ~77% |

Best For: Production workloads with consistent, predictable baseline capacity; long-term applications with stable traffic patterns

Reserved Capacity Planning

Strategy: Reserve baseline capacity, use On-Demand or auto-scaling for peaks

Planning Steps:

  1. Analyze 30+ days of CloudWatch metrics for baseline consumption
  2. Identify minimum consistent utilization (your baseline)
  3. Reserve capacity for 70-80% of baseline (safety margin)
  4. Configure auto-scaling for traffic above reserved capacity
  5. Consider On-Demand for highly variable workloads

Important Notes:

  • Reserved capacity is use-it-or-lose-it (no rollover)
  • Cannot transfer between regions
  • Applies automatically to matching tables
  • Can combine with auto-scaling for cost optimization

Example Architecture:

  • Reserved: 500 WCU, 1000 RCU (baseline)
  • Auto-scaling: 500-2000 WCU, 1000-5000 RCU (variable)
  • Peak handling through auto-scaling above reserved baseline

Workload Pattern Analysis

Capacity Mode Selection by Workload Pattern

Workload PatternRecommended ModeKey ReasoningCost Impact
New application, unknown trafficOn-DemandNo capacity planning needed, zero risk of over-provisioningHigher per-request but no waste
Spiky, unpredictable trafficOn-DemandInstant scaling, no throttling riskPay only for actual usage
Consistent, predictable trafficProvisioned + Auto-ScalingLower per-unit cost, controlled scalingUp to 70% cheaper than On-Demand
Scheduled peaks (e.g., daily batch)Provisioned + Scheduled ScalingPre-scale before known peaksOptimized cost with predictable scaling
Baseline + variable peaksReserved + Auto-ScalingReserved for baseline, auto-scale for peaksMaximum savings with flexibility
Development/Test environmentOn-DemandMinimal usage, no idle costsZero cost when not in use
Seasonal business (e.g., retail)On-Demand or aggressive auto-scalingHandle 10-100x traffic spikesAvoid paying for year-round peak capacity
SHAWS CLI - Check Current Capacity Mode
# Get table description including billing mode
aws dynamodb describe-table \
  --table-name my-table \
  --query 'Table.{BillingMode: BillingModeSummary.BillingMode, ProvisionedThroughput: ProvisionedThroughput}'

# List all tables with their billing modes
aws dynamodb list-tables --query 'TableNames' | \
  xargs -I {} aws dynamodb describe-table \
    --table-name {} \
    --query '{TableName: Table.TableName, BillingMode: Table.BillingModeSummary.BillingMode}'
SHAWS CLI - Switch Capacity Modes
# Switch to On-Demand mode
aws dynamodb update-table \
  --table-name my-table \
  --billing-mode PAY_PER_REQUEST

# Switch to Provisioned mode with specific capacity
aws dynamodb update-table \
  --table-name my-table \
  --billing-mode PROVISIONED \
  --provisioned-throughput ReadCapacityUnits=100,WriteCapacityUnits=50
SHAWS CLI - Configure Auto Scaling
# Register scalable target for write capacity
aws application-autoscaling register-scalable-target \
  --service-namespace dynamodb \
  --resource-id "table/my-table" \
  --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
  --min-capacity 5 \
  --max-capacity 1000

# Create target tracking scaling policy
aws application-autoscaling put-scaling-policy \
  --service-namespace dynamodb \
  --resource-id "table/my-table" \
  --scalable-dimension "dynamodb:table:WriteCapacityUnits" \
  --policy-name "WriteCapacityScaling" \
  --policy-type "TargetTrackingScaling" \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "DynamoDBWriteCapacityUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60
  }'

# Configure auto scaling for read capacity
aws application-autoscaling register-scalable-target \
  --service-namespace dynamodb \
  --resource-id "table/my-table" \
  --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
  --min-capacity 10 \
  --max-capacity 5000

aws application-autoscaling put-scaling-policy \
  --service-namespace dynamodb \
  --resource-id "table/my-table" \
  --scalable-dimension "dynamodb:table:ReadCapacityUnits" \
  --policy-name "ReadCapacityScaling" \
  --policy-type "TargetTrackingScaling" \
  --target-tracking-scaling-policy-configuration '{
    "TargetValue": 70.0,
    "PredefinedMetricSpecification": {
      "PredefinedMetricType": "DynamoDBReadCapacityUtilization"
    },
    "ScaleOutCooldown": 60,
    "ScaleInCooldown": 60
  }'
SHAWS CLI - Monitor Capacity Metrics
# Get consumed write capacity for last hour
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ConsumedWriteCapacityUnits \
  --dimensions Name=TableName,Value=my-table \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Average Sum Maximum

# Get throttled requests count
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ThrottledRequests \
  --dimensions Name=TableName,Value=my-table \
  --start-time $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 3600 \
  --statistics Sum

# Check current provisioned vs consumed capacity
aws cloudwatch get-metric-data \
  --metric-data-queries '[
    {"Id": "provisioned", "MetricStat": {"Metric": {"Namespace": "AWS/DynamoDB", "MetricName": "ProvisionedWriteCapacityUnits", "Dimensions": [{"Name": "TableName", "Value": "my-table"}]}, "Period": 300, "Stat": "Average"}},
    {"Id": "consumed", "MetricStat": {"Metric": {"Namespace": "AWS/DynamoDB", "MetricName": "ConsumedWriteCapacityUnits", "Dimensions": [{"Name": "TableName", "Value": "my-table"}]}, "Period": 300, "Stat": "Average"}}
  ]' \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ)
SHAWS CLI - Purchase Reserved Capacity
# List available reserved capacity offerings
aws dynamodb describe-reserved-capacity-offerings \
  --query 'ReservedCapacityOfferings[*].{OfferingId: ReservedCapacityOfferingId, Duration: Duration, ProductDescription: ProductDescription}'

# Purchase reserved capacity (requires valid offering ID)
aws dynamodb purchase-reserved-capacity-offerings \
  --reserved-capacity-offering-id <offering-id> \
  --capacity-to-reserve ReadCapacityUnits=100,WriteCapacityUnits=100

# List current reserved capacity
aws dynamodb describe-reserved-capacity \
  --query 'ReservedCapacity[*].{TableName: ReservedCapacityId, State: State, StartTime: StartTime, Duration: Duration}'

Best Practices

  1. Start with On-Demand for New Applications: Use On-Demand initially to establish traffic patterns, then switch to Provisioned once patterns are clear
  2. Use Auto-Scaling with Appropriate Target: Set target utilization to 70% (default) for most workloads, lower for latency-sensitive applications
  3. Monitor Throttling Metrics: Set CloudWatch alarms for ThrottledRequests to detect capacity issues early
  4. Reserve Baseline Capacity: For stable production workloads, reserve 70-80% of baseline and auto-scale the remainder
  5. Configure GSI Auto-Scaling Separately: Global Secondary Indexes have independent capacity - configure auto-scaling for each GSI
  6. Use Scheduled Scaling for Known Peaks: Pre-scale before anticipated traffic spikes (marketing campaigns, product launches)
  7. Review Capacity Monthly: Use AWS Cost Explorer to identify over-provisioned tables and optimize
  8. Consider Table Class: Use DynamoDB Standard-IA for infrequently accessed data to reduce storage costs

Common Exam Scenarios

Exam Scenario Decision Guide

ScenarioRecommended SolutionKey Reasoning
Startup launching MVP with unknown user adoptionOn-Demand capacityNo upfront capacity planning, scales with growth, zero cost when idle
E-commerce site with predictable daily traffic patternsProvisioned with Auto-ScalingCost optimization for known patterns, auto-scale handles variations
Gaming application with massive, unpredictable player spikesOn-Demand capacityInstant scaling without throttling risk, worth premium pricing
Financial services with steady transaction volumeProvisioned with Reserved CapacityMaximum cost savings for consistent, predictable workloads
Application experiencing frequent throttlingIncrease provisioned capacity or switch to On-DemandThrottling indicates insufficient capacity for workload
Dev/test environment used 8 hours per dayOn-Demand capacityPay only during active development, no idle costs
Batch processing job that runs nightlyProvisioned with Scheduled ScalingPre-scale before batch job, scale down after completion
Read-heavy analytics workloadProvisioned with aggressive read auto-scalingOptimize for read-heavy pattern, scale reads independently

Common Pitfalls

24-Hour Mode Switch Limitation

You can only switch between On-Demand and Provisioned capacity modes once every 24 hours per table. Plan capacity mode changes carefully and avoid frequent switching. If you need flexibility, consider staying on On-Demand or implementing robust auto-scaling.

Auto-Scaling Lag Time

Auto-scaling takes 2-5 minutes to react to traffic changes. It monitors CloudWatch metrics, evaluates policies, and then adjusts capacity. For sudden traffic spikes, this lag can cause throttling. Use burst capacity awareness, consider scheduled scaling for known peaks, or use On-Demand for truly unpredictable spikes.

GSI Capacity Independence

Global Secondary Indexes (GSIs) have completely independent capacity from the base table. Failing to configure auto-scaling for GSIs is a common mistake that leads to throttling on GSI queries even when the base table has sufficient capacity. Always configure auto-scaling for BOTH the table AND each GSI.

Reserved Capacity Use-It-or-Lose-It

Reserved capacity does not roll over. If you reserve 1000 WCUs but only use 500 WCUs, you still pay for 1000 WCUs. Over-reserving wastes money. Analyze at least 30 days of consumption data before purchasing reserved capacity, and reserve only 70-80% of your consistent baseline.

Ignoring Transactional Operations

DynamoDB transactions consume 2x the capacity of standard operations. A transactional write of a 1 KB item consumes 2 WCUs, not 1. When capacity planning, account for transactional operations separately to avoid unexpected throttling during transaction-heavy periods.

Quick Reference

Capacity Mode Comparison

FeatureOn-DemandProvisioned
Pricing ModelPay-per-requestPay-per-hour
Capacity PlanningNone requiredRequired
ScalingInstant, automaticAuto-scaling with lag
Cost per UnitHigher (~5x)Lower
Throttling RiskVery lowPossible if under-provisioned
Reserved CapacityNot applicableAvailable (up to 77% discount)
Best ForUnpredictable workloadsPredictable workloads
Switch FrequencyOnce per 24 hoursOnce per 24 hours

Auto-Scaling Configuration Quick Reference

ParameterDescriptionDefaultRecommended Range
Target UtilizationPercentage to maintain70%50-80%
Min CapacityFloor for scalingVariesBaseline minimum
Max CapacityCeiling for scalingVaries10x peak expected
Scale-Out CooldownWait after scale up60s60-120s
Scale-In CooldownWait after scale down60s300-900s

Key CLI Commands

# Check current billing mode
aws dynamodb describe-table --table-name my-table \
  --query 'Table.BillingModeSummary.BillingMode'

# Switch to On-Demand
aws dynamodb update-table --table-name my-table \
  --billing-mode PAY_PER_REQUEST

# Switch to Provisioned
aws dynamodb update-table --table-name my-table \
  --billing-mode PROVISIONED \
  --provisioned-throughput ReadCapacityUnits=100,WriteCapacityUnits=50

# Check for throttling
aws cloudwatch get-metric-statistics \
  --namespace AWS/DynamoDB \
  --metric-name ThrottledRequests \
  --dimensions Name=TableName,Value=my-table \
  --period 3600 --statistics Sum \
  --start-time $(date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ)

Capacity Unit Calculations

OperationItem SizeCapacity Units
Strongly Consistent ReadUp to 4 KB1 RCU
Eventually Consistent ReadUp to 4 KB0.5 RCU
Transactional ReadUp to 4 KB2 RCUs
Standard WriteUp to 1 KB1 WCU
Transactional WriteUp to 1 KB2 WCUs

Pricing Quick Reference (US-East-1, approximate)

On-Demand:

  • Write Request Unit: $1.25 per million WRUs
  • Read Request Unit: $0.25 per million RRUs

Provisioned:

  • Write Capacity Unit: $0.00065/hour ($0.47/month)
  • Read Capacity Unit: $0.00013/hour ($0.09/month)

Reserved Capacity (3-Year, All Upfront):

  • Up to 77% discount on provisioned pricing

Test Your Knowledge

Q

A startup is launching a new mobile application. User adoption is completely unknown, and they expect traffic patterns to be highly variable if the app goes viral. The development team has no experience with DynamoDB capacity planning. Which capacity mode should they choose?

AProvisioned capacity with auto-scaling configured at 50% target utilization
BProvisioned capacity with maximum reserved capacity for cost savings
COn-Demand capacity mode
DProvisioned capacity with very high minimum and maximum limits
Q

A company runs an e-commerce platform with predictable daily traffic: 1,000 WCUs during business hours and 100 WCUs at night. They consistently use 800 WCUs average during peak hours. They want to minimize costs while ensuring no throttling. What is the MOST cost-effective configuration?

AOn-Demand capacity mode for flexibility
BProvisioned with auto-scaling, min=100, max=1000, target=70%
CProvisioned with auto-scaling, min=100, max=1000, plus Reserved Capacity for 500 WCUs
DProvisioned with fixed 1,000 WCUs 24/7
Q

An application using DynamoDB Provisioned capacity is experiencing intermittent throttling during morning traffic spikes that occur between 8:00-8:15 AM daily. Auto-scaling is configured with 70% target utilization. What is the BEST solution to prevent throttling?

ASwitch to On-Demand capacity mode
BDecrease the target utilization to 50% for faster scaling
CImplement scheduled scaling to pre-provision capacity before 8:00 AM
DIncrease the auto-scaling maximum capacity limit
Q

A DynamoDB table has the following CloudWatch metrics over 30 days: consistent 200 RCU consumption, occasional spikes to 500 RCU lasting 2-3 hours, and very rare spikes to 2000 RCU during monthly sales events. What capacity configuration provides the BEST balance of cost and performance?

AOn-Demand capacity for maximum flexibility
BProvisioned 2000 RCU with Reserved Capacity
CReserved Capacity 150 RCU + Auto-scaling 150-1000 RCU + Scheduled scaling for monthly events
DProvisioned 500 RCU fixed with burst capacity for spikes

Further Reading

Related services

DynamoDB