Strangling the Monolith
Decomposing a legacy PHP monolith into high-performance Node.js microservices.
"The Strangler Fig pattern allows for gradual migration of legacy systems, reducing the risk of a big-bang rewrite."
The Theory
In “Building Microservices”, Sam Newman warns against “The Big Bang Rewrite”—pausing development to rewrite an entire system from scratch. Instead, he advocates for the Strangler Fig Pattern: gradually replacing specific functionality with new microservices while the legacy system continues to operate, intercepted by a proxy or routing layer.
The architecture shown above demonstrates this approach: an Nginx proxy routes authentication requests to the new Node.js service while other traffic continues to the PHP monolith.
The Problem (Before)
The speech therapy medical system project GoTech worked with was a profitable but aging system written in legacy PHP. The code had complex interdependencies, making new feature development challenging and time-consuming.
The Failure Modes:
- Adding a simple feature (e.g., “SMS Reminders”) required regression testing the entire monolithic codebase.
- The “User Session” logic was embedded everywhere, preventing independent scaling of components.
- The database was a single point of contention for all operations.
The Solution (After)
I identified the User Accounts & Authentication module as the highest value target—it was high traffic but had well-defined boundaries. We built a new Node.js (NestJS) service to handle this domain.
- The Proxy Layer: Nginx Reverse Proxy placed in front of the legacy PHP application.
- The Route Switch: Nginx routes
/api/v2/auth/*traffic to the new Node.js service; all other traffic falls back to PHP. - The Data Sync: Dual-write strategy keeps legacy and new databases in sync until PHP retirement.
Impact Metrics
| Metric | Before | After |
|---|---|---|
| Architecture | PHP Monolith | Node.js Microservices |
| Deployment Risk | Full system | Incremental |
| Rollback | Manual | Configuration toggle |
When To Use This Pattern
Use the Strangler Pattern when:
- You have a legacy system that still generates business value
- A “big bang” rewrite would freeze feature development for months
- You can identify modules with clear boundaries (auth, payments, notifications)
- The team needs to build confidence with incremental wins
Avoid this pattern when:
- The legacy system is so coupled that no boundaries exist
- You’re under regulatory pressure to replace everything immediately
- The legacy codebase is small enough for a quick rewrite (< 3 months)
The Outcome
- Risk Mitigation: If the new Node.js service had bugs, we could revert the Nginx config in seconds.
- Performance: Login times dropped by 40% due to Node.js’s non-blocking I/O and Redis caching.
- Velocity: The team iterated on Authentication logic (adding 2FA) without modifying the existing PHP codebase.