Case study
Migrating a monolith to microservices
Gradually extracting microservices from a monolith without downtime: domain boundaries, events and orchestration in Kubernetes.
- Year
- 2026
- Client
- Mature SaaS product
- Role
- Tech Lead
Description
A mature Laravel monolith stopped meeting the business requirements: releases became risky, teams got in each other way, and individual high-load modules could not be scaled independently. I led a phased migration to microservices using the strangler fig strategy, without stopping the product. We started by drawing boundaries by domains based on DDD, then sequentially extracted services, moving inter-module interaction to asynchronous events through a message broker and a transactional outbox for reliable publishing. The most latency-critical services are implemented in Go, while the product ones remained in Laravel. All services are containerized and deployed in Kubernetes with independent CI/CD pipelines, autoscaling and full observability: structured logs with correlation IDs, Prometheus metrics and distributed tracing. The monolith meanwhile kept working, gradually slimming down as functionality was extracted.
Task
The monolith became a bottleneck: any release affected the whole system and carried risk, teams conflicted in shared code and the database, and high-load modules could not be scaled separately from the rest.
Solution
I applied the strangler fig strategy: defined domain boundaries, extracted services in phases with asynchronous event exchange and an outbox, rewrote the high-load parts in Go, and deployed everything in Kubernetes with separate pipelines and end-to-end observability.
Results
Release frequency increased 4 times, incident recovery time dropped threefold, high-load services scale independently, the migration went without product downtime, and the time to ship new features dropped by 40%.