Amazon DynamoDB Table Design Patterns - Single-Table Design and GSI Strategies

Learn about DynamoDB partition key design, single-table design, and how to implement diverse access patterns using GSIs.

Overview of DynamoDB

DynamoDB is a fully managed NoSQL database that delivers single-digit millisecond latency. Unlike RDS, it is schemaless and accesses data through a combination of partition keys and sort keys. As the standard data store for serverless architectures, it is commonly used alongside Lambda and API Gateway. It offers two capacity modes: on-demand and provisioned. DynamoDB automatically scales on a per-partition basis, with each partition handling up to 10 GB of data and 3,000 RCU / 1,000 WCU per second. There is no upper limit on table size, accommodating hundreds of TB of data.

Table Design

The partition key directly affects data distribution, so choose attributes with high cardinality (such as user IDs or order IDs). In single-table design, the PK is prefixed like "USER#123" or "ORDER#456", and the SK represents entity types and relationships. A Query specifying the PK can retrieve both user information and order history in a single call. GSIs support different access patterns (e.g., looking up users by email address or searching orders by date range), and you can create up to 20 per table. Choosing low-cardinality values like dates or status codes for partition keys causes the hot partition problem where access concentrates on specific partitions. In such cases, append a suffix (random value or partial timestamp) to the key to distribute requests.

GSI and Single-Table Design

Global Secondary Indexes (GSIs) allow queries using a different partition key and sort key from the main table. In single-table design, multiple entities (users, orders, products) are stored in a single table, and GSI overloading handles diverse access patterns. Prefixes like 'USER#123' for PK and 'ORDER#456' for SK are used, and entities are filtered with the begins_with condition. Sparse indexes include only items with specific attributes in the index, reducing index size and cost. For a deeper understanding of NoSQL design patterns, specialized books (Amazon) are a great resource.

Design Best Practices and Pitfalls

Single-table design is widely recommended as a DynamoDB best practice, but it is not suitable for all cases. For applications with complex inter-entity relationships and frequently changing access patterns, separating tables may be easier to operate. GSI write throttling propagates to the main table, so design GSI capacity to keep up with the main table's write volume. When writing more than 25 items with BatchWriteItem, always implement retry logic for unprocessed items. In event-driven patterns combining DynamoDB Streams with Lambda, note that Lambda's parallel execution depends on the number of partitions. Adaptive Capacity automatically raises throughput for hot partitions, but cannot exceed the total provisioned capacity for the table.

When to Use DynamoDB vs. RDS

DynamoDB specializes in key-based reads and writes, delivering extremely low latency for simple key lookups and range queries. Complex JOIN queries, aggregations, and workloads centered on ACID transactions are better suited for RDS (Aurora / PostgreSQL). DynamoDB transactions (TransactWriteItems / TransactGetItems) have a limit of 100 items and do not support complex transactions spanning multiple tables. DynamoDB is ideal for user profiles, session stores, real-time leaderboards, and IoT device data ingestion. For workloads primarily consisting of reporting and analytical queries, it is more efficient to export from DynamoDB to S3 and analyze with Athena, or sync to OpenSearch via DynamoDB Streams.

DynamoDB Cost Optimization

DynamoDB's on-demand mode charges per read (approximately $0.25 per million RRUs) and per write (approximately $1.25 per million WRUs). Provisioned mode charges hourly for WCU/RCU, and when combined with Auto Scaling, it improves cost efficiency for stable workloads. Reserved capacity offers discounts of up to 77%. Since GSIs consume their own capacity, remove unnecessary GSIs and minimize projection attributes to reduce storage costs. Use TTL to automatically delete expired data and keep storage costs down.

Summary

DynamoDB is a NoSQL database that achieves single-digit millisecond latency through partition key and sort key design. GSI overloading and single-table design support diverse access patterns, while sparse indexes optimize index costs. By choosing between on-demand and provisioned modes and using TTL for automatic data deletion, you can manage costs efficiently.