What Is DynamoDB?
DynamoDB is AWS's fully managed NoSQL database. It's a key-value and document store that scales horizontally without you managing servers, shards, or replicas. You define a table, pick a partition key (and optionally a sort key), and AWS handles the rest.
It's not a general-purpose database. It's fast (single-digit millisecond reads at any scale) but inflexible. You need to know your access patterns before you design your table. If you're coming from a relational background, this feels backwards. In SQL you model your data first and write queries later. In DynamoDB you model your queries first and structure your data around them.
When to Use It
Good fit:
- High-throughput, low-latency reads and writes
- Known access patterns that won't change frequently
- Serverless architectures (Lambda + DynamoDB is a natural pairing)
- Multi-tenant SaaS where each tenant's data is isolated by partition key
- Event stores, session stores, user profiles, IoT telemetry
Poor fit:
- Ad-hoc reporting and analytics (use Athena or Redshift instead)
- Complex joins across entities (use RDS/Aurora)
- Full-text search (use OpenSearch)
- Small datasets with complex query needs where RDS is simpler and cheaper
Key Concepts
Partition Key and Sort Key
Every item needs a partition key (PK). This determines which physical partition stores the item. Optional sort key (SK) allows multiple items per partition, queryable in sorted order.
PK: USER#12345
SK: PROFILE β user's profile data
SK: ORDER#2024-001 β user's first order
SK: ORDER#2024-002 β user's second order
Single-Table Design
Instead of one table per entity (like relational), you store multiple entity types in one table and use composite keys to organize them. This lets you fetch related data in a single query.
Global Secondary Indexes (GSIs)
GSIs give you alternate query patterns. You can project different attributes as the PK/SK of a GSI to support access patterns your base table doesn't cover. You get up to 20 GSIs per table.
On-Demand vs Provisioned Capacity
- On-demand: Pay per request. No capacity planning. Good for unpredictable or spiky workloads.
- Provisioned: Set read/write capacity units. Cheaper for steady-state workloads. Add auto-scaling to handle variance.
CDK Example
import { Table, AttributeType, BillingMode } from 'aws-cdk-lib/aws-dynamodb';
const table = new Table(this, 'AppTable', {
tableName: 'my-app-table',
partitionKey: { name: 'PK', type: AttributeType.STRING },
sortKey: { name: 'SK', type: AttributeType.STRING },
billingMode: BillingMode.PAY_PER_REQUEST,
pointInTimeRecovery: true,
deletionProtection: true,
});
// GSI for inverted access pattern
table.addGlobalSecondaryIndex({
indexName: 'GSI1',
partitionKey: { name: 'GSI1PK', type: AttributeType.STRING },
sortKey: { name: 'GSI1SK', type: AttributeType.STRING },
});
Common Patterns
Tenant isolation
Use the tenant ID as part of the partition key: TENANT#acme. This keeps data physically separated and makes it impossible to accidentally query across tenants.
Time-series queries
Use a sort key with an ISO timestamp: SK: 2024-06-15T10:30:00Z. Query with begins_with or between operators to get time ranges.
Sparse indexes
A GSI only includes items that have the indexed attributes. Put a status attribute on items that need processing, create a GSI on it, and items automatically leave the index when you remove the attribute.
Cost Considerations
- On-demand: ~$1.25 per million write request units, ~$0.25 per million read request units
- Storage: $0.25/GB/month
- GSIs multiply your write costs (each GSI replicates writes)
- DynamoDB Streams add ~$0.02 per 100K read requests
For most serverless applications, DynamoDB is significantly cheaper than RDS because you're not paying for idle compute. The break-even point where provisioned RDS becomes cheaper is usually high-throughput, steady-state workloads with complex query needs.
Further Reading
- DynamoDB Developer Guide
- DynamoDB best practices
- DynamoDB pricing
- DynamoDB CDK constructs
- Using DynamoDB with .NET: SDK options, AoT-compatible patterns, and FluentDynamoDB
Related Blog Posts
Looking for hands-on help? View my AWS architecture services β