Iurii RoguliaIurii Rogulia
AboutServicesPricingProjectsStackReviewsPhrasesBlog
Contact
Iuriiย ships.

Iurii Rogulia, IT partner for business & fractional CTO. Professionally building software since 2001.

Think of a number
PricingQuality checklistPrivacy PolicyCookie Policy

Business

TMI Iurii Rogulia
VAT ID: FI29845875
DUNS: 368664211
Lappeenranta, Finland ๐Ÿ‡ซ๐Ÿ‡ฎ

[email protected]
  1. Home
  2. /
  3. Blog
  4. /
  5. Rewrite or Stabilise: The Decision Framework I Use

Iuriiย Advises: Rewrite or Stabilise: The Decision Framework I Use

The instinct to rewrite is almost always wrong โ€” here's how to tell when it isn't

June 22, 2026ยท 12 min read

Rewrite or stabilise a legacy codebase? A practical decision framework: when stabilisation wins, when rewrite is justified, and the Strangler Fig middle path.

Topics

Rescue ProjectsTechnical StrategyLegacy CodeArchitectureEngineering Practice
Rewrite or Stabilise: The Decision Framework I Use

On this page

  • Why the Rewrite Instinct Is a Trap
  • What Stabilisation Actually Involves
  • When Rewrite Is Actually Justified
  • The Decision Framework
  • What I Usually Find
  • The Question Worth Asking First

A founder reaches out. The message is usually some version of this: "Our codebase is a mess. Previous developers left, the thing barely works, we've been patching it for two years. We think we need to rewrite everything. Can you help?"

My first question is never "when do you want to start?" It's: "What makes you think it needs a rewrite?"

The answer is almost always some combination of: the code is hard to read, adding features takes too long, the old developers wrote it in a way nobody understands anymore, and something broke last week that took three days to fix.

None of those are reasons to rewrite. They're symptoms of a system under strain โ€” and the question of whether rewrite is the right response to that strain is one of the most consequential technical decisions a company can make. It's also one that gets made badly, consistently, because it gets made on emotion rather than analysis.

I've been on both sides of this decision. I've stabilised systems that looked unsalvageable. I've recommended rewrites when stabilisation genuinely wasn't the right answer. The framework I use now is the result of getting both calls right and wrong enough times to know what actually matters.

Why the Rewrite Instinct Is a Trap

The pull toward rewriting is understandable. You're looking at code that's painful to work in. You know roughly what the system should do. You know the current implementation is wrong in dozens of ways. Starting fresh seems like it would clear all of that โ€” a clean slate, no accumulated technical debt, no inherited decisions you wouldn't have made yourself.

This is the "second system" problem, documented by Fred Brooks in 1975 and rediscovered by every generation of developers since. The rewrite starts optimistically. It proceeds reasonably. And then, somewhere around the 60% mark, it runs into the same wall every rewrite runs into: the old system contained knowledge that wasn't in any document, specification, or README. It was encoded in the code itself โ€” in the edge cases it handled, the validation rules it enforced, the integration behaviours that were discovered through production incidents and silently fixed.

The rewrite doesn't have this knowledge. It has to rediscover it. Through incidents. With real users.

Meanwhile, the business is running on the old system. Two timelines now exist: the old system, which still needs maintenance and still breaks, and the new system, which is consuming engineering capacity without producing any business value yet. This lasts longer than anyone estimated โ€” typically 1.5x to 3x longer. Features that were planned for the new system get postponed. The old system gets more fragile because the people who understood it are now working on the replacement.

The most common outcome: the rewrite ships late, is missing features the old system had, and within two years is described by the next team as "the old codebase" โ€” a mess that needs replacing.

I'm not opposed to rewrites. I'm opposed to reflexive ones.

What Stabilisation Actually Involves

Stabilisation is not "leave everything as-is and suffer." It's a deliberate programme of making a system safe to work in โ€” without rebuilding it from scratch.

In practice, it has four components:

Critical path tests. The first thing I do in any rescue engagement is write tests for the paths that matter most: the payment flow, the authentication sequence, the order pipeline, whatever is core to the business working. Not unit tests โ€” end-to-end characterisation tests that capture what the system currently does, good and bad. These are your safety net before you touch anything. I've written about this in more detail in agency codebase takeover โ€” the first 48 hours before you change a line.

Observability. A system you can't see is a system you can't safely change. The second priority is getting logs, error tracking, and alerting into the production environment. Not because it fixes anything immediately, but because it means the next time something breaks, you find out first. Before this is in place, every change is a blind operation.

