HomeAboutCase StudiesBlog
Services
Web DevelopmentMobile App DevelopmentAI ServicesAI Agents & ChatAI AutomationUI/UX DesignSEO & ContentDigital MarketingCloud SolutionsCybersecurityData AnalyticsAR / VRBlockchain & Web3IoT Solutions
View all 14 services →
Get a QuoteStart Project
Modernising a 15-Year-Old Monolith: A Complete Technical Case Study
Blog/Case Studies

Modernising a 15-Year-Old Monolith: A Complete Technical Case Study

TechGeneses Admin
April 20, 2026 13 min read 0 views

A £50M logistics company needed to modernise a 15-year-old PHP monolith that was blocking growth and creating significant operational risk. Here is how we delivered the transformation incrementally without disrupting operations.

The Legacy Problem: 15 Years of Technical Debt

Logistics Ltd (name changed) had built a competitive advantage in the early 2010s on a bespoke PHP logistics platform. In 2025, that platform was their biggest competitive liability. Written in PHP 5.6 with a MySQL database structured around 2009 business requirements, the system was: too slow to accommodate their current transaction volumes, too brittle to modify safely (deployments required 2-day weekend windows), too expensive to run (£140K per year in legacy infrastructure), and too difficult to integrate with modern carrier APIs.

Two development agencies had attempted rewrites. Both failed after 12+ months and significant investment. The company could not afford a third failed attempt.

Our Approach: Strangler Fig, Not Big Bang

The previous rewrite attempts failed for the same reason: they tried to rebuild everything before replacing anything. We applied the Strangler Fig pattern — the new system grows around the old one, gradually strangling it until the legacy core is gone.

This required building an API gateway in front of the legacy system that could route specific requests to either the legacy monolith or the new microservices, depending on what had been migrated. Traffic starts 100% on the legacy system and ends 100% on the new one, with a gradual incremental migration in between.

Phase 1: Foundations and the Routing Layer (Months 1–3)

Legacy System Documentation

We spent the first month doing something the previous agencies had skipped: fully documenting the legacy system. Every API endpoint, every database table, every business rule, every integration point. This documentation, painful to produce, became the specification for every new service we built.

We discovered 23 undocumented business rules embedded in the legacy code — rules that had been added over 15 years and never written down anywhere. Had we built the new system without finding these, we would have broken critical business logic that users had come to depend on.

The API Gateway

We deployed an nginx-based API gateway with custom routing logic. Initially, all requests passed through to the legacy system. As each new microservice completed testing, the gateway was updated to route those specific endpoints to the new service. The legacy system had no idea it was being gradually bypassed.

Phase 2: Service Extraction (Months 3–12)

Prioritisation Framework

We extracted services in order of: business value of improvement (how much better would the new version be?), integration risk (how many other components does this module touch?), and data complexity (how complex is the data model for this module?). High value, low risk, low complexity migrated first. The customer portal — high value (customers demanded a better UX), moderate risk, moderate complexity — was our first full service extraction.

Database Migration Strategy

The legacy MySQL schema was 347 tables, many of which violated first normal form and contained business logic in column naming conventions. We ran the old and new databases in parallel during migration, with a synchronisation layer that kept them consistent. Cutover for each service's data happened in a 15-minute window, not a weekend outage.

Phase 3: Final Cutover (Months 12–15)

The final modules to migrate — carrier integrations and the billing engine — were the most complex and most critical. We ran parallel processing for 4 weeks: every transaction processed by both systems, with automated comparison to detect any discrepancy. When discrepancy rate dropped below 0.01% for two consecutive weeks, we cut over.

Outcomes

15 months after project start: the legacy system was fully decommissioned. New infrastructure costs: £48K per year (66% reduction). Deployment frequency: from bi-monthly to daily. System uptime: from 99.1% to 99.97%. API response time improvement: 71% for core transaction endpoints. The development team can now ship features in days that previously took months — and the company's technology is no longer a constraint on their growth strategy.

Tags:legacy modernisationmonolith migrationstrangler fig patternPHP legacylegacy system migration
TechGeneses Admin
TechGeneses Editorial Team

Expert insights on AI, software engineering, and digital transformation from the TechGeneses team of engineers and strategists.

✦ Ready to Build?

Your Digital Future
Starts Here

Book a free 30-minute AI strategy session. We'll analyze your business and show exactly how intelligent technology can accelerate your growth — no commitment required.

No credit card required
Response within 24 hours
Free 30-min consultation