Reference Guide · Laravel

Laravel Upgrades for Long-Lived Systems

“Still running in ten years” is only credible if you can keep a system current without dreading it. Why upgrades don't fail because of the framework but because of postponement — and how to turn them into a calm routine instead of a dreaded leap. A decision document for CTOs, lead developers and senior engineers.

What is this? · Reference Guide

A solid guide to an engineering question — with trade-offs, costs and the case in which we decide differently. Not an opinion piece, but a reference text. Go to overview

Author
Batunet Engineering
Reading time
16 min
Level
In depth
Status
Approved
Last reviewed
21 July 2026
Updated
21 July 2026
On this page

The promise of long-lived software — that a system will still be running in ten years — stands or falls with an inconspicuous capability: keeping it current. A framework evolves whether you go along or not, and a system that stands still while its foundation moves on does not become long-lived, just old. That is why the upgrade question is not a technical footnote but the practical core of longevity. Anyone who promises that a system will carry a decade must be able to say how it gets through the years without being put at risk at every step.

This document discusses this strategy using Laravel as the example, but its core is not specific to Laravel. It presupposes the general principles of long-lived systems covered elsewhere — separating the business domain from the framework, working in small reversible steps — and applies them to the concrete question of how to keep the framework current over the years. It deliberately avoids version numbers, because it is about a stance, not a snapshot.

1. Why upgrades are frightening

The fear of upgrades is real and has an understandable reason: you are changing something load-bearing in a running system, and you don't know for sure what will break. An upgrade touches the foundation everything stands on, and the thought that afterwards something will no longer work — something you might not notice right away — makes many teams avoid updating for as long as they possibly can. The system is running, after all; why take the risk?

This fear is understandable, but it is aimed at the wrong target. It is not the upgrade that is dangerous, but the system that has been allowed to reach a state in which an upgrade is dangerous. A system whose business logic is tightly interwoven with the framework, that has no safety net and has not been updated in a long time turns every upgrade into a leap into the unknown. A differently built system turns the same upgrade into a routine. So the fear is not an argument against upgrades, but a symptom of how the system was built and maintained.

Postponement also has a price that has nothing to do with the upgrade itself: a system stuck on an old version gradually loses touch with the ecosystem around it. Libraries it relies on align with the current version; tools, help and knowledge move on over time. And at some point an old version stops receiving security fixes — which means known vulnerabilities stay open, vulnerabilities you yourself know about. Standing still is therefore not preserving a good state, but slowly drifting away from a living environment.

Trade-off. Taking the fear seriously and fixing its cause means investing in upgradability before the benefit shows — work that seems superfluous during calm operation.

Cost. Making a system upgradable — decoupled, safeguarded, current — takes effort that contributes nothing visible to its functionality.

When we decide differently. For a system that will foreseeably be short-lived and switched off soon anyway, investing in upgradability does not pay off; its value grows with the expected lifespan.

2. The real cause: postponed upgrades

The most common reason an upgrade becomes dangerous is that it was postponed. Every skipped update widens the gap between your system's version and the current one — and that gap is the real danger. A small step from one version to the next is manageable; a leap across many skipped versions at once piles all the changes, all the breaks, all the adjustments into a single, unwieldy operation. What was intended as caution — better not touch it — creates exactly the risk you wanted to avoid.

continuous: many small steps postponed: one big leap Risk

Diagram: the same distance — covered in many small steps or pent up into one big leap. The pent-up leap concentrates the risk that the small steps would have spread out.

This leads to the central insight: upgrade debt behaves like any debt — it grows as long as you don't service it, and becomes harder to pay off over time. Keeping a system current is therefore not an occasional feat of strength but ongoing maintenance that keeps the gap small. Whoever takes small steps regularly never has a big one to fear; whoever waits until they have to has brought about the very leap they wanted to avoid.

Trade-off. Servicing upgrades continuously buys the avoidance of the big leap with a steady, small burden that never quite disappears.

Cost. Regular maintenance continuously ties up some capacity that delivers nothing new — paid-for prevention against a failure that would otherwise hit later and cost more.

When we decide differently. Where a system is being frozen — shortly before shutdown, with no new requirements — you can deliberately stop upgrading; as long as it lives and evolves, ongoing maintenance is the cheaper path.

3. Continuous instead of in leaps

The nature of upgrade debt dictates the strategy: continuous instead of in leaps. You take each step as soon as it is available, in small, manageable updates, instead of accumulating many and catching up in one big effort. Each small step is manageable on its own — you see what changes, check it, move on. Over the years, these small steps add up to a system that is always close to the current version without ever having made a dreaded leap.

This continuity has a side effect that increases its value further: it keeps knowledge fresh. A team that updates regularly knows the changes while they are small and keeps learning the framework as it evolves; a team that waits for years faces a pile of accumulated innovations it has to understand all at once. Continuous maintenance is therefore not only technically safer but also easier for the people — it spreads not only the risk but also the learning. What stays self-evident in small doses becomes overwhelming in a flood.

