DynamoDB Pricing
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
✦ Skip the page breaks and see fewer ads — read each lesson on a single page with Pro
Mastering DynamoDB Pricing: A Comprehensive Guide to Cost-Optimized Architectures
Introduction: Why DynamoDB Pricing Matters
When you are architecting applications on the cloud, the database is often the single most significant driver of your monthly infrastructure bill. Amazon DynamoDB, a fully managed NoSQL database service, is celebrated for its ability to scale to millions of requests per second with single-digit millisecond latency. However, because it is a consumption-based service, the way you structure your data, choose your capacity mode, and interact with the API can lead to either massive cost savings or unexpected budget overruns.
Understanding DynamoDB pricing is not just about reading a price list; it is about understanding how your application’s data access patterns map to AWS’s billing metrics. If you treat DynamoDB like a traditional relational database—performing complex joins, scanning entire tables, or ignoring item size—you will likely pay far more than necessary. By mastering the nuances of read/write capacity units, storage costs, and the various architectural levers available, you can build systems that are both high-performing and incredibly cost-efficient.
This lesson explores the mechanics of DynamoDB costs, starting from the fundamental unit of billing and extending into advanced strategies for optimization. We will look at how to choose between On-Demand and Provisioned capacity, how to optimize your data model to minimize read/write consumption, and how to avoid common pitfalls that lead to "bill shock."
The Fundamental Units of Cost
To understand your bill, you must first understand what you are actually paying for. DynamoDB bills based on three primary pillars: Read/Write throughput, Data Storage, and optional features (like backups or global tables).
Read and Write Capacity Units (RCUs and WCUs)
In the provisioned capacity model, you pay for the throughput you reserve.
- Write Capacity Unit (WCU): One WCU represents one write request per second for an item up to 1 KB in size. If your item is larger than 1 KB, you will consume more WCUs.
- Read Capacity Unit (RCU): One RCU represents one strongly consistent read request per second for an item up to 4 KB in size, or two eventually consistent read requests per second for an item up to 4 KB.
Data Storage
Storage is billed per gigabyte per month. While this is often the smallest part of the bill for high-traffic applications, it can become significant if you store large blobs or maintain millions of versions of items without a proper TTL (Time to Live) strategy.
The Math of Throughput
If you have an item that is 3 KB and you want to perform a strongly consistent read, you are still consuming 1 RCU, because the item fits within the 4 KB threshold. However, if that item grows to 5 KB, you now consume 2 RCUs for that same read. This is a critical point: Item size directly impacts your throughput costs.
Callout: Strongly Consistent vs. Eventually Consistent A strongly consistent read returns the most up-to-date data, reflecting all prior successful write operations. An eventually consistent read might return data that is slightly stale but costs half as much. For many applications, such as user profiles or product catalogs, eventual consistency is perfectly acceptable and serves as an easy way to cut your read costs in half.
Capacity Modes: On-Demand vs. Provisioned
One of the most important architectural decisions you will make is selecting the capacity mode for your table. This choice dictates how you pay for the throughput your application consumes.
On-Demand Capacity
In On-Demand mode, DynamoDB handles the capacity management for you. You do not need to specify how much read or write throughput you need. Instead, you pay per request.
- Best for: Unpredictable workloads, new applications where traffic patterns are unknown, or intermittent traffic.
- Pros: Zero management overhead; you never have to worry about "provisioning" enough capacity.
- Cons: Higher cost per request compared to provisioned capacity if your traffic is steady and predictable.
Provisioned Capacity
In Provisioned mode, you specify the number of reads and writes per second that you expect your application to require.
- Best for: Predictable, steady-state workloads.
- Pros: Significantly cheaper than On-Demand if you can maintain high utilization of your provisioned units.
- Cons: Requires monitoring and manual adjustment (or Auto Scaling) to ensure you have enough capacity without over-provisioning.
Tip: Use Auto Scaling with Provisioned Capacity If you choose Provisioned Capacity, always enable Auto Scaling. It allows DynamoDB to automatically adjust your provisioned units in response to actual traffic. This provides the cost benefits of provisioned capacity while protecting you from performance degradation during unexpected traffic spikes.
Optimizing Write Costs: Efficiency at the Source
Writing to DynamoDB is often the most expensive operation in a high-scale system. To optimize, you must focus on item size and batching.
1. Minimize Item Size
Every byte you store costs money, and every byte you write consumes WCUs. If you have large text fields or unnecessary metadata in your items, you are effectively paying a "storage tax" on every write.
- Strategy: Store large binary data or documents in S3 and only store the S3 URI (a small string) in DynamoDB.
- Strategy: Use compression for long strings or JSON blobs before writing them to the database.
2. Batching Operations
Using the BatchWriteItem API allows you to write multiple items in a single request. While this does not reduce the total number of WCUs consumed, it reduces the overhead of HTTP requests and can improve application latency.
3. Avoid Writing Unchanged Data
If your application logic performs a "put" operation every time a user clicks a button, even if the data hasn't changed, you are wasting money. Implement "read-before-write" logic or use conditional updates to only write when the data actually changes.
# Example of a conditional update to save costs
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('UserActivity')
# Only update if the activity status has actually changed
response = table.update_item(
Key={'UserId': '12345'},
UpdateExpression="SET ActivityStatus = :new_status",
ConditionExpression="ActivityStatus <> :new_status",
ExpressionAttributeValues={':new_status': 'ACTIVE'}
)
Optimizing Read Costs: Access Patterns
Read costs are often driven by inefficient query patterns. If you find yourself scanning a table to find a specific item, you are paying to read every single item in that table.
1. Avoid Scan Operations
The Scan operation reads every item in your table. If your table has 1 million items, a Scan will consume 1 million items' worth of RCUs, regardless of whether you only need one piece of data.
- Solution: Use
Queryinstead. Queries allow you to use partition keys and sort keys to fetch only the specific items you need.
2. Use Global Secondary Indexes (GSIs)
If you need to query your data by a different attribute (e.g., querying by Email instead of UserId), don't use a Scan. Create a GSI. While GSIs have their own storage and throughput costs, they are orders of magnitude cheaper than performing a full table scan.
3. Leverage Eventually Consistent Reads
As mentioned earlier, unless your application requires absolute, up-to-the-millisecond accuracy, use eventually consistent reads. This effectively cuts your read costs by 50%.
Warning: The "Hot Partition" Problem If you design your primary key poorly (e.g., using a timestamp as a partition key), all your traffic will hit a single partition. This creates a "hot partition" that cannot handle the load, forcing you to over-provision throughput across the entire table just to satisfy one small, overloaded partition. Always choose a partition key with high cardinality to ensure data is spread evenly.
Storage Optimization: TTL and Archival
Storage costs are generally lower than throughput costs, but they add up over time. If you are storing logs, session data, or event history, you need a strategy to prune old data.
1. Time to Live (TTL)
DynamoDB TTL allows you to set an expiration timestamp on an item. Once that time passes, DynamoDB automatically deletes the item for you at no additional cost.
- Why it matters: It keeps your table size small and prevents you from paying for storage you no longer need. It also makes your queries faster, as the database has fewer items to filter through.
2. Archival to S3
If you need to keep data for compliance or long-term analytics, move it out of DynamoDB. Use DynamoDB Streams to trigger a Lambda function that moves data to S3 or Amazon Glacier. S3 storage is significantly cheaper than DynamoDB storage for long-term archival.
Advanced Cost Strategies: Reserved Capacity
If you have a predictable, long-term workload (e.g., a steady state of 5,000 RCUs and 1,000 WCUs), you should look into Reserved Capacity.
By committing to a one-year or three-year term, you can receive a significant discount (up to 77%) compared to standard Provisioned Capacity pricing. This is the "wholesale" route for DynamoDB.
- Decision Matrix:
- On-Demand: Pay-as-you-go, high flexibility, highest cost.
- Provisioned: Monthly commitment, requires monitoring, moderate cost.
- Reserved: Annual/Multi-year commitment, lowest cost, zero flexibility.
Common Pitfalls and How to Avoid Them
Pitfall 1: Over-Provisioning
Many teams provision capacity based on the "peak" of their traffic. If your peak is 10,000 requests per second but your average is 500, you are wasting 9,500 units of capacity for most of the day.
- Fix: Always use Auto Scaling with aggressive target tracking, or use On-Demand for workloads with high variance.
Pitfall 2: Neglecting Item Size
Developers often store large objects like base64-encoded images or full JSON payloads in a single DynamoDB item. This causes the item to exceed the 400 KB limit and bloats your RCU/WCU consumption.
- Fix: Follow the "Pointer Pattern." Store the binary or large text in S3 and the pointer/metadata in DynamoDB.
Pitfall 3: Inefficient Index Design
Creating too many GSIs can significantly increase your write costs. Every time you write to the base table, DynamoDB must also update every GSI. If you have 5 GSIs, one write operation effectively becomes 6 write operations.
- Fix: Only create the indexes you absolutely need for your query patterns. Periodically audit your GSIs to see if they are actually being used.
Comparison: Pricing Models at a Glance
| Feature | On-Demand | Provisioned | Reserved |
|---|---|---|---|
| Pricing | Per request | Per unit/hour | Per unit/year |
| Flexibility | Highest | Medium | Low |
| Best For | Spiky/New workloads | Predictable traffic | Steady-state base load |
| Management | None | Auto Scaling recommended | Manual capacity planning |
Step-by-Step: Analyzing Your Costs
If you want to get a handle on your current DynamoDB spend, follow these steps:
- Open the AWS Cost Explorer: Filter by "Service: DynamoDB" to see your total spend over the last three months.
- Enable CloudWatch Metrics: Look at
ConsumedReadCapacityUnitsandConsumedWriteCapacityUnitsversusProvisionedReadCapacityUnitsandProvisionedWriteCapacityUnits. - Identify the Gap: If your provisioned capacity is significantly higher than your consumed capacity, you are over-provisioning. Adjust your Auto Scaling policies to be more responsive.
- Check for Scans: Look at the
ScanAPI metrics in CloudWatch. If you see high scan volumes, identify the offending code and refactor it to useQueryorGetItem. - Review TTL: Ensure your tables have TTL enabled if they contain time-series or ephemeral data.
- Analyze Item Size: Use the
DescribeTableAPI to check average item size. If it is consistently high, evaluate if you can move data to S3.
Note: The Cost of Global Tables If you enable DynamoDB Global Tables to replicate your data across multiple regions, you pay for the replicated writes. This effectively doubles your write costs because every write in the primary region is replicated to the secondary region. Only enable Global Tables if your application truly requires multi-region availability or low-latency access from different geographic locations.
Designing for Cost: A Practical Example
Imagine you are building a social media feed. You have a table called Posts.
Initial thought:
Store every comment inside the Post item as a list of strings.
- Problem: As a post gets popular, the item size grows. Eventually, the item hits the 400 KB limit, and the write costs skyrocket because every time someone adds a comment, you have to read, modify, and write the entire list of comments back to the database.
Optimized approach:
Store Posts in one table and Comments in another table with a partition key of PostId.
- Why it works: Adding a comment is now a single
PutItemoperation in theCommentstable. You only pay for the size of that one comment. You don't have to read the post or other comments. This is a classic "Relational" approach applied to NoSQL, and it saves significantly on throughput.
Best Practices Checklist
- Use the Right Tool: If you need complex SQL joins, DynamoDB might not be the right choice. Don't force a relational model into a NoSQL database, as it will lead to expensive, inefficient queries.
- Monitor, Monitor, Monitor: Use CloudWatch Alarms to alert you when your provisioned capacity utilization drops below 30%.
- Keep Items Small: Aim for items under 1 KB whenever possible.
- Use TTL: It is the "set it and forget it" way to manage storage costs.
- Audit GSIs: Remove unused indexes to save on both storage and write throughput.
- Choose Consistency Wisely: Default to eventually consistent reads for non-critical data.
- Use Batching: Combine multiple operations into
BatchGetItemandBatchWriteItemto reduce request overhead.
Common Questions (FAQ)
Q: Does it cost more to read from a GSI than a base table? A: You pay for the read throughput on the GSI, which is the same rate as the base table. However, since the GSI only contains a subset of attributes, the items are often smaller, which might result in more items fitting into a single RCU.
Q: Can I change from Provisioned to On-Demand? A: Yes, you can switch between capacity modes once every 24 hours. This is useful if you have a scheduled event (like a Black Friday sale) and want to switch to On-Demand for the duration of the spike.
Q: What is the most expensive part of DynamoDB? A: Usually, it is the throughput (RCUs/WCUs) for high-traffic applications. If your application is idle, storage might be the largest cost.
Q: Is there a way to see my cost per request? A: AWS does not provide a "cost per request" dashboard. You must divide your total monthly spend by the number of requests (found in CloudWatch) to calculate your effective cost per request.
Conclusion: Key Takeaways
Mastering DynamoDB pricing is a journey of understanding the trade-offs between performance, consistency, and cost. By following these principles, you ensure your architecture remains sustainable as your application grows:
- Throughput is the primary driver: Focus on optimizing your read and write patterns first. Use
QueryoverScanand leverage eventual consistency whenever possible. - Item size is money: Larger items cost more to store and more to read/write. Keep your items lean by offloading large blobs to S3.
- Choose your mode wisely: Use On-Demand for unknown patterns and Provisioned (with Auto Scaling) for stable, predictable traffic.
- Use TTL for automatic cleanup: Never pay for data you no longer need. Use TTL to prune stale items automatically.
- Avoid the "Hot Partition" trap: Use high-cardinality keys to ensure your data—and your costs—are distributed evenly across the system.
- Optimize your indexes: Treat GSIs as a precious resource. Only create them when necessary and remove them when they are no longer in use.
- Commit for the long haul: If you have a steady-state workload, look into Reserved Capacity to unlock massive discounts that aren't available to pay-as-you-go users.
By applying these strategies, you move from being a passive consumer of cloud services to an active architect who builds systems that are as efficient as they are scalable. DynamoDB is a powerful engine, but like any engine, it requires the right tuning to get the best performance for the lowest fuel consumption.
Continue the course
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons