If you own a PHP application that has been running for years, you have probably been quoted a number for "modernizing" it and wondered what is inside that number. The honest answer is that legacy PHP application modernization cost depends far more on how the system is built than on how big it is. Two applications with the same number of screens can differ by a factor of three or four in effort.

This article explains what actually moves the price, how I size a modernization before anyone commits budget, and how to phase the work so you are never betting everything on a single estimate. I am not going to give you a single magic figure, because any number without an audit behind it is a guess.

What "modernization" actually means#

People use the word for very different jobs, and the price follows the job:

  • Version upgrade: moving to a supported PHP version and a current framework release, with the existing structure kept.
  • Refactor in place: adding tests, extracting business logic from templates, and cleaning up the data layer without changing what users see.
  • Strangler-style migration: replacing the application piece by piece behind the same URLs, usually onto Laravel, while the old code keeps running.
  • Full rewrite: building a new system and cutting over.

Most buyers want the outcome of a rewrite at the price of an upgrade. The useful question is which of these four your business problem actually needs. If the pain is that the server runs an unsupported PHP version, you do not need a rewrite. If the pain is that every change breaks something else, an upgrade alone will not fix it. This is the kind of question my legacy application modernization service starts with. I cover that decision in more depth in rewrite vs refactor for a legacy application.

The five factors that drive cost#

1. Test coverage (or the lack of it)#

This is the biggest single driver. An application with a decent automated test suite can be upgraded and refactored safely, because the tests tell you what broke. An application with none means every change needs manual verification, and manual verification is slow and expensive. Often the first piece of paid work should be building characterization tests around the riskiest flows, such as checkout, billing or anything that moves money.

2. How logic is organised#

Business rules buried in templates, in SQL strings, or in a 4,000-line include file are expensive to move. Code that already has clear boundaries (even if the style is dated) costs much less. When I audit a system I look for where the rules live, not how pretty the code is.

3. The database#

Schemas that have grown without constraints, with duplicated data and unclear ownership, create most of the nasty surprises. Migrating code is predictable. Migrating data you do not fully understand is not. Reviewing the schema early is the cheapest risk reduction available.

4. Dependencies and integrations#

Old Composer packages that were abandoned years ago, payment gateways on retired API versions, and hand-rolled integrations all need attention. Each external system is a small project of its own.

5. Downtime tolerance#

If the business can accept a maintenance window, cutover is simple. If it cannot, you need parallel running, feature flags or a strangler approach, and that adds engineering time.

🛠 Engineering Service

Need specialized help with Legacy Application Modernization?

Modernize aging PHP and Laravel applications without disrupting existing business operations, improving architecture, performance, security, and maintainability.

Discuss Architecture →About this service

How I size a modernization before quoting it#

A reliable estimate comes from an audit, not from a sales call. On the freight-forwarding platform audit, I was brought in to review a nearly finished Core PHP and MySQL system before further development. The work was understanding first: auditing operational workflows, reviewing the database structure, assessing frontend maintainability, mapping dependencies and evaluating configuration and environment governance, then assessing the path towards a future Laravel migration. The point of that phase was to replace assumptions with a written map.

A good audit typically produces:

  1. An inventory of modules, routes and external integrations.
  2. A risk list ranked by business impact, not by code ugliness.
  3. A proposed phase plan with a rough effort band for each phase.
  4. A clear list of what is out of scope.

Ask for this before you accept a fixed quote. If a vendor quotes a firm price without seeing the code, either the price includes a large safety margin or the scope will change later.

Phase the work so the budget stays honest#

Instead of one big project, split the engagement into stages with a decision point after each:

Phase Typical focus What you get
0. Audit Read-only review of code, database, hosting Written map, risks, phased estimate
1. Stabilise PHP version, security patches, backups, monitoring A system that is safe to keep running
2. Safety net Tests around critical flows, CI pipeline Confidence to change things
3. Modernise Framework upgrade or incremental migration Maintainable core
4. Improve New features on the new foundation Business value

You can stop after any phase and still have something useful. That is the main protection against a modernization that runs over budget and delivers nothing until the end.

💡Tip

If a quote jumps straight to phase 3 or 4 without phases 0 to 2, ask what the plan is for verifying that behaviour did not change.

Where budgets usually go wrong#

  • Treating the audit as optional. Skipping it moves the discovery cost into the build, where it is more expensive.
  • Changing scope mid-flight. Adding features during a migration doubles the testing burden.
  • Underestimating data work. Cleaning and migrating data is often a quarter or more of the effort and rarely appears in first estimates.
  • No owner on the business side. Decisions about which legacy behaviours to keep need someone who can answer quickly.
  • Forgetting the run cost. A modernized system still needs hosting, monitoring and maintenance. I wrote about that in what to budget for software maintenance.

When modernization is the wrong answer#

Sometimes the right call is to leave the system alone. If the application is stable, low-risk, rarely changed and on a supported PHP version, spending money to rewrite it creates risk without business benefit. Put the budget into backups, monitoring and security patching instead. Modernize when the code is blocking something you care about: shipping features, passing a security review, hiring developers, or integrating with newer systems.

Also check the version situation first. The PHP supported versions page shows which releases still get security fixes, and the Laravel release notes show the support window for each framework version. If you are far behind, an upgrade path such as the one in my Laravel upgrade checklist is often cheaper than people expect, because it is mostly mechanical. Tools like Rector automate a good share of the syntax changes.

Frequently asked questions#

How long does a legacy PHP modernization take?#

It depends on the route. A version upgrade with good tests can take weeks. A staged migration of a business-critical system usually takes months, because the old and new code run side by side. An audit will give you a realistic band.

Can the site stay online during modernization?#

Yes, if the work is planned for it. The strangler pattern, described well on Martin Fowler's site, replaces functionality gradually so users never see a cutover day.

Is Laravel the right target?#

Often, but not always. Laravel suits most business applications because of its conventions, queue system and ecosystem. The right target is whatever your team can maintain. I walk through one real move from Core PHP in migrating a legacy Core PHP platform to Laravel.

Should I rewrite instead?#

Only if the existing system cannot be understood or safely changed and the business logic is small enough to re-specify. Rewrites hide risk until late in the project.

Key takeaways#

  • Cost is driven by test coverage, code organisation, data quality, integrations and downtime tolerance, not by page count.
  • Pay for an audit first. It converts guesses into a phased estimate.
  • Phase the work so you can stop at any stage with something usable.
  • Do not modernize stable, low-risk systems for the sake of it.

If you want a sized, phased plan for your own application, you can book a call or send the details through the contact page. That is exactly how an engagement with me begins.

Originally published at aqibjavaid.site.