system-design · intermediate

Splitting a Monolith Safely (Strangler Fig)

Start here

Splitting a Monolith Safely (Strangler Fig) is a practical idea you will meet while building and operating real systems.

In plain English: it helps teams shape how internet-facing backend handles user requests and persistent records so the product stays correct, fast enough, and operable when something breaks.

Think of it like a growing shop that adds counters, storerooms, and delivery routes carefully. The analogy will guide intuition; later sections mark where software diverges.

You should care because skipping this topic usually means paying tuition during incidents—outages, silent data issues, or designs that cannot evolve. This lesson assumes you are capable but new to the details. Important terms are defined before they are reused as shorthand.

What you will learn

  1. Explain Splitting a Monolith Safely (Strangler Fig) in plain English without unexplained jargon.
  2. Describe the problem that appears when teams ignore it.
  3. Walk through how it works step by step with a concrete system.
  4. Apply a complete worked example using internet-facing backend.
  5. Recognize common failure modes and how to detect them.
  6. Weigh trade-offs so you can choose deliberately, not by fashion.
  7. Practice with questions you can answer in writing or at a whiteboard.

What you should know first

IdeaWhy it helps
Core HTTP request/responseMost examples assume networked services
Failure is normalProduction is partial failure

You can continue even if some rows are fuzzy—the lesson re-explains what it needs in context.

Words you need before we begin

TermPlain English
Splitting a Monolith Safely (Strangler Fig)The main subject of this lesson—the idea you will apply end to end.
InvariantA rule that must remain true even when parts fail or retry.
LatencyHow long one operation takes from start to useful result.
ThroughputHow much work completes per unit time.
IdempotencyDoing the same logical action more than once does not multiply side effects.
TimeoutA deadline after which you stop waiting and take a fallback path.
RetryAttempting an operation again after a failure (must be bounded).
ObservabilityAbility to understand system behavior from logs, metrics, and traces.
Blast radiusHow widely a failure or bad change spreads.
Trade-offA gain that costs something elsewhere (simplicity, cost, consistency, etc.).
RollbackReturning to a previous known-good state when a change misbehaves.
SLOService Level Objective—a target for user-visible reliability or latency.

Simple story

Imagine a growing shop that adds counters, storerooms, and delivery routes carefully.

In that world, people invent informal rules so work keeps moving when someone is late, a tool breaks, or two people grab the same task. Splitting a Monolith Safely (Strangler Fig) is the engineered version of those rules for software: explicit, testable, and visible in metrics.

Where the analogy stops: software adds concurrency, multi-tenant blast radius, automated retries, partial network failure, and adversarial traffic. Always re-check the analogy against a real request or data path before copying it into production design.

The problem without this concept

Without a clear approach to Splitting a Monolith Safely (Strangler Fig), teams often:

  1. Discover edge cases only in production under peak load.
  2. Argue from anecdotes instead of shared definitions and metrics.
  3. Patch symptoms (more retries, bigger machines) that increase hot keys, cascading timeouts, or unbounded queues.
  4. Couple components so tightly that a single dependency outage becomes a user-facing outage.
Skipping the foundation is cheaper on day one and more expensive on day one hundred. Learning **Splitting a Monolith Safely (Strangler Fig)** in calm time is cheaper than learning it during a Sev-1.

Step-by-step explanation

Step 1 — Name the user-visible success

Write what “good” means for a journey that depends on Splitting a Monolith Safely (Strangler Fig). Example for internet-facing backend: the user receives a correct outcome for user requests and persistent records within an agreed latency budget, or a clear error they can act on—not a spinner forever.

Step 2 — Identify the moving parts

List the components that participate: clients, APIs, data stores, workers, caches, and third parties. Mark which are on the critical path versus optional enrichment.

Step 3 — Define invariants and failure language

