Work · Case study
Two years of migration and not one maintenance window.
01 / Challenge
A large Node.js monolith had become tightly coupled across business domains, with direct database access spread through the codebase. Releases were slow and risky, regressions were hard to isolate, and scaling one busy domain meant scaling everything. A full rewrite was the obvious answer and the wrong one: the platform serves live traffic and could not stop.
02 / Approach
The migration ran endpoint by endpoint on a gateway pattern rather than domain by domain on a rewrite. An API is implemented in a NestJS microservice; a gateway module generates a reusable internal package; the monolith consumes that package; and the direct database call it used to make is replaced by a gateway call. Only then does Nginx routing shift that endpoint across.
That ordering matters. At every point the monolith still works, the new service is proven against real traffic before it owns any, and a step that goes wrong is one endpoint to reverse rather than a release to roll back.
Datadog carried the decision to advance. Traffic, latency and error rates were watched across each shift, and no phase expanded until the previous one held. The shared relational database stayed in place throughout, because moving the data and the code at the same time is how these migrations become the rewrite everyone was avoiding.
03 / Outcome
years without a rewrite
maintenance windows taken
Backend domains are separated, coupling inside the monolith is materially reduced, and individual services can now be scaled horizontally on their own. Deployment risk dropped because service isolation limits what a bad release can reach, and service-level observability made debugging a matter of reading one service rather than searching a monolith. The client's own summary of the approach was that it was non-disruptive and cost-efficient, with no full rewrite required.