Skip to content
Back to case studies
NDA-safeMigration2022

Event-Driven Commerce Migration

Peak-hour monolith failures + inflated EC2 → 5M+ orders/mo, P99 <200ms, ~30% infra reduction.

Role
Senior Software Engineer
Context
Retail / E-Commerce
Duration
8 months
Team
4 engineers + 1 architect (me)

Why they called

A PHP monolith on EC2 was failing under promotion traffic. Peak capacity was around 500 requests a second with P99 latency near 2.8 seconds, failures cascaded under load, deploys were weekly and manual, and the instances had been oversized to compensate. Every promotion was a gamble on whether checkout would stay up.

Tech stack

  • Node.js
  • Go
  • Kafka
  • ECS/EKS
  • Kubernetes
  • Redis
  • MySQL
  • Terraform
  • GitHub Actions
Executive summary

Business problem and production context.

Business problem

Legacy PHP monolith on EC2 couldn't handle peak-hour traffic spikes during promotions. Deployments were risky, costs were inflated from overprovisioned instances, and the system suffered from cascading failures under load.

Architecture decision

Led migration using the Strangler Fig pattern, incrementally routing traffic from the monolith to event-driven microservices built with Node.js, Go, and Kafka on ECS/EKS. Implemented blue-green deployments and auto-scaling on Kubernetes for zero-downtime releases.

Result

Before and after.

P99 Latency
Before2.8s
After<200ms
Monthly Infra Cost
Beforebaseline
After~30% lower
Deploy Frequency
Before1x/week (manual)
After4x/day (automated)
Peak Capacity
Before~500 req/s
After5,000+ req/s
Architecture

Order traffic moved off a PHP monolith one endpoint at a time, with orders flowing through Kafka events.

The routing, order services, event bus and release path. Networking, the data stores and the monolith's internals are not shown.

Simplified view

Main components only; supporting services are left out.

  1. Routing

    • API Gateway

      Routes each endpoint, old or new

    • Load balancer

      Blue and green target groups

  2. Services

    • PHP monolith on EC2

      Serves endpoints not yet migrated

    • ECS

      Runs Node.js and Go order services

    • EKS

      Kubernetes auto-scaling on queue depth

  3. Events

    • Kafka

      Order lifecycle event bus

    • CloudWatch

      Alarms on consumer group lag

  4. Release and operations

    • GitHub Actions

      Automated deploy pipeline

    • Terraform

      Defines services and target groups

    • CodeDeploy

      Switches traffic blue to green

How it works, step by step

  1. 1The API Gateway sends each migrated endpoint to the new services and leaves every other endpoint on the PHP monolith.
  2. 2Node.js and Go services handle the request and publish order lifecycle events (placed, confirmed, dispatched, delivered) to Kafka instead of calling each other directly.
  3. 3Downstream services consume those events, and Kubernetes scales them on order queue depth during promotions.
  4. 4CloudWatch alarms on Kafka consumer group lag flag delayed order confirmations.
  5. 5Each release goes out blue-green through CodeDeploy, so a bad release rolls back by switching traffic to the previous target group.

Guardrails

  • Strangler fig routing, endpoint by endpoint, starting with order search before checkout
  • Old and new systems ran in parallel, comparing response times and error rates before cutover
  • Blue-green deployments for fast rollback
  • Auto-scaling tied to order queue depth
  • CloudWatch alarms on Kafka consumer group lag

Considered and not used

  • Lambda as the main compute: Containers chosen for long-running order processing workflows and predictable latency.
  • SQS: Kafka chosen for high-throughput event streaming with replay.
  • Canary deployments: Blue-green chosen for simpler rollback during critical commerce operations.
What Rahul owned

My part of the work, separate from the team's.

The team behind the engagement is in the facts row above. These are the parts I was responsible for, and the artifacts that show the work.

Owned scope

  • Migration path from fragile monolith endpoints toward independently deployable order services
  • Traffic, latency, rollback, and event-flow decisions for peak commerce load
  • Operational shape for blue-green releases and queue/consumer monitoring

Evidence artifacts

5M+ monthly orders supportedP99 latency improvementStrangler migrationBlue-green release pathQueue-lag monitoring
Constraints

What would fail first?

Every project has constraints. The useful work is naming them early enough that rollback, cost, and ownership are designed before an incident.

Peak traffic

Promotion traffic created sharp spikes where synchronous paths and overprovisioned compute both hurt.

Revenue path

Checkout and order flows had to migrate without creating customer-visible downtime.

Mixed stack

The migration needed to coexist with a legacy PHP monolith during staged cutover.

Decision table

Trade-offs accepted on purpose.

ECS/EKS vs pure Lambda
Chose containers for long-running order processing workflows and predictable latency.
Kafka vs SQS
Kafka selected for high-throughput event streaming with replay capability across 5M+ monthly orders.
Blue-green vs canary
Blue-green chosen for simpler rollback during critical commerce operations.
Risk table

Production risks and how they were controlled.

Cascading order failures
Separated order lifecycle events and monitored consumer lag before expanding traffic.
Order platform owner
Bad release during checkout traffic
Used phased routing and blue-green rollback instead of big-bang replacement.
Release owner
Overprovisioned infrastructure stayed hidden
Mapped traffic hotspots and autoscaling behavior before committing to the new shape.
Platform + finance
Implementation approach

Small steps, visible changes, fewer surprises.

  1. 01

    Audited the PHP monolith and mapped all 47 API endpoints, identifying 12 high-traffic hotspots causing 80% of the latency issues.

  2. 02

    Implemented Strangler Fig pattern, routing traffic endpoint-by-endpoint from monolith to new Node.js/Go microservices behind an API Gateway.

  3. 03

    Built Kafka-based event bus for order lifecycle events (placed → confirmed → dispatched → delivered), decoupling services from synchronous calls.

  4. 04

    Deployed on ECS/EKS with Kubernetes auto-scaling tied to order queue depth, handling 3x traffic spikes during promotions without manual intervention.

  5. 05

    Ran both systems in parallel for 6 weeks, comparing response times and error rates before fully cutting over.

Takeaway

What carries over to your system.

  • Started by migrating the order search API first: low risk, high visibility. This built team confidence before touching the critical checkout flow.
  • Kafka consumer lag monitoring was essential. Without it, we missed a 2-hour delay in order confirmations during the first week. Added CloudWatch alarms on consumer group lag.
  • Blue-green deployments saved us twice during the migration. One bad Go service release was rolled back in under 30 seconds with zero customer impact.

Rollback path

The strangler path kept old and new services running in parallel so endpoint rollback stayed possible during migration.

Cost considerations

Cost reduction came from removing overprovisioned instances and scaling around real order traffic rather than peak fear.

Observability notes

P99 latency, order error rate, queue/consumer lag, deploy health, and checkout-path alarms mattered more than generic dashboard count.

Services built on this work

Have a similar production problem?

Send the current architecture, bill concern, deployment pain, or GenAI reliability issue. I will help you find the first real bottleneck.

Scroll or pinch to zoom, drag to move100%