Use when designing or reviewing a DynamoDB table: access patterns, partition and sort keys, single-table design, GSIs and sparse indexes, hot partitions, one-to-many and many-to-many modeling, capacity mode and cost, or the Terraform for the table.
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
A DynamoDB schema follows the queries. A table designed before the queries are known has to be redesigned, and a key change means a backfill of every item.
If the user asks for a table design and has not listed the access patterns, stop. Do not write tables, keys, GSIs, or a "starting schema" in that reply, not even one built on assumed patterns. Instead:
The same rule applies when the user pushes back ("just give me a starting schema", "we can migrate later"). Explain that a migration means a scan and rewrite of every item. Then offer to draft the access-pattern list with the user. Design only after the user confirms a list.
The rule is for data-model design. It does not stop a build. When the user asks you to build a service and the table is one part of it, such as "an API that reads and writes an orders table", build the table and do not stop:
order_id), with no sort key and no GSIs. A GSI added later backfills itself. A changed primary key does not.If the build needs several related entities, such as users, organizations and projects, the data model is the design question. Stop and ask as described above.
All patterns are in
references/dynamodb-patterns.md.
| Topic | Key Insight |
|---|---|
| Data modeling | Design access patterns FIRST, schema second |
| Single-table design | Items queried together live together |
| GSIs | Multi-attribute composite keys avoid synthetic key hacks |
| Cost optimization | Filter expressions do NOT reduce read costs |
| Sort order control | # prefix positions parent at sort boundary; numeric difference enables reverse integer ordering |
| Sparse indexes | Entity-type filter (always-on attr) vs conditional filter (add/remove attr on state change) |
| Reference counts | TransactWriteItems: child PutItem (attribute_not_exists) + parent UpdateItem increment |
| Hot partitions | Timestamp-shard GSI PK by day; read-shard caches across N copies |
| Many-to-many | Adjacency list: link item in base table + GSI projects into second parent's collection |
| Uniqueness enforcement | Uniqueness tracking item (no data) + TransactWriteItems with attribute_not_exists on each |
TOURNAMENT#X#REGION#Y) — use multi-attribute composite keys (provider v6.29.0+)ISSUE#9 sorts after ISSUE#100 lexicographically; zero-pad to fixed width (ISSUE#00000009)ISSUE#CLOSED#<id>)FilterExpression: TTL > current_epochattribute_not_exists enforce the constraint| Use Single Table When | Use Multiple Tables When |
|---|---|
| Items queried together | Completely independent data |
| Same team owns all data | Different teams, different access |
| Need transactional writes | Data has vastly different access patterns |
Migrations are ranked by difficulty. Always check if a change is purely additive before planning ETL.
| Situation | Additive? | ETL Required? | Strategy |
|---|---|---|---|
| New optional attribute on existing entity | Yes | No | Handle missing attribute with a default in app code (lazy loading) |
| New entity, no relational access pattern | Yes | No | Start writing new items immediately — zero changes to existing data |
| New entity co-located with existing parent | Yes | No | Match parent PK, assign new SK prefix — no backfill |
| New entity needing a new GSI item collection | No | Yes | Scan + UpdateItem to add GSI attributes to all existing parent items |
| Refactoring an existing access pattern | No | Yes | Redesign SK + new GSIs + Scan + UpdateItem on all affected items |
For large tables, use parallel scans (TotalSegments + Segment) to distribute the ETL job — DynamoDB handles all worker coordination.
| Use Multi-Attribute Keys | Keep Synthetic Keys |
|---|---|
| New GSIs on existing tables (no backfill) | Base table PK/SK (not supported) |
| Attributes have distinct types (Number + String) | Need begins_with() across entity types |
| Hierarchical drill-down queries | Single-table overloaded GSI with mixed entities |
| Terraform AWS provider v6.29.0+ | Legacy tables where migration cost > benefit |
| Feature | AWS GA | Terraform AWS Provider |
|---|---|---|
| Multi-attribute composite GSI keys | Nov 2025 | v6.29.0+ (PR #45357) |
For prices, use the AWS Pricing MCP server (awslabs.aws-pricing-mcp-server). Its README has the setup. Prices in this skill are dated examples, not quotes.
Load references/dynamodb-patterns.md for all DynamoDB questions — it covers modeling patterns (item collections, # prefix trick, sparse indexes, reference counts, TTL guard), GSI design (composite keys, multi-attribute keys), cost, and Terraform examples.
a-pavithraa/aws-serverless-skill
d96e7f9
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.