Selective stabilisation of the highest-risk areas. Not everything needs to be fixed. The goal is to identify the three or four things that are genuinely dangerous โ€” money paths with no idempotency, authentication with gaps, database queries that will fail under moderate load โ€” and fix those first. Everything else goes in a prioritised backlog. Trying to fix everything at once is how stabilisation projects turn into de-facto rewrites with none of the planning.

Strangler Fig for the worst modules. Where a specific module is genuinely unsalvageable โ€” the logic is incomprehensible, the structure is wrong, there's no safe path to incremental improvement โ€” the answer is not to rewrite the whole system, but to replace that module incrementally. You build the replacement alongside the old code, route traffic to it gradually, and delete the original once you're confident. This is the Strangler Fig pattern, and it's the right answer for the 20% of cases where a module really does need replacing. It is not the answer for the 80% of cases where a module is merely unpleasant.

Related service

Rescue Projects

Inherited a codebase someone's told you to rewrite? I do structured rescue assessments โ€” codebase audit, honest written recommendation, and a path that doesn't require betting six months of engineering on a big-bang rewrite.

More about this service โ†’

When Rewrite Is Actually Justified

There are real cases where rewrite is the right answer. They are rarer than the instinct suggests, but they exist.

The technology stack is genuinely dead. Not "old" โ€” dead. A system built on a framework with no maintained dependencies, no security patches, and no engineers who still know it is a system that cannot be safely operated. The cost of keeping it running โ€” the constant workarounds, the inability to hire, the security exposure โ€” exceeds the cost of replacing it. This is different from "it's not the latest version" or "we'd write it differently today." Those aren't rewrite justifications.

The data model is fundamentally wrong for what the business does now. This is the most legitimate technical rewrite trigger I encounter. If the business has changed direction significantly and the data model no longer reflects how the product actually works, stabilisation becomes increasingly expensive with each new feature. You're not paying down technical debt โ€” you're fighting the data model. This is rare, but when the schema is architecturally incompatible with the current product direction, that's real.

The business has changed what it is, not just what it does. Sometimes a company acquires another product, pivots from B2C to B2B, or decides to embed a formerly standalone system into a larger platform. The old system wasn't designed for this context and cannot be made to fit it through incremental work. This is a legitimate rewrite trigger โ€” but note that it's a business reason, not a code quality reason.

The accumulated risk is higher than the replacement cost. This is the hardest one to measure but it's real. Some systems have accumulated enough contradictions โ€” security exposures, data integrity issues, operational fragility โ€” that the cost of maintaining them is genuinely higher than the cost of replacing them. To make this argument honestly, you need numbers: the cost of the incidents the system has caused, the ongoing engineering overhead, the opportunity cost of features you can't ship. Without numbers, it's an aesthetic argument dressed up as an economic one.

What's notably absent from this list: "the code is hard to read," "developers don't like working in it," "it wasn't built the way I would have built it," and "we inherited it from a team we don't trust." These are not rewrite justifications. They're reasons to improve documentation, run a code review, and write a coding-standards doc.

The Decision Framework

When I enter a rescue engagement and need to form a recommendation, I go through a set of questions in roughly this order.

Frequency and severity of incidents. How often does the system fail in ways that affect users? How long does it take to diagnose and fix those failures? A system with one production incident per month that takes four hours to resolve is in a different category than one with daily incidents that require a specialist. The incident log is often the most honest signal about how the system is actually behaving โ€” more honest than the code, which can look terrible and still be stable.

Test coverage on critical paths. Not overall coverage percentage โ€” that number is almost meaningless. Are the core business flows โ€” payment, authentication, the primary user journey โ€” covered by tests that would catch a regression? If yes, you have a foundation to build on. If no, your first job is to create that foundation, not to rewrite.

Age of the stack and dependency health. Is the stack still maintained? Are there known security vulnerabilities in dependencies with no upgrade path? A system on a deprecated Node.js LTS with unpatched CVEs in production dependencies is a different situation than a system on a current stack with messy application code.

Team turnover and knowledge concentration. Who understands how the system works? If one engineer left six months ago and took all operational knowledge with them, you don't necessarily have a rewrite problem โ€” you have a knowledge recovery problem. Rewriting won't give you the knowledge back; it'll just give you a new system nobody fully understands.