State invariants involving Splitting a Monolith Safely (Strangler Fig). Example: “we never apply the same logical effect twice,” or “we never serve unauthorized data,” or “we degrade optional features before failing money paths.” Choose language your on-call can use in a war room.

Step 4 — Design the happy path

Walk one request or job from start to durable result. Name the storage writes, the network hops, and the acknowledgements. Keep the path short enough to explain on a whiteboard.

Step 5 — Design the unhappy path on purpose

For each dependency, pick timeout, retry policy (only if safe), fallback, and whether to fail open or fail closed. Unbounded retries without jitter are how retry storms start.

Step 6 — Make effects safe under at-least-once realities

Networks and workers duplicate messages. Prefer idempotency keys, unique constraints, and explicit state machines for user requests and persistent records. Assume redelivery.

Step 7 — Instrument before wide rollout

Add metrics and logs that show latency percentiles, error budgets, and capacity plans. If you cannot see hot keys, cascading timeouts, or unbounded queues, you cannot operate Splitting a Monolith Safely (Strangler Fig).

Step 8 — Roll out with limited blast radius

Feature flags, canaries, or shadow traffic. Document rollback. Prefer progressive exposure over big-bang cutovers for risky changes related to Splitting a Monolith Safely (Strangler Fig).

Visual mental model

flowchart TB
  U[User or upstream client] --> E[Edge / API]
  E --> C[Core logic for Splitting a Monolith Safely (Strangler Fig)]
  C --> S[(Durable state)]
  C --> X[Dependencies]
  C --> O[Observability signals]
  X -->|timeouts / retries / isolation| C
  O --> H[Humans on-call]

Learning question: Which box is most often missing from slideware about Splitting a Monolith Safely (Strangler Fig)—and what breaks when it is missing?

Caption: Benefits attract adoption; failure handling and observability keep systems honest.

Complete worked example: internet-facing backend

Starting situation

A team runs internet-facing backend. Peak traffic is rising. They need Splitting a Monolith Safely (Strangler Fig) to keep user requests and persistent records correct while staying within latency and error budgets.

Constraints

Decisions

  1. Define user-visible success metrics tied to Splitting a Monolith Safely (Strangler Fig).
  2. Keep critical-path dependencies bounded with timeouts and isolation.
  3. Push non-critical work off the request path when possible.
  4. Persist enough state to make retries idempotent for user requests and persistent records.
  5. Add alerts on symptoms users feel—not only on CPU.
  6. Ship behind a flag with a documented rollback.

Execution

  1. Implement the happy path with clear module boundaries.
  2. Add tests for unhappy paths: timeouts, duplicates, permission failures.
  3. Load-test a realistic mix, including dependency slowdowns.
  4. Enable for a small cohort; watch latency percentiles, error budgets, and capacity plans.
  5. Expand gradually; freeze expansion if error budgets burn too fast.

Failure behavior samples

FailureUser impactSystem response
Dependency slowHigher latencyTimeout; degrade optional work; protect core
Dependency downFeature limited or fail closedFallback or clear error; alert
Duplicate request/messageNone if idempotentUnique keys / dedupe store
Bad deployElevated errorsRollback; reduce blast radius
Data growth surpriseSlower reads/writesCache, index, or partition plan

Outcome

The team can explain Splitting a Monolith Safely (Strangler Fig) with numbers: latency, error rate, and a specific health signal. Limitations remain—compliance, multi-region, or provider quirks may force adaptations—but the questions stay stable.

What we explicitly did not do

We did not pretend a single pattern removes all trade-offs. We also did not add unbounded queues or infinite retries as a substitute for capacity and good boundaries.

How it works in production

Ownership

Name a team for configuration, dashboards, and incidents touching Splitting a Monolith Safely (Strangler Fig). Unowned subsystems become unpageable mysteries.

Operational checklist

Signals that matter

Deployment concerns

Prefer small releases. Configuration for timeouts and limits is as dangerous as code—review it like code. Keep feature flags for risky paths related to Splitting a Monolith Safely (Strangler Fig).

