🚀 Inspiration
Every sneaker drop, limited merch release, or flash sale has the same nightmare — overselling. We've all seen it: a product shows "1 left", five people buy it, and then five people get cancellation emails. Trust breaks. Brands lose credibility. Customers feel cheated.
I asked myself — what if this problem was solved at the database level, not the application level?
That's how DropRush was born.
⚡ What I Built
DropRush is a full-stack flash sale platform where brands can launch limited-stock drops and shoppers can claim them the moment they go live — with a mathematical guarantee of zero oversells.
Two interfaces:
/— Public storefront with live countdown timers, real-time stock bars, and a claim button/admin— Brand dashboard with drop creation, live stats, and inventory tracking
🔬 How I Built It
The core insight was simple: don't solve race conditions in code — solve them in the database.
I used AWS DynamoDB's atomic UpdateItem with a ConditionExpression:
UpdateItem({
UpdateExpression: "SET remainingStock = remainingStock - :one",
ConditionExpression: "remainingStock > :zero"
})
This single operation is atomic at the DynamoDB level. If 1000 users hit claim simultaneously, DynamoDB serializes the writes internally — and stops exactly when stock hits zero. No locks. No queues. No application-level logic needed.
DynamoDB Single-Table Design:
| Entity | PK | SK |
|---|---|---|
| Drop metadata | DROP#<id> |
META |
| Claim record | DROP#<id> |
CLAIM#<userId> |
GSI1 powers the live drop feed sorted by launch time:
GSI1PK = STATUS#activeGSI1SK = <startTimeISO>#<dropId>
The frontend was scaffolded using Vercel v0, deployed on Vercel, and connected to DynamoDB via AWS SDK v3.
🧗 Challenges I Faced
1. The hydration problem
Next.js renders on the server first — but Date.now() returns different values on server vs client. This caused React hydration errors on countdown timers. I fixed it by initializing timer state as null and only calculating on the client after mount.
2. Credentials in scripts vs Next.js
.env.local is automatically loaded by Next.js dev server — but not by raw node scripts/... commands. I had to manually set environment variables for setup scripts, and document this clearly.
3. Making the race condition visible
The atomic guarantee is invisible unless you can show it failing gracefully. I solved this by using 2 different browsers (Chrome, Edge) to simulate concurrent users — each with a different localStorage identity — and demonstrating live stock depletion in real time.
📚 What I Learned
- DynamoDB single-table design is powerful but requires upfront planning of access patterns
ConditionExpressionin DynamoDB is the right tool for inventory management at scale- Vercel v0 dramatically accelerates UI scaffolding — what took hours now takes minutes
- The gap between "it works locally" and "it works at scale" is bridged by choosing the right database primitive
🏆 What's Next
- Stripe integration for real payments per drop
- Email/SMS notifications when a drop goes live
- Waitlist system for sold-out drops
- Multi-region Aurora DSQL for globally distributed drops
Built With
- aws-dynamodb
- aws-sdk-v3
- next.js
- react
- tailwind-css
- typescript
- vercel
- vercel-v0
Log in or sign up for Devpost to join the conversation.