Skip to content

Strangler fig migration

Route at the front, move one slice at a time, prove each slice by shadow comparison, then delete what the old path no longer serves.

Predict first

Before you read: predict

ExamHall's legacy results app serves three pages behind its CDN: /results/:id, /results/:id/pdf and /history. Candidates open them from bookmarks and emailed links. The team has rebuilt /history in Next.js.

Which change gets candidates the new /history while the other two pages keep working?

Pick one

The 30-second version

Don't replace a live system in one switch. Put a routing layer in front, rebuild one slice and route it to the new code. Before switching, shadow it: answer from the old code, copy to the new, count differences. Switch when a pre-agreed criterion holds, then delete the old path.

Route at the front, move one slice at a time, prove each slice by shadow comparison, then delete what the old path no longer serves.

How it works

Step 1 of 12

Big bang chases a moving target. Rebuilding everything before switching ships nothing until the end, while the live system keeps changing.

Analogy: A car assembly plant moving its welding to robots

The line keeps building cars while the weld stations change over one at a time.

In the assembly plant In the system
the line controller sends each body to the manual station or the robot cell, station by station; build sheets stay as they were the routing layer per path; addresses unchanged (steps 2, 3)
the door-seam station changes over this month, the roof next one slice at a time (step 4)
for a while the robot welds a scrap test panel for each body the manual station welds; only the manual weld goes on the car, and the two are compared shadow comparison (step 6)
the date the station changes over is set before the first test panel is welded the clean window fixed before the shadow starts (step 9)
the old station is dismantled only when its own counter shows no body for weeks delete when the old app's log is empty (step 11)

Breaks down when: a test panel costs steel and a robot's time; a copied request costs the new app only load.

Contrasting case: shutting the plant for the summer to fit every robot at once is the big bang: one switch, no comparison, no way to move one station back.

In real terms: the router decides who answers each path, and the old code goes only when the evidence says nothing needs it.

Examples, run for real

4.1 ExamHall EXH-3970: the host switch that broke two pages

ExamHall's team rebuilt the results page in Next.js and, for a trial hour, pointed the whole results host at it.

4.1 before: the whole results host pointed at Next.js for one hour · 1,000 requests: 600 result pages answered, 240 PDF and 160 history requests got 404 (400 failed)
4.1 MR !4270: a CDN rule per rebuilt path, shadowed first · shadow week 1: 2,000 result pages compared, 12 differ (scores ending in .5 rounded) · after the fix, week 2: 2,000 compared, 0 differ · switched: 600 of the hour's 1,000 requests from Next.js, the rest from legacy, 0 failed

MR !4270 adds one CDN rule per rebuilt path and shadows it first, against a clean window the team wrote down before the shadow started (steps 2, 6, 9).

4.2 Ticketing: a box office moving page by page

A ticket site moves its box-office pages to a new app over six weeks, one route rule at a time.

4.2 ticketing: one route rule a week (help, account, orders, seat map, events) · share of the week's 1,000 requests the new app answers: week 1 0% · week 2 5% · week 3 15% · week 4 35% · week 5 60% · week 6 100% · failed requests 0 in every week

Each moved page serves its share from the new app the week it moves (step 4).

Try it

Answer first, then check. Nothing is saved.

Question 1 of 6

A ticket site's box office runs on a PHP app behind a load balancer. The team has rebuilt the /orders/:id page in a new service, which still has two bugs nobody has found. No customer may ever get a wrong order page, and no request may fail.

Put the four steps in order.

Your order

  1. 1empty
  2. 2empty
  3. 3empty
  4. 4empty

Tap the lines in the order you expect.

Question 2 of 6

The ticket site's next route, POST /orders/:id/refund, stores a refund row and emails the customer. The new service's refund still leaves out the booking fee on group bookings. The /orders page was shadowed by copying each request to the new service. The interviewer follows up.

How do you shadow the refund route?

Pick one

Question 3 of 6

A box office puts each month's shows on sale on the 1st, the day its old seat-map app also releases seats held by unpaid group bookings. The new seat-map service is shadowed from 5 March, at 4,000 requests a day, and the team fixes a difference the day after it appears.

Which switch-off criterion does the team write down before the shadow starts?

Pick one

Question 4 of 6

The box office's load balancer sends /account and /seat-map/:id to the new service. The PHP app's /account code was deleted last week; its seat-map code is still in place. The seat map came with the new service's latest build, and since this morning it shows sold seats as free.

Which change stops the wrong seat maps today without failing any request?

Pick one

Question 5 of 6

Two weeks ago the ticket site's load balancer started sending /orders to the new service. Customers reach /orders through the load balancer; the venue's door scanners and a nightly accounting export also fetch order pages. The team wants to delete the PHP app's /orders code.

Which check tells them whether that is safe?

Pick one

Question 6 of 6

A streaming service rebuilds the 6 pages of its legacy account app, one a week: page 1 in week 1, page 2 in week 2, and so on. Each week product ships one change, and each must reach users the week it is made: week 1 page 4, week 2 page 1, week 3 page 1, week 4 page 2, week 5 page 3. Plan X rebuilds all six pages and then switches. Plan Y routes each page to the new app as soon as it is rebuilt.

At the end of week 5, how many changes has each plan built twice, and how many pages do users get from the new app?

Pick one

Go deeper

Pro tips
  1. Before you shadow a route, count what the copies cost the new app's dependencies. When: a design round, when you propose shadow traffic and the interviewer asks what it costs (step 6). Verify:
    tip 50,000 shadowed requests a day x 3 database reads per page = 150,000 extra reads a day on a database the old and new apps share
    Status: RAN.
Source

quote-check.mjs finds every passage below verbatim in its saved text. Valid as of 2026-10-13.

  • Martin Fowler, Strangler Fig (22 August 2024): https://martinfowler.com/bliki/StranglerFigApplication.html (fowler-strangler-fig.txt). The row's only source. Quoted: "Replacing a serious IT system takes a long time, and the users can't wait for new features."; "Like the fig, it begins with small additions, often new features, that are built on top of, yet separate to the legacy code base."; "Since these components are small, there isn't so much risk involved when we introduce the new software."; "Once working, the business can reap the value from these new components, allowing earlier return on the investment."; "transitional architecture to allow the new and legacy system to coexist, code that will go away once the modernization is complete". Supports steps 1, 4 and 12.

The page names no routing layer, shadow comparison or log check.

Checked against the tools and docs as of 2026-10-13.