Failure modes

ModeTriggerUser impactDetectionMitigationPrevention
Missing success definitionNo SLI/SLOEndless thrashArgument-driven opsDefine user journeysReviews
No timeoutsHung dependenciesCascading stallsThread/pool metricsBound remote callsStandards
Unbounded retriesTransient errorsRetry stormsDependency error spikesBackoff + jitter + capsShared libraries
Non-idempotent effectsAt-least-once deliveryDouble side effectsCustomer reports; unique violationsDedupe keysDesign reviews
Silent degradationPartial failureSlow wrong answersSynthetic checksExplicit alertsSLOs
Hot key / skewUneven loadLatency islandsPer-partition metricsSplit keys; cacheLoad tests
Config mistakeBad flag/timeoutWide outageDeploy correlationRollbackProgressive delivery
Ownership gap“Everyone’s job”Long MTTRRepeated incidentsAssign ownersTeam topology

For each mode, practice saying: trigger → user experience → system view → detect → mitigate → prevent.

Trade-offs

ChoiceBenefitCost
Simpler designFaster delivery; easier reasoningMay need redesign under extreme scale
More moving partsIsolation and flexibilityOps burden; harder debugging
Strong consistency where requiredCorrectness for user requests and persistent recordsLatency and availability trade-offs
Eventual consistency for non-critical viewsScale and availabilityStale reads; careful UX
Sync dependency callsImmediate answersCoupling and cascade risk
Async handoffIsolation and smoothingLag; idempotency requirements
Fail closed on uncertaintySafer for sensitive actionsMore user-visible errors
Fail open on optional featuresBetter UX under partial failurePossible missing enrichment

There is no free lunch. Good engineering makes the trade-offs explicit and revisits them when load or product goals change.

Compare with related concepts

Related ideaHow it differs from Splitting a Monolith Safely (Strangler Fig)
Generic “best practices” listsThis lesson is operational and example-driven, not slogans
Only adding hardwareCapacity helps, but wrong boundaries still fail
Only adding retriesRetries without policy can worsen outages
Only drawing microservicesSplit services without Splitting a Monolith Safely (Strangler Fig) still share fate poorly

Related lessons to read next:

  1. microservices-architecture
  2. change-data-capture-vs-dual-writes
  3. zero-downtime-schema-migration
  4. distributed-transactions-saga

Common misunderstandings

  1. “If it works on my laptop, production will be fine.”
Production adds concurrency, multi-tenant load, and partial failure.
  1. “More retries fix reliability.”
Unbounded retries create storms. Bound them; prefer idempotency.
  1. “Async means we can ignore failures.”
Async moves failure in time. You still need DLQs, lag SLOs, and owners.
  1. “A cache removes the need for correct data modeling.”
Caches miss; correctness still lives in source-of-truth systems.
  1. “Exactly-once is a checkbox.”
End-to-end exactly-once effects usually mean at-least-once plus idempotent handling.
  1. “Microservices automatically isolate failure.”
Without timeouts, bulkheads, and clear contracts, they amplify failure.
  1. “Observability is optional polish.”
You cannot operate **Splitting a Monolith Safely (Strangler Fig)** blind.

Check your understanding

  1. Define Splitting a Monolith Safely (Strangler Fig) in one or two sentences without jargon.
  2. What problem appears when teams skip it?
  3. Name two invariants you would protect in internet-facing backend.
  4. Give one sync and one async choice that might appear near this topic.
  5. What metric would tell you users are hurting?
  6. Describe a failure mode and its first mitigation.
  7. What trade-off would you explicitly tell a product manager about?

