Skip to main content
Back to Insights
Engineering
•14 min read

Migrating from Monolith to Microservices: A Strangler Fig Case Study

How we helped a fintech company decompose a 15-year-old monolith into 40+ services with zero downtime. Patterns, pitfalls, and the migration playbook.

Marcus Rodriguez
VP Engineering

The Monster in the Basement

Apex Insurance's policy administration system: 2.3M lines of Java, 15 years old, 40 developers afraid to touch it. Deployments took 6 hours. One schema change broke 200 tests.

They didn't need microservices. They needed deployability.

The Strangler Fig Pattern

Don't rewrite. Strangle.

[Legacy Monolith] ←→ [Facade/Proxy] → [New Services]
                            ↓
                      [Traffic Router]
                            ↓
                    [Canary Releases]
  1. Identify a bounded context
  2. Build new service alongside
  3. Proxy traffic to new service
  4. Validate, then cut over
  5. Delete legacy code
  6. Repeat

Phase 1: The Facade

We built an API gateway (Kong) in front of the monolith. Every request passes through. This gave us:

  • Request/response logging
  • Rate limiting
  • Authentication termination
  • Traffic routing rules

Phase 2: Domain Extraction Order

We mapped the domain using Domain-Driven Design. Extraction order:

  1. Notifications (low risk, high value) - Email, SMS, push
  2. Document Generation - PDF policies, quotes, letters
  3. Payment Processing - Already partially externalized
  4. User Management - Auth, profiles, permissions
  5. Quoting Engine - Core business logic, high complexity
  6. Policy Administration - The crown jewel, highest risk

Each extraction: 6-10 weeks. Parallel tracks after phase 1.

Phase 3: Data Synchronization

The hardest part. Shared database = distributed monolith.

Strategies we used:

  • Dual Write: Write to both old and new. Reconciliation job nightly.
  • Change Data Capture: Debezium streams MySQL binlog → Kafka → new service DB.
  • API Facade: New service owns data. Legacy calls new service API.
  • Materialized Views: For reporting, build read models from events.

Phase 4: Traffic Migration

Canary releases with feature flags:

# LaunchDarkly flag
newQuotingEngine:
  variations:
    - legacy: 90%
    - new: 10%
  targeting:
    - internal-users: 100% new
    - beta-customers: 50% new
    - all: gradual rollout over 4 weeks

Metrics gates: error rate, latency, business metrics (quote accuracy, conversion).

Phase 5: Decommission

Legacy code deletion is satisfying but dangerous.

Checklist before delete:

  • [ ] Zero traffic for 30 days
  • [ ] All tests pass without legacy stubs
  • [ ] Documentation updated
  • [ ] Team trained on new service
  • [ ] Rollback plan tested (it's just a flag flip)

Results After 18 Months

  • 42 services extracted
  • Deployment frequency: monthly → 50/day
  • Lead time: 6 hours → 15 minutes
  • Change failure rate: 15% → 0.5%
  • MTTR: 4 hours → 12 minutes
  • Developer satisfaction: 3.2/10 → 8.7/10

The Playbook

  1. Start with observability - You can't migrate what you can't measure
  2. Extract low-risk, high-value first - Build confidence and tooling
  3. Invest in platform - CI/CD, service mesh, observability, deploy tooling
  4. Data is the blocker - Plan synchronization before extraction
  5. Culture eats architecture - Teams must own services end-to-end

Facing a monolith migration? We've done this before.

MicroservicesStrangler FigMigrationDomain-Driven DesignLegacy Modernization
Marcus Rodriguez
VP Engineering
Marcus oversees engineering delivery and technical strategy. 15+ years building products at Google, Airbnb, and high-growth startups.

Want more insights like this?

Subscribe to our newsletter for weekly deep dives on digital product development, cloud engineering, and technology strategy.