[{"data":1,"prerenderedAt":524},["ShallowReactive",2],{"insight-strangler-fig-modernization":3,"insights-cards":414},{"id":4,"title":5,"body":6,"category":395,"date":396,"description":397,"extension":398,"meta":399,"navigation":400,"path":401,"readingTime":402,"relatedArticles":403,"relatedAssessment":407,"relatedServices":408,"seo":411,"stem":412,"__hash__":413},"insights\u002Finsights\u002Fstrangler-fig-modernization.md","Replace the legacy system in slices: a working guide to the strangler fig pattern",{"type":7,"value":8,"toc":382},"minimark",[9,13,18,21,24,27,31,34,37,40,43,103,106,109,112,115,119,122,125,160,163,166,169,173,176,179,206,209,213,216,219,251,254,258,261,267,273,279,283,286,330,334,337,375,379],[10,11,12],"p",{},"A full rewrite asks the business to wait a year or two for a system that does what the old one already does. The strangler fig pattern removes the wait. A thin interception point goes between callers and the old application, capabilities migrate to new code one by one, and each retired piece of legacy code gets deleted once its replacement has proven itself. It works well when three things are true, and it fails in a predictable way when they are not.",[14,15,17],"h2",{"id":16},"why-the-rewrite-keeps-losing","Why the rewrite keeps losing",[10,19,20],{},"The big-bang rewrite has an attractive plan and a bad risk profile. All the value arrives on one date, at the end. Until that date, you pay for two systems and benefit from one. Requirements keep changing in the old system while the new one is being built, so the target moves. And the cutover is a single high-stakes weekend where every hidden behavior of a fifteen-year-old codebase gets discovered at once, in production, by your customers.",[10,22,23],{},"The strangler fig approach, a name Martin Fowler gave the pattern after the tree that grows around its host until the host is gone, changes the shape of the risk. Each step is small, each step ships, and each step can be undone. You never bet the company on one release.",[10,25,26],{},"The cost is real, and it is worth stating up front: you run two systems for the whole migration, and you have to build and operate the plumbing that connects them. The pattern trades one large risk for a longer period of moderate complexity. That is usually a good trade. It is not free.",[14,28,30],{"id":29},"the-facade-is-where-the-work-actually-happens","The facade is where the work actually happens",[10,32,33],{},"Everything depends on one component: a layer that sits between callers and the legacy system and decides, request by request, who answers.",[10,35,36],{},"At the start, the facade forwards everything to the old system and changes nothing. That first deployment is boring on purpose. It proves that you can stand in the path of production traffic without breaking it, and it is the single most valuable milestone in the first month.",[10,38,39],{},"After that, the facade gains routing rules. \"Requests for customer address lookups go to the new service. Everything else goes to the old one.\" Moving a capability means changing a rule. Rolling back means changing it back.",[10,41,42],{},"What the facade looks like depends on how callers reach the legacy system:",[44,45,46,59],"table",{},[47,48,49],"thead",{},[50,51,52,56],"tr",{},[53,54,55],"th",{},"How callers reach the old system",[53,57,58],{},"Where the facade goes",[60,61,62,71,79,87,95],"tbody",{},[50,63,64,68],{},[65,66,67],"td",{},"HTTP or web UI",[65,69,70],{},"Reverse proxy or API gateway routing by path, host or header",[50,72,73,76],{},[65,74,75],{},"Direct database access from other apps",[65,77,78],{},"A service API in front of the tables, with callers migrated onto it one by one",[50,80,81,84],{},[65,82,83],{},"File drops and batch jobs",[65,85,86],{},"An intake step that decides which pipeline processes each file",[50,88,89,92],{},[65,90,91],{},"Message queues",[65,93,94],{},"A router or topic split that sends message types to old or new consumers",[50,96,97,100],{},[65,98,99],{},"A desktop client talking to a database",[65,101,102],{},"Usually the hardest case; often you need a new UI for the migrated slice and a link to it from the old one",[10,104,105],{},"Three rules keep the facade healthy.",[10,107,108],{},"First, it routes and it does not think. The moment business rules start living in the proxy configuration, you have built a third system that nobody planned to maintain.",[10,110,111],{},"Second, routing has to be switchable without a deployment. A feature flag or a config value that can be flipped in seconds is what makes a slice reversible in practice, not only in theory.",[10,113,114],{},"Third, it must be able to route a fraction of traffic. Sending five percent of requests, or one customer segment, or internal users only, to the new path is how you find problems while they are still small.",[14,116,118],{"id":117},"picking-the-first-slice","Picking the first slice",[10,120,121],{},"The first slice sets the tone for the whole program. Choosing it badly is the most common early mistake, and it usually goes wrong in one of two directions: too trivial to prove anything, or so central that it takes nine months and the sponsor loses patience.",[10,123,124],{},"A good first slice has these properties:",[126,127,128,136,142,148,154],"ul",{},[129,130,131,135],"li",{},[132,133,134],"strong",{},"A clean seam."," There is an identifiable set of entry points (a few URLs, one screen, one batch job) that you can intercept without touching everything else.",[129,137,138,141],{},[132,139,140],{},"Limited data entanglement."," It reads and writes a small number of tables, and ideally few other modules write to those same tables.",[129,143,144,147],{},[132,145,146],{},"Visible value."," Someone outside engineering will notice that it got better. A read-only report nobody opens proves the plumbing and nothing else.",[129,149,150,153],{},[132,151,152],{},"Bounded size."," A team can take it to production in weeks, not quarters.",[129,155,156,159],{},[132,157,158],{},"Real traffic."," It needs enough usage to exercise the facade, the deployment pipeline and the monitoring under honest conditions.",[10,161,162],{},"A simple way to choose is to list candidate capabilities and score each one on business value, coupling to the rest of the system, and risk if it misbehaves. You are looking for high value, low coupling, moderate risk. The module that causes the most pain is often the most tangled one, so resist starting there. Take it third or fourth, after the team has the routing, the data sync and the rollback routine working.",[10,164,165],{},"Picture a regional distributor running a twenty-year-old order management system. The pricing engine is the thing everyone complains about, but it reaches into inventory, contracts, credit limits and invoicing. Order status lookup, by contrast, is read-mostly, is hit thousands of times a day by customers and reps, and touches a handful of tables. Status lookup goes first. It delivers a faster customer portal, and it forces the team to build the facade, the read replica or data feed, and the monitoring. Pricing goes later, with all that infrastructure already paid for.",[10,167,168],{},"One more test: prefer a first slice that includes at least one write. A purely read-only slice postpones every hard question about data ownership, and those questions are where migrations stall.",[14,170,172],{"id":171},"data-is-the-hard-part","Data is the hard part",[10,174,175],{},"Routing requests is straightforward. Deciding where the truth lives is not.",[10,177,178],{},"For every slice, pick exactly one system of record for each piece of data at each point in time. The workable options are:",[180,181,182,188,194,200],"ol",{},[129,183,184,187],{},[132,185,186],{},"New service reads from the legacy database."," Fastest to start. It couples the new code to the old schema, so treat it as temporary and hide the schema behind a translation layer.",[129,189,190,193],{},[132,191,192],{},"Legacy remains the writer, new system gets a copy."," Change data capture or scheduled sync feeds a new store. Good for read-heavy slices. You must accept and measure the replication delay.",[129,195,196,199],{},[132,197,198],{},"New system becomes the writer, legacy gets a copy."," Needed once a slice is truly migrated but old modules still depend on the data. The sync now runs in the other direction.",[129,201,202,205],{},[132,203,204],{},"Both write."," Avoid it. Dual writes without a single owner produce conflicts that surface weeks later as reconciliation tickets.",[10,207,208],{},"The step from option 2 to option 3 is the real cutover for a slice. Plan it as its own event, with a rehearsal.",[14,210,212],{"id":211},"shadow-compare-cut-over","Shadow, compare, cut over",[10,214,215],{},"Do not switch a slice on faith. Run the new implementation next to the old one and compare what they produce.",[10,217,218],{},"The sequence that works:",[180,220,221,227,233,239,245],{},[129,222,223,226],{},[132,224,225],{},"Shadow."," The facade sends each request to the old system, returns the old answer to the caller, and also sends a copy to the new system. The new system's response is recorded and discarded. For writes, the new path must run against a sandbox or in a dry-run mode so it produces no side effects (no emails, no payments, no duplicate orders).",[129,228,229,232],{},[132,230,231],{},"Compare."," A job diffs old and new outputs. Every mismatch is classified: a bug in the new code, a bug in the old code that the business has been living with, or an intentional difference. The second category is always larger than anyone expects, and each case needs a decision from someone who owns the process, not from a developer guessing.",[129,234,235,238],{},[132,236,237],{},"Canary."," Route a small share of real traffic to the new path and serve its answers. Watch error rates, latency and the business numbers that the slice affects.",[129,240,241,244],{},[132,242,243],{},"Ramp and switch."," Increase the share in steps. At one hundred percent, keep the old path alive and callable for an agreed period.",[129,246,247,250],{},[132,248,249],{},"Decommission."," Remove the old code, the old tables that nothing else uses, the sync jobs and the routing rule. The slice is not done until this step is done.",[10,252,253],{},"Step 5 is the one that gets skipped. An old code path that is \"probably unused\" stays forever, and the system you were shrinking stops shrinking.",[14,255,257],{"id":256},"three-conditions-that-break-it","Three conditions that break it",[10,259,260],{},"The pattern is not self-executing. It fails in three recognizable ways.",[10,262,263,266],{},[132,264,265],{},"There is no seam."," If there is no place to intercept calls, there is nothing to route. This happens with thick clients bound directly to a database, with logic buried in stored procedures and triggers that fire regardless of who writes, and with systems where every module calls every other module through shared memory or shared tables. You can sometimes create a seam first (wrap the database in an API, move triggers into a service), but that is a project in its own right and it has to be budgeted honestly.",[10,268,269,272],{},[132,270,271],{},"The data cannot be divided."," When forty modules read and write the same wide tables, each slice you extract still depends on the whole. You end up with new services on the outside and one shared legacy database in the middle, which gives you the operating cost of a distributed system and the coupling of a monolith. If the data model cannot be split along the lines of your slices, fix that or pick different slices.",[10,274,275,278],{},[132,276,277],{},"The organization stops halfway."," The first slices deliver most of the visible benefit. The remaining ones are less glamorous. Funding moves to something else, and the company is left running both systems, plus the facade and the sync jobs, with no end date. This is strictly worse than either finishing or never starting. The defense is to make decommissioning an explicit, funded deliverable of every slice, and to get agreement on the end state before the first one starts.",[14,280,282],{"id":281},"what-to-track","What to track",[10,284,285],{},"Counting migrated screens tells you about effort. These tell you whether the legacy system is actually dying:",[126,287,288,294,300,306,312,318,324],{},[129,289,290,293],{},[132,291,292],{},"Share of traffic or transactions served by the new path",", per capability and overall.",[129,295,296,299],{},[132,297,298],{},"Legacy surface removed",": tables dropped, jobs retired, lines of code deleted, licenses cancelled. If this number is flat while \"migrated\" goes up, you are accumulating, not replacing.",[129,301,302,305],{},[132,303,304],{},"Mismatch rate during shadow runs",", and how long open mismatches stay unresolved.",[129,307,308,311],{},[132,309,310],{},"Lead time per slice",", from start to decommission. It should fall as the team learns. If it rises, the remaining slices are more coupled than the plan assumed.",[129,313,314,317],{},[132,315,316],{},"Sync health",": replication lag and reconciliation failures between the two systems.",[129,319,320,323],{},[132,321,322],{},"Incidents caused by the migration itself",", and how long rollback took in each case.",[129,325,326,329],{},[132,327,328],{},"Run cost of the dual estate",", so the price of dragging the migration out is visible to whoever controls the budget.",[14,331,333],{"id":332},"when-a-different-approach-is-better","When a different approach is better",[10,335,336],{},"The strangler fig is a default, not a law. Skip it when:",[126,338,339,345,351,357,363,369],{},[129,340,341,344],{},[132,342,343],{},"The system is small."," If a competent team can rebuild and test the whole thing in a couple of months, the facade and sync machinery cost more than they save.",[129,346,347,350],{},[132,348,349],{},"A packaged product is the right replacement."," If you are moving to a commercial ERP or CRM, the vendor's migration path, not incremental strangling, often dictates the sequence. You may still phase by business unit or region.",[129,352,353,356],{},[132,354,355],{},"The business process itself is being discarded."," There is no point in carefully reproducing behavior you intend to eliminate. Redesign the process first.",[129,358,359,362],{},[132,360,361],{},"There is a hard external deadline."," End of vendor support or a data center exit may force a lift-and-shift now, with incremental modernization afterward.",[129,364,365,368],{},[132,366,367],{},"No seam can be made at a reasonable cost."," Sometimes the honest answer is a parallel new system with a planned data migration and a rehearsed cutover.",[129,370,371,374],{},[132,372,373],{},"The data model is the actual problem."," If the schema is what is wrong, wrapping the code around it preserves the defect.",[14,376,378],{"id":377},"which-part-of-your-system-could-you-move-first-without-anyone-noticing","Which part of your system could you move first without anyone noticing?",[10,380,381],{},"If you can name the slice, the seam and the owner of its data, you are most of the way to a plan. If you cannot, that gap is the first thing worth two weeks of focused work. Trivo maps the slices, the facade and the data ownership with your team and leaves you with a written sequence you own.",{"title":383,"searchDepth":384,"depth":384,"links":385},"",2,[386,387,388,389,390,391,392,393,394],{"id":16,"depth":384,"text":17},{"id":29,"depth":384,"text":30},{"id":117,"depth":384,"text":118},{"id":171,"depth":384,"text":172},{"id":211,"depth":384,"text":212},{"id":256,"depth":384,"text":257},{"id":281,"depth":384,"text":282},{"id":332,"depth":384,"text":333},{"id":377,"depth":384,"text":378},"Modernization","2026-10-12","How to retire a legacy system piece by piece while the business keeps running: the facade, the first slice, parallel runs, and when the pattern fails.","md",{},true,"\u002Finsights\u002Fstrangler-fig-modernization",9,[404,405,406],"legacy-erp-anticorruption-layer","rpa-vs-api-integration","build-vs-buy","legacy-risk",[409,410],"modernization","custom-software",{"title":5,"description":397},"insights\u002Fstrangler-fig-modernization","t155gtQzs6PwedmviCDCXEvSbUFGydEL0FgpxrjSeS4",[415,421,428,433,438,443,451,456,461,466,472,479,484,490,496,501,507,512,517,519],{"path":416,"title":417,"description":418,"category":419,"readingTime":402,"relatedServices":420,"date":396},"\u002Finsights\u002Fbuild-vs-buy","The License Fee Is the Small Number: A Working Guide to Build or Buy","Buying software is usually right, until the product sits on top of how you make money. How to sort capabilities, price the hidden costs and decide.","Strategy",[410,409],{"path":422,"title":423,"description":424,"category":425,"readingTime":402,"relatedServices":426,"date":396},"\u002Finsights\u002Fcloudflare-observability","The Cloudflare Signals You Need Wired Up Before Something Breaks","Cloudflare records plenty by default. Whether a person hears about a problem in time depends on choices made in a quiet week, not mid-outage.","Cloudflare",[427,409],"cloudflare",{"path":429,"title":430,"description":431,"category":425,"readingTime":402,"relatedServices":432,"date":396},"\u002Finsights\u002Fcloudflare-performance-tuning","After the Static Assets: Where Cloudflare Performance Is Actually Won","Default caching handles images, CSS and JavaScript. The larger gains sit in HTML, API responses, cache keys and origin trips that nobody tuned.",[427,410],{"path":434,"title":435,"description":436,"category":425,"readingTime":402,"relatedServices":437,"date":396},"\u002Finsights\u002Fcloudflare-waf-and-ddos","Managed Rules Know the Internet. Custom Rules Have to Know Your Application.","Cloudflare's managed WAF and DDoS rules stop generic attacks. Logins, APIs, bots and false positives still need rules written from your own traffic.",[427,410],{"path":439,"title":440,"description":441,"category":425,"readingTime":402,"relatedServices":442,"date":396},"\u002Finsights\u002Fcloudflare-zero-trust-and-integrity","Who Got In Versus What Is Running: Two Integrity Problems One Control Cannot Solve","Zero Trust verifies who reaches a system. Client-side script monitoring verifies what runs in the browser. They fail differently and need separate owners.",[427,409],{"path":444,"title":445,"description":446,"category":447,"readingTime":448,"relatedServices":449,"date":396},"\u002Finsights\u002Fcrm-adoption-and-training","Your CRM Passed Every Test and Nobody Uses It: A Diagnostic for Stalled Adoption","Low CRM adoption is rarely a training gap. How to tell whether the cause is screen friction, missing payback or management habits, and what to fix first.","CRM",8,[450],"crm",{"path":452,"title":453,"description":454,"category":447,"readingTime":448,"relatedServices":455,"date":396},"\u002Finsights\u002Fcrm-implementation-timeline","The Honest Calendar of a CRM Implementation: Five Phases and Where the Weeks Go","Provisioning a CRM takes a day. Making it the place your team sells from takes months. A phase-by-phase calendar, with the parts quotes tend to leave out.",[450,410],{"path":457,"title":458,"description":459,"category":447,"readingTime":402,"relatedServices":460,"date":396},"\u002Finsights\u002Fcrm-migration-checklist","CRM Migration Checklist: The Records Arrive, the Selling Process Gets Left Behind","A CRM migration is a process migration with a data load attached. What a plain export loses, how to choose a cutover, and a checklist for each stage.",[450,409],{"path":462,"title":463,"description":464,"category":447,"readingTime":448,"relatedServices":465,"date":396},"\u002Finsights\u002Fcustom-crm-vs-off-the-shelf","Should You Build Your Own CRM? Run the Build-or-Buy Test on Your Sales Process","Most of a CRM is a commodity you should buy. The question is whether the way you sell fits the platform's model, and what it costs when it does not.",[450,410],{"path":467,"title":468,"description":469,"category":419,"readingTime":470,"relatedServices":471,"date":396},"\u002Finsights\u002Fcustom-software-cost-framework","Estimate Before the Estimate: Sizing a Custom Software Budget on Your Own","You can't know the price before a quote, but you can know what drives it. Six cost drivers, a self-check worksheet and how to read a proposal.",10,[410],{"path":473,"title":474,"description":475,"category":476,"readingTime":402,"relatedServices":477,"date":396},"\u002Finsights\u002Fetl-vs-elt","Transform before or after loading? A practical ETL versus ELT decision for mid-sized teams","ETL or ELT is a question of where transformation runs and who pays for it. A practical way for a mid-sized team to choose, with the costs most plans miss.","Data",[410,478],"ai-automation",{"path":480,"title":481,"description":482,"category":419,"readingTime":470,"relatedServices":483,"date":396},"\u002Finsights\u002Fevaluating-engineering-depth","Ask About the Outage: How to Vet a Software Vendor's Real Engineering Ability","Portfolios and logos look the same from every vendor. The interview questions, artifacts and deal-breakers that show who has really run software in production.",[410,409],{"path":485,"title":486,"description":487,"category":488,"readingTime":470,"relatedServices":489,"date":396},"\u002Finsights\u002Fhipaa-business-associate-agreement","A BAA Is a Contract, Not a Badge: What Your Software Vendor Is Really Signing Up For","What a HIPAA Business Associate Agreement commits a software vendor to, what it leaves unproven, and what to ask and build before PHI reaches the system.","Compliance",[410,478],{"path":491,"title":492,"description":493,"category":488,"readingTime":494,"relatedServices":495,"date":396},"\u002Finsights\u002Fhipaa-technical-safeguards-checklist","Reading 45 CFR 164.312 Like a Design Document: HIPAA Technical Safeguards for Engineers","The five HIPAA technical safeguard standards mapped to concrete engineering decisions: identity, logging, integrity, authentication and encryption.",11,[410,409,427],{"path":497,"title":498,"description":499,"category":395,"readingTime":402,"relatedServices":500,"date":396},"\u002Finsights\u002Flegacy-erp-anticorruption-layer","The ERP stays as it is: building on a decades-old system through an anti-corruption layer","How to build new software on an old ERP without modifying it, using an anti-corruption layer: what goes inside, how to handle writes, when to skip it.",[409,410],{"path":502,"title":503,"description":504,"category":505,"readingTime":470,"relatedServices":506,"date":396},"\u002Finsights\u002Fllm-in-production-confidence-thresholds","An LLM that proposes and a system that decides: thresholds, review and audit for production AI","Running an LLM in production without giving it autonomy: measured confidence, thresholds set by business cost, human review that works, an audit trail.","AI",[478,410],{"path":508,"title":509,"description":510,"category":419,"readingTime":402,"relatedServices":511,"date":396},"\u002Finsights\u002Fnearshore-offshore-onshore-cost","Cheap Hours, Expensive Projects: Pricing US, Nearshore and Offshore Teams Honestly","The hourly rate tells you little about what a project will cost. How overlap, rework, turnover and compliance change the math for each delivery model.",[410],{"path":513,"title":514,"description":515,"category":505,"readingTime":402,"relatedServices":516,"date":396},"\u002Finsights\u002Frpa-vs-api-integration","Bots on the screen or calls to the API: where RPA earns its place and where it becomes debt","RPA and API integration solve the same problem at different layers. How to choose, what screen automation really costs, and how to run it safely if you must.",[478,410],{"path":401,"title":5,"description":397,"category":395,"readingTime":402,"relatedServices":518,"date":396},[409,410],{"path":520,"title":521,"description":522,"category":419,"readingTime":470,"relatedServices":523,"date":396},"\u002Finsights\u002Ftwo-week-discovery-deliverables","Paying for a Plan, Not a Pitch: What Two Weeks of Discovery Owes You","A paid discovery should leave you with documents another team could build from. The five deliverables, the work behind them and the limits to expect.",[410,409],1792618973217]