Technical
The DynamoDB Free Tier: What You Actually Get
Every article about DynamoDB's free tier gives you the raw numbers without context. 25 WCU, 25 RCU, 25GB. But what does that actually mean in terms of real application usage? Here is the practical breakdown.
The Raw Numbers
AWS DynamoDB free tier (perpetual, does not expire):
- 25 Write Capacity Units (WCU): Up to 25 writes/second (items up to 1KB)
- 25 Read Capacity Units (RCU): Up to 25 reads/second (strongly consistent, items up to 4KB)
- 25 GB storage: Data plus indexes
- 2 Global Secondary Indexes per table
What That Translates To
Writes (25 WCU)
25 writes per second = 2.16 million writes per day = 64.8 million writes per month.
For a blog platform, writes happen when:
- Creating a new post (1 write)
- Updating a post (1 write)
- Adding a subscriber (1 write)
- Recording a newsletter send (1 write)
At 64.8 million writes per month, you could create 2 million blog posts per month and still be within the free tier. No blog needs that.
Reads (25 RCU)
25 strongly consistent reads per second for items up to 4KB. For eventually consistent reads (which is fine for a blog), you get 50 reads per second.
50 reads/second = 4.32 million reads per day = 129.6 million reads per month.
For a blog:
- Each page view requires 1-2 reads (post data + categories)
- At 50 reads/second, you handle 25 concurrent page views
- With frontend caching (revalidate:60), most requests never hit DynamoDB
Storage (25 GB)
A typical blog post (title, body, metadata) is 5-10KB. At 10KB per post:
- 25 GB = ~2.5 million posts
- Plus GSI storage (roughly doubles the data)
- So approximately 1.25 million posts within free tier
The Gotcha: Provisioned vs On-Demand
The free tier ONLY applies to provisioned capacity mode. On-demand mode is pay-per-request and does not qualify for the free tier.
# Correct: provisioned mode (free tier eligible)
table = dynamodb.create_table(
TableName='plai-content',
ProvisionedThroughput={
'ReadCapacityUnits': 5,
'WriteCapacityUnits': 5,
},
# ...
)
# Wrong: on-demand mode (charges per request, no free tier)
table = dynamodb.create_table(
TableName='plai-content',
BillingMode='PAY_PER_REQUEST',
# ...
)The GSI Limit
You get 2 GSIs per table within the free tier. Each GSI has its own provisioned capacity that counts against the 25 WCU/RCU limits. Plan your access patterns carefully. Two GSIs are enough for most simple applications.
The Bottom Line
For a blog, portfolio, or small SaaS with moderate traffic, DynamoDB's free tier is more than sufficient. The key is using provisioned mode, keeping items small, and leveraging frontend caching to reduce database reads.
See the DynamoDB pricing page for the current free tier details.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read