Partition Keys, Sort Keys, and Data Modeling
DynamoDB organizes data using a primary key that uniquely identifies each item. The primary key can be simple (partition key only) or composite (partition key + sort key). Understanding key design is fundamental to DynamoDB performance.
A partition key determines which physical partition stores the item. DynamoDB distributes data across partitions using hash-based routing. If your partition key has low cardinality (few distinct values), you create a "hot partition"—one partition receives disproportionate traffic, limiting throughput. For example, using status as a partition key for an orders table means all "pending" orders go to one partition.
A composite key adds a sort key that allows you to store multiple items with the same partition key, sorted by the sort key. For an orders table, the partition key could be customer_id and the sort key order_date, enabling efficient queries like "get all orders for customer X between two dates."
LSIs (Local Secondary Indexes) share the same partition key as the base table but use a different sort key. They must be created at table creation and cannot be added later. Use LSIs when you need alternative sort orders on the same partition key.
GSIs (Global Secondary Indexes) have their own partition and sort keys, independent of the base table. You can add GSIs after table creation. A GSI on product_id + order_date lets you query orders by product across all customers.
Design tip: Think about your access patterns first, then design keys to serve those patterns. DynamoDB is optimized for specific query patterns, not ad-hoc joins like relational databases.
On-Demand vs Provisioned Capacity and Auto-Scaling
DynamoDB offers two capacity modes with significantly different cost and performance characteristics.
On-Demand Mode charges per read and write request. There is no capacity planning—DynamoDB automatically handles traffic spikes. This mode is ideal for unpredictable workloads, new applications with unknown traffic patterns, or tables with infrequent, bursty access. For example, a ticketing system that sells out concerts needs sudden write bursts that on-demand handles gracefully.
Provisioned Mode lets you specify read capacity units (RCUs) and write capacity units (WCUs). You pay for the provisioned capacity regardless of actual usage. This mode is cheaper for predictable, steady-state workloads. A social media feed with consistent daily traffic benefits from provisioned capacity with auto-scaling.
Auto-Scaling adjusts provisioned capacity based on utilization. You define a target utilization percentage (e.g., 70%) and min/max capacity bounds. DynamoDB monitors utilization and adjusts capacity every minute. During a flash sale, auto-scaling increases capacity to handle the spike, then reduces it when traffic normalizes.
One RCU allows one strongly consistent read per second for items up to 4 KB, or two eventually consistent reads per second. One WCU allows one write per second for items up to 1 KB. Understanding these units is critical for accurate capacity planning.
Use the AWS DynamoDB Capacity Calculator to estimate costs before choosing a mode. A common pattern is starting with on-demand for prototyping, then switching to provisioned with auto-scaling once traffic patterns stabilize.
DynamoDB Streams and Global Tables
DynamoDB Streams capture a time-ordered sequence of item-level modifications in a DynamoDB table. Streams enable event-driven architectures by triggering AWS Lambda functions when data changes.
For example, when a user places an order, a DynamoDB Stream triggers a Lambda function that sends a confirmation email, updates inventory in another table, and notifies the shipping service. This decouples the order processing from downstream actions.
Stream records are available for 24 hours and can be read using the DynamoDB Streams API. Each record contains the before and after image of the modified item, enabling you to detect what changed. You can configure streams to capture only the new image, old image, or both.
Global Tables provide multi-region, multi-active replication. You enable DynamoDB Streams on a table, then create a Global Table that replicates data across regions. Writes to any replica are propagated to all other replicas within seconds.
A gaming company with players in North America and Europe might use Global Tables to replicate player data between us-east-1 and eu-west-1. Players experience low-latency reads from their nearest region, and writes propagate globally.
Conflict resolution in Global Tables uses "last writer wins" semantics based on timestamps. If two regions write to the same item simultaneously, the most recent write (by system clock) wins. Design your application to handle potential conflicts or use conditional writes to prevent them.
DAX Caching for Microsecond Latency
Amazon DynamoDB Accelerator (DAX) is a fully managed, in-memory caching layer for DynamoDB that delivers microsecond read latency for frequently accessed data. DAX is API-compatible with DynamoDB, requiring minimal code changes.
DAX operates as a cluster with primary and replica nodes. The primary node handles writes and serves reads, while replica nodes distribute read traffic. If the primary fails, a replica is promoted automatically. DAX caches both query and scan results, reducing the need to hit DynamoDB.
Consider an e-commerce product catalog. Product details are read thousands of times per second but updated infrequently. DAX caches these reads, returning cached results in microseconds versus DynamoDB's single-digit millisecond latency. The cache hit ratio depends on your access patterns—DAX works best with skewed access patterns where a subset of items receives disproportionate reads.
DAX supports two caching layers:
- Item Cache: Caches individual GetItem and BatchGetItem results
- Query Cache: Caches Query and Scan results
Write-through behavior ensures that when an item is written to DynamoDB, the DAX cache is updated simultaneously. This prevents stale data in the cache. However, DAX does not invalidate cache entries when external processes modify DynamoDB data directly.
DAX is a good fit when you need consistent microsecond reads and have read-heavy access patterns. For write-heavy workloads or when external processes modify data, consider invalidation strategies or skip DAX entirely.
Quiz
1. What happens when a DynamoDB partition key has low cardinality?
2. Which capacity mode is best for unpredictable traffic patterns?
3. When can you create a Local Secondary Index (LSI)?
4. What conflict resolution strategy do DynamoDB Global Tables use?
5. What latency does DAX provide for cached reads?
Flashcards
Question
Partition Key
Click to reveal answer
Answer
The primary attribute that determines which physical partition stores an item. Must have high cardinality to distribute traffic evenly across partitions.
Question
Composite Primary Key
Click to reveal answer
Answer
A primary key consisting of a partition key and a sort key. Allows multiple items with the same partition key, sorted by the sort key value.
Question
LSI vs GSI
Click to reveal answer
Answer
LSI shares the base table partition key with a different sort key (must be created at table creation). GSI has independent partition and sort keys and can be added after creation.
Question
Read Capacity Unit (RCU)
Click to reveal answer
Answer
One RCU allows one strongly consistent read per second for items up to 4 KB, or two eventually consistent reads per second for items up to 4 KB.
Question
DynamoDB Streams
Click to reveal answer
Answer
A time-ordered sequence of item-level modifications available for 24 hours. Triggers Lambda functions for event-driven processing. Records are available for 24 hours.
Question
DAX
Click to reveal answer
Answer
DynamoDB Accelerator - a fully managed in-memory cache providing microsecond read latency. API-compatible with DynamoDB, supports item cache and query cache layers.
Revision Notes
Key Takeaways
- 1. Design partition keys with high cardinality to avoid hot partitions
- 2. On-demand mode suits unpredictable workloads; provisioned suits steady-state
- 3. LSIs must be created at table creation; GSIs can be added later
- 4. DynamoDB Streams enable event-driven processing with Lambda triggers
- 5. Global Tables provide multi-region replication with last-writer-wins conflict resolution
- 6. DAX delivers microsecond reads for skewed access patterns
Interview Tips
- • Explain hot partition problems and solutions (composite keys, sharding techniques)
- • Compare on-demand vs provisioned capacity cost tradeoffs
- • Describe how DynamoDB Streams enable exactly-once processing patterns
- • Discuss Global Tables consistency model and conflict resolution
Cheat Sheet
Partition key = high cardinality. Composite key = partition + sort. LSIs = same partition, alternate sort (create at table creation). GSIs = independent keys (add anytime). On-demand = pay per request, no planning. Provisioned = fixed capacity + auto-scaling. Streams = event triggers. Global Tables = multi-region, last writer wins. DAX = microsecond cache reads.