DynamoDB Primary Keys
The primary key is the most important design decision you make for a DynamoDB table. It determines how data is stored, how fast it is retrieved, and how well the table scales. Choosing the wrong primary key leads to performance problems that are very hard to fix later.
What a Primary Key Does
A primary key uniquely identifies every item in a table. No two items in the same table can have the same primary key value. When you want to retrieve a specific item, you provide its primary key and DynamoDB finds it instantly.
Think of a primary key as a locker number in a school. Each student has a unique locker number. To open a specific locker, you need the exact number — there is no need to search every locker in the hallway.
Type 1: Partition Key (Simple Primary Key)
A partition key is a single attribute that uniquely identifies each item. DynamoDB uses this value to decide where to store the item across its physical storage nodes (partitions). This process is called hashing.
How Hashing Works
Partition Key Value → Hash Function → Physical Partition ───────────────────────────────────────────────────────── "U001" → Hash() → Partition A "U002" → Hash() → Partition B "U003" → Hash() → Partition A "U004" → Hash() → Partition C
The hash function distributes items evenly across partitions. This is how DynamoDB scales — data spreads across many nodes, so no single node gets overloaded.
Example: Users Table with Partition Key
| UserID (Partition Key) | Name | City |
|---|---|---|
| U001 | Aditya Verma | Pune |
| U002 | Sneha Iyer | Chennai |
| U003 | Rohan Das | Kolkata |
Each UserID is unique, so you can retrieve any user directly by their ID.
When to Use a Simple Partition Key
Use a simple partition key when:
- Each item is truly independent (one user, one product, one session)
- You always know the exact key value when retrieving data
- You do not need to retrieve groups of related items from one table in a single query
Type 2: Composite Primary Key (Partition Key + Sort Key)
A composite key uses two attributes together: a partition key and a sort key. The partition key groups related items on the same physical partition. The sort key orders those items within the group.
Two items can share the same partition key value as long as they have different sort key values.
Example: Orders Table with Composite Key
TABLE: Orders ┌───────────────────────────────────────────────────────────┐ │ UserID (PK) │ OrderDate (SK) │ Product │ Amount │ ├───────────────┼──────────────────┼──────────────┼─────────┤ │ U001 │ 2024-01-05 │ Laptop │ 85000 │ │ U001 │ 2024-03-12 │ Mouse │ 1200 │ │ U001 │ 2024-06-20 │ Monitor │ 22000 │ ├───────────────┼──────────────────┼──────────────┼─────────┤ │ U002 │ 2024-02-14 │ Keyboard │ 3500 │ │ U002 │ 2024-04-01 │ Webcam │ 4800 │ └───────────────┴──────────────────┴──────────────┴─────────┘
User U001 has three orders, each on a different date. The combination of UserID + OrderDate is unique for every row. You can query all orders for U001 in a single operation because they share the same partition key.
Sort Key Powers Range Queries
The sort key enables powerful queries on a range of values. For the Orders table above, you can ask:
- Get all orders for user U001 after 2024-02-01
- Get all orders for user U001 between 2024-01-01 and 2024-06-30
- Get the most recent order for user U001
None of these queries are possible with a simple partition key alone.
Choosing a Good Partition Key
The single most important rule for DynamoDB performance: choose a partition key with high cardinality. Cardinality means how many unique values the attribute can have.
High Cardinality vs Low Cardinality
| Attribute | Cardinality | Good Partition Key? |
|---|---|---|
| UserID (UUID) | Millions of unique values | Yes — distributes well |
| OrderID | Millions of unique values | Yes — distributes well |
| Country | ~200 values | Poor — too many items on few partitions |
| Status ("Active"/"Inactive") | 2 values | Very poor — creates hot partitions |
The Hot Partition Problem
If your partition key has too few unique values, most of your data lands on the same partition. That partition gets overwhelmed with traffic while others sit idle. This is called a hot partition. DynamoDB throttles requests to an overloaded partition, which causes slowness.
BAD DESIGN: Status as Partition Key Partition "Active" → 95% of traffic hits here → THROTTLED Partition "Inactive" → 5% of traffic hits here → Idle
Sort Key Best Practices
Sort keys enable range queries, so they work best when they represent a time, sequence, or hierarchical value:
- Timestamps:
2024-06-01T10:30:00Z - Version numbers:
v1,v2,v3 - Status + Date combinations:
SHIPPED#2024-06-01
Using prefixed strings in sort keys like ORDER#2024-06-01 is a common advanced technique called composite sort key design, covered in the Design Patterns topic.
Primary Key Type Restrictions
Both the partition key and sort key must use one of these three data types: String, Number, or Binary. Boolean, Map, List, and Set are not allowed as key types.
You Cannot Change a Primary Key After Creation
This is a critical limitation. Once you create a DynamoDB table with a primary key definition, you cannot change or add key attributes. If you choose the wrong primary key, you must create a new table, migrate your data, and update your application. Plan your primary key carefully before creating the table.
Summary
| Key Type | Components | Best For |
|---|---|---|
| Simple Primary Key | Partition Key only | Independent items with unique IDs |
| Composite Primary Key | Partition Key + Sort Key | Groups of related items with range queries |
