CodeOath
← All posts
Architecture & Patterns68 min total · 17 parts

Microservices vs. Monolith: The Trade You're Actually Making

Part 15 of 17 · ~2 min

Migrating Incrementally: The Strangler Fig Pattern

Rewriting Furrow from scratch as four services in one push was on the table for about a week before someone pointed out what it would actually mean: months with nothing shippable, while the one working system got no new features and no bug fixes, in service of a rewrite that might not even come out ahead of what it replaced. The strangler fig pattern — named for the vine that grows up and around a host tree, gradually taking over until nothing of the original is left standing — is the alternative: extract one piece at a time, route just that piece's traffic to the new service, and leave everything else running in the monolith, completely unchanged, until it's its own turn.

1. Monolith handles everything: Subscriptions, Harvest, Billing, Delivery
2. Extract Billing first — its proration logic had gotten gnarly enough
   that it was the thing actually forcing the split conversation
3. A routing layer sends billing-related requests to the new service;
   everything else still hits the monolith exactly as before
4. Monolith now handles Subscriptions, Harvest, Delivery; Billing is
   fully independent and deploying on its own schedule
5. Repeat for Harvest, months later, once the Wednesday-night database
   pileup made a second extraction genuinely worth doing

Furrow extracted Billing first, not Harvest, even though Harvest's Wednesday-night contention was the more dramatic problem — because Billing's proration bugs were the thing actually costing shipped features every single week, while Harvest's contention was, at that point, an occasional bad Wednesday rather than a constant tax. That ordering choice is the actual value of doing this incrementally: it forces you to justify which piece goes first with a real, current, specific reason, instead of assuming every module eventually has to become its own service on some predetermined schedule. The system stayed fully working and shippable at every single step along the way — there was never a moment where nothing worked because the migration was half-finished.