Data model coherence. Does the database schema reflect what the product actually does? Or has it accumulated tables, columns, and relations that map to a version of the product that no longer exists? Schema drift โ€” the gap between what the migrations say and what the product needs โ€” is one of the more reliable indicators of how much architectural work stabilisation will involve.

Business horizon for feature delivery. How long can the business wait for new feature delivery while engineering is consumed by rescue work? A company with runway pressure and stakeholders expecting visible progress in three months is in a different position from one with time to invest in a six-month stabilisation. This doesn't change what the right technical answer is, but it changes what plan is actually feasible.

Cost of the incidents versus cost of the rewrite. This is where the analysis has to get honest. If incidents are costing the business โ‚ฌ5,000 per month in support time, lost revenue, and engineering hours, and stabilisation would cost โ‚ฌ40,000 and take the incident rate to near zero, stabilisation pays for itself in eight months. If stabilisation would cost โ‚ฌ40,000 and reduce incidents by 30%, the math looks different. Actual numbers, not estimates, not feelings.

What I Usually Find

In the rescue projects I've taken on, the breakdown has been roughly this: around two-thirds of the time, the right answer is stabilisation โ€” often with Strangler Fig replacement of one or two modules. One third of the time, there's a case for some form of rewrite, and in most of those cases, that rewrite is partial rather than complete: replace the payment module, keep the order management; rebuild the auth layer, keep the rest.

Full big-bang rewrites โ€” throw everything out and start from scratch โ€” have been the right answer in a small minority of cases. They've been cases where the technology was genuinely unsupported, or where the data model was so wrong that every feature was a fight against the schema, or where the system had accumulated security debt severe enough that the operational risk of running it exceeded the disruption of replacement.

The pattern I see most often is a codebase that's genuinely difficult to work in โ€” unclear structure, missing tests, accumulated inconsistencies โ€” but that still has sound core logic and a data model that reflects the product correctly. That system does not need a rewrite. It needs someone to read it carefully, understand what's load-bearing, and build a stabilisation plan that makes it safe to change without touching everything at once. That work is less dramatic than a rewrite and produces a working system faster.

Before I give any recommendation at all, I spend two hours reading the code, which I've described in detail in technical due diligence before a rewrite. The recommendation only comes after that. Anyone who tells you whether to rewrite or stabilise before they've read the code is guessing.

The Question Worth Asking First

There's one question I've learned to ask before any technical analysis, and the answer changes how everything else is framed.

"If the codebase were clean and well-tested tomorrow morning, would you know what to build next?"

If the answer is yes โ€” you have a clear product direction, defined features, a team ready to execute โ€” then the technical question matters a lot. Getting the codebase to a state where it can support that work is worth investing in.

If the answer is no โ€” if the real problem is unclear direction, team misalignment, or business decisions that haven't been made โ€” then the codebase is not the primary problem. Fixing it won't fix what's actually broken. I've seen rewrites happen for this reason: the technical decision becomes a proxy for a non-technical crisis, and the rewrite provides the feeling of action while the real problem waits.

The technical decision is consequential. It's also sometimes the second decision, not the first.


If you're at this decision point โ€” a codebase that's struggling and pressure from multiple directions about what to do โ€” the due diligence post describes exactly what I examine before forming any recommendation. The agency codebase takeover post covers the first days of a stabilisation engagement in detail. And if the codebase was built mostly by AI, vibe-coded codebase patterns describes the specific failure modes that look like chaos but follow a consistent pattern.

Iurii Rogulia

Working on something like this?

Rescue Projects

If you're standing at this decision point right now โ€” a codebase that's barely holding together and no clear path forward โ€” that's exactly the kind of engagement I take on. I'll tell you honestly which way it should go.

More about this service

Relevant client work

View all projects
Pikkuna โ€” AI-Powered Localization Pipeline
Pikkuna โ€” AI-Powered Localization Pipeline
July 30, 2026
Pikkuna โ€” AI-Powered Localization Pipeline

A production localization pipeline built entirely on the OpenAI API: one English source of truth, SEO-aware translation prompts, cross-model verification with

pi-pi.ee โ€” B2B Deal & Document Portal
pi-pi.ee โ€” B2B Deal & Document Portal
July 1, 2026
pi-pi.ee โ€” B2B Deal & Document Portal

Internal sales portal that turns a wholesale deal into a full set of trade paperwork โ€” pro forma, contract, commercial invoice, packing list, CMR and more โ€”