The value of continuity also grows with habit. A team for which upgrades have become routine does them without fuss — they are a natural part of the work, like tidying up after a job is done. A team for which every upgrade is an event has to muster courage and preparation anew every time. Routine takes away not only the risk of the upgrade but also its weight: what you do often, you do easily. That is how a dreaded exception becomes a calm rule, and the fear dissolves into habit.

AspectContinuousPostponed
Size of the stepsmall, manageablelarge, unwieldy
Riskspread out, controllableconcentrated at the end
Team knowledgestays freshhas to be caught up
Feelingroutinedreaded leap

Trade-off. Continuous upgrades buy safety and fresh knowledge with a regular small interruption of the actual work.

Cost. You keep turning away from the new for a moment to keep the existing current — a discipline that has to be sustained against the pressure of the next feature.

When we decide differently. Where a framework itself advances in rare, large breaks and doesn't offer small steps at all, you have to plan the leap; where it offers a continuous path, that path is the better one.

4. Separating the business domain from the framework

The most effective lever for making upgrades cheap lies not in the upgrade itself but in the architecture. A system whose business logic is separated from the framework — the business rules in a framework-independent domain, the framework merely a shell around it — experiences an upgrade as a change to the shell, not the core. Whatever concerns the framework gets updated; the business logic, which knows nothing about the framework, remains untouched. This shrinks the surface an upgrade can touch at all to a fraction.

The upgrade touches here Framework shell Business core (framework-independent, untouched)

Diagram: an upgrade touches the shell, not the core. The more clearly the business logic is separated from the framework, the smaller the surface an upgrade can reach at all.

This reveals a seeming framework question to be an architecture question. How expensive upgrades are depends far less on how the framework changes than on how tightly your own system is bound to it. A system that has written its business logic into controllers and models feels every upgrade in its full extent; a system with an independent core feels it only at the shell. Upgrade costs are therefore, like maintainability in general, a property of your own architecture — not a fate imposed by the framework.

Makes upgrades cheapMakes upgrades expensive
business logic separated from the frameworklogic in controllers and models
small, current gap to the latest versionlarge, pent-up gap
deprecations worked off continuouslywarnings ignored
behavior safeguarded by testsno safety net, just hope

Trade-off. Separating the business logic buys cheap upgrades with the effort of a domain layer that you build and maintain from the start.

Cost. This separation requires discipline and more experienced developers and only pays off over the lifespan — in the first quarter it looks like over-engineering.

When we decide differently. For a short-lived system that is rarely or never updated, the separation is over-engineered; its value grows with the number of upgrades the system goes through over the years.

5. Deprecations as an early-warning system

A well-maintained framework announces changes before it enforces them: whatever will go away or change in the future is marked as deprecated for a while before it actually disappears. This advance warning is a gift that many teams leave unused. Whoever takes deprecation notices seriously and gradually replaces what is marked while the old still works spreads the work of a future upgrade over the time before it — and, when the old finally goes away, has long since moved to the new. The upgrade itself is then merely confirmation of what you have already done.

Whoever ignores the warnings, on the other hand, accumulates them until their expiry forces the issue — and experiences all at once during the upgrade what could have been spread over months. Treating deprecations as an early-warning system is therefore the practical side of continuous maintenance: you work off the announced changes while they are still optional, instead of waiting until they become mandatory. That way the dreaded upgrade becomes a calm step, because the real work is already done before it comes due.

A well-maintained framework does not leave you alone with this work. It usually makes visible what is deprecated and offers ways to find and replace the outdated — aids that accompany the path from one version to the next. Taking this support seriously and using it, instead of groping blindly through the changes, is part of the strategy: you follow the mapped-out path the framework offers instead of searching for it yourself. Whoever uses the help provided makes an upgrade less a piece of detective work and more an orderly checklist.

Trade-off. Working off deprecations continuously buys calm upgrades with steady small work on things that still function today.

Cost. You change working code because it will go away in the future — effort that seems unnecessary in the moment and whose benefit only becomes visible at the later upgrade.

When we decide differently. Where something marked will foreseeably only go away in the distant future and its replacement is expensive, you may wait and bundle it; continuous work-off pays for what will go away soon or can be replaced with little effort.

6. Tests as a safety net for upgrades

What turns an upgrade from a leap into the unknown into a controllable change is the ability to know afterwards whether everything still works. Tests provide that ability — not as an end in themselves, but as the net that safeguards an upgrade. A system whose important behavior is pinned down by tests can be updated and then checked for whether something has shifted that should not have. A system without this safeguard has to hope after every upgrade — and only learns of a break when a user reports it.

This closes the circle with the other levers. Separating the business logic keeps the surface an upgrade touches small; continuous maintenance keeps the steps small; deprecations warn of what is coming; and the tests confirm that the step succeeded. Together they transform the upgrade from something dreaded into something routine. None of these levers is specific to Laravel; they are the general answer to the question of how a system gets through the years — applied here to keeping the framework current. Which behavior the tests should safeguard is a separate, careful question.

