Case study · Named with permission
KFC Thailand: PHP monolith to event-driven ordering
The problem
A PHP monolith on EC2 was failing under promotion traffic. Peak capacity was around 500 requests a second, P99 latency was near 2.8 seconds, failures cascaded under load, deploys were weekly and manual, and instances had been oversized to compensate.
Constraints
Orders could not stop during the migration, checkout was the most critical path, and promotions drove 3x traffic spikes.
The decision
Migrate incrementally with the Strangler Fig pattern: route traffic endpoint by endpoint from the monolith to Node.js and Go services, decouple the order lifecycle with Kafka events, run on ECS/EKS with autoscaling tied to order-queue depth, and release with blue-green deployments.
What was decided first
The first service migrated was order search, not checkout. It was low risk and highly visible, so the team built confidence on a path where a mistake would not stop orders.
Before any code moved, all 47 API endpoints in the monolith were mapped. Twelve high-traffic endpoints caused about 80% of the latency problems, and those set the migration order.
Options considered
- Containers (ECS/EKS) or pure Lambda. Containers were chosen for long-running order-processing workflows and predictable latency.
- Kafka or SQS. Kafka was chosen for high-throughput event streaming with replay across millions of monthly orders.
- Blue-green or canary releases. Blue-green was chosen because rollback had to be simple during live commerce operations.
How the change was made safe
The order lifecycle (placed, confirmed, dispatched, delivered) became Kafka events, so services stopped depending on synchronous calls to each other. Autoscaling followed order-queue depth, which absorbed 3x promotion spikes without manual intervention.
The old and new systems ran in parallel for six weeks, with response times and error rates compared before the full cut-over.
Blue-green deployment paid for itself twice during the migration. One bad Go release was rolled back in under 30 seconds with no customer impact.
What went wrong
In the first week, order confirmations were delayed by two hours and nobody saw it, because Kafka consumer lag was not monitored. CloudWatch alarms on consumer-group lag were added after that.
Results
| Measure | Before | After | When |
|---|---|---|---|
| P99 latency | 2.8 s | under 200 ms | After the 8-month migration |
| Peak capacity | about 500 req/s | more than 5,000 req/s | After the 8-month migration |
| Releases | weekly, manual | 4 a day, automated | After the 8-month migration |
| Monthly infrastructure cost | baseline | about 30% lower | After the 8-month migration |
Figures are as reported by Rahul and recorded in the InfraTales proof register. Measured on the client's systems; not a promise of the same result elsewhere.
When this approach would not fit
This was a high-throughput system with long-running workflows, so containers and Kafka earned their operational cost. A smaller system with bursty, short-lived work and no need for event replay would usually be simpler and cheaper on Lambda and SQS. Kubernetes and Kafka are worth their operating load only when the workload clearly needs them.
Verified record
- Engagement
- At Imaginato, Rahul led the migration of KFC Thailand's PHP ordering monolith to event-driven Node.js, Go and Kafka services on ECS/EKS, over 8 months with a team of four engineers.
- Results
- After the migration, P99 latency fell from 2.8 seconds to under 200 ms, peak capacity rose from about 500 to more than 5,000 requests per second, releases went from weekly manual deploys to four automated deploys a day, and monthly infrastructure cost fell by about 30%.
- Production work
- Worked on an event-driven ordering platform for a major international QSR brand, processing more than 5 million orders per month with 99.99% uptime.