HTPBE? โ€” Internal Admin Dashboard
HTPBE? โ€” Internal Admin Dashboard
March 15, 2026
HTPBE? โ€” Internal Admin Dashboard

Role-gated admin dashboard for the HTPBE? SaaS platform โ€” real-time KPIs, per-user quota tracking, and a zero-dependency bar chart, all server-rendered via

What clients say

โ€œ

I'd built most of our MVP with Cursor and it looked finished โ€” it compiled, the tests were green, the demo worked. It just wouldn't survive real users. Iurii took it over and found what I couldn't see: authentication handled four different ways, tests that only asserted what the code already did, and a dependency list half of which was unused. He didn't rewrite it from scratch โ€” he told me honestly what was salvageable, ripped out the dead code, and got it to something a real team could build on. Two weeks and it went from 'looks done' to actually shippable.

Sebastian Falk ๐Ÿ‡ธ๐Ÿ‡ช

Founder

Stack

Next.jsTypeScript

Topics

Technical DebtAICode ReviewArchitecture
โ€œ

We had an acquisition offer on the table and I needed to know whether our own codebase would survive the buyer's technical review before I walked into that room. Iurii did a five-day independent audit and gave me a written report I could actually act on โ€” what was solid, the two things that would raise flags in a data room, and what it would take to fix them first. He caught an undocumented dependency on one ex-contractor's private package that would have been a red flag the moment their team looked. We cleaned it up before diligence started, and the deal closed without a single technical concession. Best money I spent on the whole process.

Wouter Claes ๐Ÿ‡ง๐Ÿ‡ช

Founder & CEO

Topics

Due DiligenceArchitectureCode ReviewTechnical Debt
โ€œ

We'd just raised and needed to double the engineering team fast, but nobody internally had hired at that scale or owned the architecture decisions that came with it. A full-time CTO was a six-month search we didn't have time for. Iurii held the role two days a week in the meantime โ€” he set up the interview loop, sat in on the senior candidates, killed a rewrite the team was quietly drifting toward, and made the infrastructure call before it turned into a fire. When we finally hired someone permanent the handover took a week because everything was already documented. He ran it like an owner, not a consultant billing hours.

Kasper Holm ๐Ÿ‡ฉ๐Ÿ‡ฐ

CEO

Topics

LeadershipCTOHiringArchitectureStrategy

Related articles

Technical Due Diligence Checklist Before a Software Rewrite
June 10, 2026ยท 17 min
Technical Due Diligence Checklist Before a Software Rewrite

Technical due diligence before a rewrite: a structured 2-hour audit method covering architecture, security, debt, and cost range. What to expect.

Topics

Rescue ProjectsTechnical Due DiligenceEngineering PracticeBest Practices
Why AI Coding Widens the Seniorโ€“Junior Developer Gap
June 1, 2026ยท 16 min
Why AI Coding Widens the Seniorโ€“Junior Developer Gap

AI coding widens the gap between senior and junior developers โ€” it amplifies existing skill.

Topics

AIEngineering PracticeBest PracticesArchitectureOpinion
Preventing Overselling: Inventory Locks Under Concurrent Checkouts
July 31, 2026ยท 13 min
Preventing Overselling: Inventory Locks Under Concurrent Checkouts

Prevent overselling under concurrent checkouts: reservations vs hard decrements, SELECT FOR UPDATE, deadlock-safe multi-line carts, and the payment window.

Stack

Next.jsTypeScriptNode.js

Databases

PostgreSQLRedis

Topics

E-commercePaymentsArchitectureSaaS
Gated B2B Pricing in Next.js: Hiding Prices Behind Per-Customer Access
July 24, 2026ยท 9 min
Gated B2B Pricing in Next.js: Hiding Prices Behind Per-Customer Access

Gated B2B pricing in Next.js: per-account price lists, server-side access control so prices never leak to crawlers, and a deal-record data model where every

Stack

Next.jsReactTypeScript

Databases

PostgreSQL

Topics

B2BE-commerceAuthSSRArchitectureSecurity
Why 'Two Weeks' Always Means Six โ€” and How to Estimate Honestly
July 15, 2026ยท 15 min
Why 'Two Weeks' Always Means Six โ€” and How to Estimate Honestly

How to estimate software projects honestly: why two weeks becomes six, the iceberg under the happy path, ranges over single numbers, and calibration.

Topics

Fractional CTOProject ManagementSoftware EstimationEngineering PracticeLeadership