Six months ago, SuperDealz ran on a single Next.js application backed by one PostgreSQL database. It worked. Until it didn't. This is the story of how we migrated to a microservices architecture — and the painful lessons we learned along the way.
Why We Migrated
The breaking point came during our Republic Day sale. Traffic spiked 8x, and three things happened simultaneously: the deal feed slowed to a crawl, QR redemptions started timing out, and the merchant dashboard became unresponsive. All because a single database connection pool was shared across every feature.
We realised that our monolith had become a single point of failure. One slow query in the analytics module could starve the redemption system of connections. We needed isolation.
The Architecture
We decomposed into five core services:
1. Deal Service — Manages deal CRUD, discovery, and search. Backed by PostgreSQL + Elasticsearch for full-text search.
2. Redemption Service — Handles QR generation, verification, and settlement. Uses Redis for deduplication and rate limiting.
3. User Service — Authentication, profiles, and loyalty point management. Separated to allow independent scaling during auth-heavy periods (morning app opens).
4. Merchant Service — Dashboard API, analytics, and deal management. Can be slower without affecting consumer-facing features.
5. Notification Service — Push notifications, email, and SMS. Fully async via message queue.
What Went Wrong
Migration was not smooth. Three key mistakes:
Distributed transactions — We initially tried to maintain ACID consistency across services. This was a mistake. We moved to an eventual consistency model with saga patterns for multi-service operations like deal redemption.
Premature optimization — We over-decomposed early. Our first attempt had 12 microservices. We consolidated to 5 after realising that the operational overhead of 12 services exceeded the benefits for our current scale.
Testing gaps — Unit tests passed. Integration tests passed. But end-to-end tests across service boundaries? We didn't have enough. Two production incidents in the first week were caused by contract mismatches between services.
Results
Post-migration, the improvements were dramatic:
Key Takeaway
Don't start with microservices. Start with a well-structured monolith, identify the seams that need independent scaling, and decompose surgically. The best architecture is the one that matches your current scale — not the one you hope to reach.