Case Study - Single-File Monolith to CQRS: Scaling a StockX-Like Marketplace
I was the first full-stack engineer hired to fix BUMP scaling problem. The entire backend was a single-file Parse.js app. I migrated it to NestJS + GraphQL and architected a CQRS event-driven system.
- Client
- BUMP (YC W18)
- Year
- Service
- Backend Migration, CQRS Architecture, GraphQL API

The Challenge
BUMP was a YC W18 startup building a StockX-like marketplace for streetwear and sneakers. They'd built an MVP quickly using Parse.js (a "backend-as-a-service" platform), which let them ship fast.
But by the time I joined as the first full-stack engineer, the cracks were showing:
- The entire backend was a single file, literally one massive Parse.js script
- No separation between business logic, database queries, and API endpoints
- Adding features meant scrolling through thousands of lines to find the right function
- The mobile team (iOS/Android) was blocked waiting for backend changes
- The order system was a nightmare: buyers, sellers, verification, shipping, payouts, all tangled together
The CTO knew they needed to rebuild the backend without shutting down the business. No downtime. No breaking changes. Just migrate and scale.
What I Did
I was hired specifically to fix the scaling problem. Here's how I did it:
Phase 1: Migrate Parse.js → NestJS + GraphQL
- Rebuilt the entire backend in NestJS (a TypeScript Node.js framework)
- Exposed a GraphQL API for the mobile apps to consume
- Coordinated with the iOS and Android teams to ensure a smooth migration
- Ran both systems in parallel during the transition (Parse.js + NestJS) to avoid breaking prod
- Deprecated Parse.js once all clients had migrated to the new API
Phase 2: Architect a CQRS Event-Driven Order System
- The old order system was a mess: buyers, sellers, verification, shipping, and payouts all in one giant function
- I architected a CQRS (Command Query Responsibility Segregation) pattern:
- Commands (PlaceOrder, VerifyItem, ShipOrder) triggered state changes
- Events (OrderPlaced, ItemVerified, OrderShipped) captured the state transitions
- Read Models (OrderSummary, SellerDashboard) provided optimized views for queries
- This allowed us to handle complex multi-state verification flows (like StockX's authentication process)
- Each command was idempotent, so we could safely retry failed operations
Phase 3: Lead Hiring and SCRUM Processes
- Managed the SCRUM ceremonies (standups, sprint planning, retros)
- Led the end-to-end hiring pipeline for engineers
- Interviewed and hired front-end, back-end, and mobile engineers
- Established code review standards and git workflows
The Tech Stack
- NestJS (TypeScript)
- GraphQL API
- CQRS + Event Sourcing
- PostgreSQL
- Parse.js (Legacy Migration)
- iOS/Android Coordination
The Results
- to Scalable Architecture
- 1 file
- Downtime During Migration
- 0
- in Transactions Handled
- Millions
- Faster Feature Development
- 5x
The migration was seamless. Zero downtime. Zero breaking changes for users.
The new architecture handled millions in transactions without breaking a sweat. Features that used to take weeks (because of the tangled Parse.js code) now took days.
The mobile teams were unblocked. They could now build features independently using the GraphQL API instead of waiting for backend changes.
Why It Worked
Migrating a production system while the business is running is like changing the engine of a plane mid-flight. Most teams get it wrong because they try to do it all at once.
Here's what I did differently:
- Run Both Systems in Parallel: Instead of a "big bang" migration, I ran Parse.js and NestJS side-by-side. The mobile apps gradually migrated endpoints one by one.
- GraphQL for Flexibility: GraphQL let the mobile teams fetch exactly the data they needed without waiting for custom endpoints.
- CQRS for Complex State: A StockX-like marketplace has complex order flows (buyer pays → seller ships → verification → payout). CQRS made each step explicit and debuggable.
- Event Sourcing for Auditability: Every state change was logged as an event. This made debugging easy ("What happened to Order #1234?") and enabled features like order history and dispute resolution.
Lessons Learned
Most startups use Parse.js, Firebase, or Supabase to ship fast. That's fine for an MVP.
But eventually, you'll outgrow it. The question is: Do you rebuild or refactor?
At BUMP, I chose refactor in parallel. This avoided the classic mistake of halting all feature development for 6 months to "rewrite the backend."
If you're hitting scaling issues and considering a backend migration, don't rewrite from scratch. Migrate incrementally. Run both systems in parallel. And use CQRS if your domain has complex state transitions.
Need to migrate a legacy backend? If you're stuck on Parse.js, Firebase, or a tangled monolith, book a call to discuss a migration strategy.