Practice

  1. Draw the happy path for internet-facing backend involving Splitting a Monolith Safely (Strangler Fig). Mark the critical path in bold.
  2. Write timeout and retry rules for one dependency that affects user requests and persistent records.
  3. Design an idempotency approach for a duplicated request or message.
  4. List three dashboard panels and one page-worthy alert.
  5. Write a rollback plan for a bad config related to this topic.
  6. Explain the simple story to a new hire, then state where it breaks.
  7. Given a 10× traffic spike, which failure mode from the table hits first—and why?
  8. Draft a short design-review checklist item that would have caught a past bug on your team.

Deeper production notes

Capacity napkin math

Estimate peak operations/second related to Splitting a Monolith Safely (Strangler Fig), multiply by cost per operation (CPU, IO, external API), and ask whether the design still works when a dependency runs at half capacity. If the answer depends on luck, add bounds, caching, shedding, or backlog limits before the marketing campaign.

Mixed-version deploys

During rollouts, old and new binaries coexist. Ensure protocols, message fields, and transaction assumptions tolerate one deploy window of mixed versions. Breaking changes need dual-write/dual-read plans or gated flags.

Ownership and support

If you cannot name who gets paged, who can change config, and who maintains dashboards, the mechanism is not production-ready—regardless of how elegant the code looks.

Security and privacy touchpoints

Wherever user requests and persistent records includes personal or financial data, apply least privilege, audit access, and careful logging (avoid secrets in plain logs). Security is not a separate optional chapter for real systems.

Testing strategy

Unit tests catch logic bugs; contract tests catch integration skew; load tests catch saturation; game days catch operational blind spots. Untested unhappy paths become production curricula.

Revision summary

Glossary

TermDefinition
Splitting a Monolith Safely (Strangler Fig)Core subject of this lesson as applied in production systems.
Critical pathSteps that must succeed for the user-visible outcome.
IdempotencySafe re-execution semantics for the same logical intent.
Blast radiusScope of impact for a failure or bad change.
Error budgetAllowed unreliability derived from an SLO (when used).
RunbookDocumented steps for detection and mitigation.

Abbreviations and terminology

Expand acronyms on first use in conversation with beginners; this lesson introduced them beside plain-English meanings.

What to learn next

  1. microservices-architecture
  2. change-data-capture-vs-dual-writes
  3. zero-downtime-schema-migration
  4. distributed-transactions-saga
Also revisit foundational primers—latency vs throughput, fault tolerance, and idempotency—whenever this topic starts to feel like a pile of tools without a spine.

FAQ from first-time learners

Q: Is Splitting a Monolith Safely (Strangler Fig) only for big companies?
A: No. Small systems still retry, fail, and grow. Lightweight versions of these ideas prevent painful rewrites.

Q: How do I know we are done designing?
A: You can explain happy path, top failures, metrics, owners, and trade-offs without hand-waving—and tests cover at least one unhappy path.

Q: What if our constraints differ from the worked example?
A: Keep the questions; change the mechanisms. The example is a template for judgment, not a mandatory architecture.

Q: Should we copy a famous company’s diagram?
A: Copy questions and principles, not cargo-cult boxes. Their scale, staffing, and history are not yours.

Q: How does this show up in interviews?
A: Interviewers listen for requirements, estimates, request paths, bottlenecks, and failure talk. Use the structure here as a spine.

Final field checklist

Before you claim Splitting a Monolith Safely (Strangler Fig) is production-ready for internet-facing backend:

  1. User success is defined and measurable.
  2. Critical vs non-critical dependencies are labeled.
  3. Timeouts and retry policies are explicit and safe.
  4. Duplicate application of effects is handled.
  5. Dashboards and alerts exist and are owned.
  6. Rollback / degrade paths are documented.
  7. Load or failure testing touched the unhappy path.
  8. Trade-offs are written where future readers will find them.
If any box is unchecked, you still have design work—not just implementation work.

Track: Software Design and Architecture

Previous: Service Discovery — Finding Instances That Change

Next: Stateful vs. Stateless Architecture — Managing Session State

By Shubham Jain

All articles · Study paths

Shubham Jain · Learning Lab