The short version. Modernizing a legacy PHP app costs less than a rewrite and carries far less risk, because you keep the product earning while you fix it. A rewrite asks you to pay twice, once to rebuild what already works, and again for the months of lost ground while the new version catches up. I price modernization as a monthly partnership, not a fixed quote, because the honest answer to “what will it cost” depends on the state of your codebase, and I can only know that after I read it. This post explains what actually drives the cost, so you can budget before we talk.
Why a rewrite is the expensive option, not the cheap one
A rewrite feels cheaper because it comes with a clean number. Someone quotes you a fixed price to “rebuild it properly,” and a fixed number feels safe.
It is not safe. A rewrite pays to recreate features your customers already use, and every one of them has years of edge cases baked in that nobody wrote down. You do not see those edge cases until the new version breaks on them in production. Meanwhile the old system still needs maintenance, so for the length of the rewrite you are paying for two systems and shipping value on neither.
I have watched teams spend eighteen months rewriting a product that made money the whole time, and arrive at a new version that did less than the old one. The old code was not bad. It was just unread. Modernizing in place costs less because you never stop earning, and you never throw away the edge cases that took years to get right.
What actually drives the cost of modernization
The cost of modernizing a legacy PHP app is driven by four things: how stable the code is right now, how much of it lacks tests, how tangled the worst parts are, and how fast you need to move. Nothing else moves the number much.
Stability comes first. If the app falls over under load or throws errors nobody has traced, the first weeks go to stopping the bleeding, not to new work. A codebase that is ugly but stable is cheaper to modernize than a pretty one that crashes.
Test coverage is the second driver. If there are no tests, I add them at the seams before I change anything, so a fix in one place cannot silently break another. That is upfront cost that pays for itself the first time it catches a regression before your customers do.
The third is how tangled the hardest parts are. Most legacy apps have one or two areas everyone is scared to touch. Those cost real time. The rest usually moves faster than people expect.
The fourth is pace. Modernizing in small safe steps over months costs less per unit of work than a rushed push, because rushed work skips the tests and you pay for that later.
When a rewrite is actually the right call
A rewrite is sometimes the honest answer, and I will tell you when it is. If the stack is dead rather than just old, running on a PHP version that no longer gets security patches and a framework nobody maintains, you are not modernizing, you are on life support, and a rewrite is the way out. If the app is small, a few thousand lines of straightforward code with no years of edge cases baked in, then the main reason not to rewrite does not apply, and a rewrite is quick and cheap. And if the business itself has changed shape, so the old code is not a worn asset but the wrong tool, rebuilding is the right move.
What I argue against is the big-bang rewrite of a large product that makes money and whose problems are fixable in place. That is the specific case where the rewrite’s cost is systematically underestimated, because the clean fixed quote hides the two systems you pay for and the ground you lose. For a product like that, modernizing in place wins. For the cases above, it does not, and I will say so before you spend a dollar.
How I price it: a monthly partnership, not a fixed quote
I price modernization as a fixed monthly retainer, because that is the model that keeps my incentives pointed at your product instead of at a finish line. This is how I have worked with founders for years. PerkZilla has been a fractional-CTO engagement since its 2016 launch. Viktoria Professional Movers started as a six hundred dollar Upwork project in 2011 and became a fifteen-year partnership.
A fixed quote pays me to reach a milestone and leave. A monthly partnership pays me to keep your product healthy and to still be here in a year when something breaks at 2am. For a product that earns money every day, the second one is what you actually want. I take a maximum of about two long-term clients at a time, so the ones I have get a partner who knows their codebase, not a vendor rotating through a queue.
What you get before you spend anything
Before any retainer starts, I read your codebase and give you a map. The map tells you what is stable, what is fragile, where the risk lives, and what I would do first. It is honest about what I would leave alone, because the goal is not to touch everything, it is to touch the right things in the right order.
That map is the thing that turns “what will it cost” from a guess into a plan. You do not commit to months of work to find out whether your app can be saved in place. You find that out first, on a small engagement, and then you decide. If you want to see what this looks like finished, I wrote up how I took a legacy SaaS from a 4.5 to an 8.0 without a rewrite.
Frequently asked questions
Is modernizing cheaper than rewriting a legacy PHP app? In almost every case, yes. A rewrite pays to rebuild features that already work and leaves you maintaining two systems until it ships. Modernizing in place keeps the product earning the whole time and preserves years of edge cases you would otherwise have to rediscover. The rewrite’s clean fixed price hides the cost of lost ground.
How do you price a modernization engagement? I price it as a fixed monthly retainer, not a fixed project quote. A retainer keeps my incentives on your product’s long-term health rather than on hitting a milestone and leaving. It is the same model behind my multi-year partnerships, some running a decade or more.
Why can’t you just give me a fixed number up front? Because the honest cost depends on the state of your code, and I can only know that after I read it. Anyone who quotes a fixed number for legacy work before reading the codebase is guessing, and you pay for that guess later. I read the code first and give you a map, then we price the real work.
How long does modernization take? It depends on how stable the app is and how much lacks tests, but the work happens in small safe steps that ship continuously, so you see value in the first weeks, not at the end of a long project. There is no big-bang release date to wait for.
Do you need existing tests to start? No. If there are no tests, I add them at the seams before changing anything, so a fix in one place cannot break another. That coverage is part of the early work and it pays for itself the first time it catches a regression.
What about an incremental or MVP rewrite instead? An incremental rewrite that keeps the product running while you replace it piece by piece is not the risky thing, it is modernization, and it is exactly what I recommend. It has a name, the strangler fig pattern. The rewrite I argue against is the big-bang one, where you stop the world, rebuild everything, and switch over at the end. The moment a rewrite happens in small safe steps alongside the live product, it stops being a bet and becomes the safe path.
The takeaway
The real cost of a legacy PHP app is not the modernization. It is the year you spend rewriting it and the ground you lose while you do. Read the code first, fix it in place, keep earning. That is the cheap option, it just does not come with a scary fixed quote attached.