It is worth realizing that these four levers reinforce one another. A decoupled core keeps the surface small, but without tests you still don't know whether the small remainder holds; continuous steps keep the gap small, but without heeding warnings you still run into avoidable breaks. Only together do they produce the calm, continuous currency that none achieves alone — and the absence of a single one is often enough to turn the upgrade back into a dreaded leap.

Trade-off. Tests as an upgrade net buy safety with the effort of safeguarding the important behavior and maintaining that safeguard.

Cost. Test coverage that genuinely carries an upgrade is work you sustain over the lifespan, not something you write once and forget.

When we decide differently. Where the behavior is trivial and the damage of an unnoticed break is small, a lean safeguard is enough; the full net is for behavior whose silent breakage would be expensive.

7. Common mistakes

The recurring patterns in which keeping current fails — almost all of them variations of fearing the upgrade instead of fixing its cause:

  • Postponing upgrades out of fear of breakage, thereby creating exactly the dangerous leap you wanted to avoid.
  • Letting upgrade debt grow until the gap to the current version makes every step risky.
  • Considering the upgrade dangerous, rather than the system you allowed to reach an upgrade-hostile state.
  • Writing the business logic into the framework and thus feeling every upgrade in its full extent instead of only at the shell.
  • Ignoring deprecation warnings and accumulating the work until expiry forces a leap.
  • Updating without a safety net and only learning of a break when a user reports it.
  • Blaming upgrade costs on the framework instead of recognizing them as a property of your own architecture.

8. Decision checklist

To be clarified in order for keeping a long-lived Laravel system current:

  • Cause or symptom? Is the fear of upgrades being addressed at its cause — coupling, missing safeguards, pent-up debt — instead of avoiding the upgrade?
  • Continuous? Are upgrades taken continuously in small steps instead of being accumulated into big leaps?
  • Business logic separated? Does the business logic live in a framework-independent domain, so that an upgrade touches the shell, not the core?
  • Deprecations worked off? Are announced changes replaced while the old still works, instead of waiting until forced?
  • Net in place? Do tests safeguard the important behavior, so that after an upgrade you know whether everything still works?
  • Capacity planned? Is ongoing maintenance planned as a fixed item, not as an occasional feat of strength?
  • Framework or architecture? Has it been recognized that upgrade costs depend more on your own architecture than on the framework?

Whoever can answer these questions keeps their system current without dreading it — and makes the promise of longevity credible.

FAQ

Why are upgrades so dreaded? Because you are changing something load-bearing in a running system and don't know for sure what will break. But the fear is aimed at the wrong target: it is not the upgrade that is dangerous, but a system that has been allowed to reach a state in which an upgrade is dangerous — tightly coupled, unsafeguarded, not updated for a long time. Fix that cause, and the upgrade becomes routine.

Isn't it safer not to touch a running system? No, it is more dangerous. Every skipped update widens the gap to the current version, and that gap is the real danger. Whoever waits until they have to has brought about the big leap they feared. Keeping a system current is the more cautious choice, not the riskier one.

Why are small, continuous upgrades better than rare, large ones? Because they spread the risk and the learning. A small step is manageable; a leap across many skipped versions bundles all the changes into one unwieldy operation. Continuous maintenance also keeps the team's knowledge fresh, while the big leap demands understanding a great deal of accumulated change all at once.

What really makes upgrades cheap? Separating the business logic from the framework. If the business logic lives in an independent core, an upgrade only touches the shell, and the surface it can reach shrinks to a fraction. Upgrade costs are therefore less a property of the framework than of your own architecture — a system with an independent core is cheap to update, one with interwoven logic is expensive.

Why heed deprecation notices when everything still works? Because they announce future work while it is still optional. Whoever replaces what is marked while the old still works spreads the work of an upgrade over the time before it and, when the old goes away, has long since moved to the new. Ignore the notices, and you accumulate them until their expiry forces a leap.

Are tests really necessary in order to upgrade? They are the net that turns an upgrade from a leap into the unknown into a controllable change. With the important behavior safeguarded, you know after the upgrade whether something has shifted; without it, you have to hope and only learn of a break from a user. For a system meant to get through the years, this net is hardly dispensable.

Further reading

It is grounded in the Batunet Engineering Method: separate the business domain from the framework, keep current in small reversible steps, safeguard for failure.

Closing engineering principle

A system does not stay long-lived by being left alone, but by being kept in motion. The standstill that feels like safety is in truth a slow drift away from the foundation the system stands on — and the longer you maintain it, the more dangerous the step back to the current version becomes. The art of keeping current is therefore not an occasional feat of strength but a calm, steady habit: small steps, a decoupled core, heeded warnings, a net of tests. Whoever cultivates it need not fear upgrades — and thereby makes good on the promise that makes long-lived software credible in the first place: that in ten years it will not only still run, but still be alive.


To dread a system you have to update is to have built a system you cannot update. The fear of the upgrade is always a message about your own system, never about the upgrade itself.

Referenced entities

Knowledge graph

Continue your engineering journey.

Related concepts, decisions, playbooks and perspectives — as one connected path, not a list of links.

A concrete project in this field?

Reference Guides show how we think. For your system, talk to our management — technical, no sales pitch.