All services

Symfony upgrade

Symfony, branch by branch. Without the leap in the dark.

The maintained branches at the moment are 6.4, 7.4, 8.1 and 8.2. Symfony 5.4 gets security fixes only; everything below it and the branches 6.0 to 6.3 and 7.0 to 7.3 get nothing at all. The route there does not run through one big jump but through a sequence of small ones: clear the deprecations, then one major version further, then start again. That is unspectacular, and it is the only route where you always know where you stand.

5.4 → 6.4 → 7.4Rector and deprecationsNo downtimeFrom 950 €
What you get
  • An inventory: target branch, intermediate steps, the PHP version each one needs
  • A list of the deprecations, sorted by effort and by location
  • The bundles checked: what exists for the target branch, what has to be replaced
  • The upgrade branch by branch, every step live on its own
  • A test net around the places that get touched
  • Handover to your team, in writing and in conversation
Scope & working together

The entry point is a fixed-price assessment, implementation is quoted by scope. Also for applications without tests and without the people who built them.

Remote from Germany. Straight with me, no agency in between.

The starting point

The effort does not sit in Symfony.

Symfony itself is the predictable part of an upgrade, because the project keeps a backward compatibility promise: whatever is to go is marked as a deprecation in a minor release and only removed with the next major. Anyone who works through those messages on the last minor before jumping has most of the jump behind them. Parts marked internal or experimental are excluded, as are security fixes, and there it can break without warning.

The problem is the bundles. A project with fifteen dependencies has fifteen separate timetables, and if one of them has not seen a commit in four years it holds the whole application still. On top of that comes your own code that relied on internals: an overridden service, an event listener at a point that no longer exists later, a configuration in a format that was dropped three versions ago.

And underneath all of it sits the language version. Symfony 6.4 requires at least PHP 8.1, 7.4 at least 8.2, the 8.x line at least 8.4. So anyone sitting on PHP 7.4 is facing two projects, not one. Which comes first is decided by the assessment, not by instinct.

Does any of this sound familiar?
  • The application runs on Symfony 5.4 or older and no longer gets bug fixes.
  • Composer reports conflicts as soon as a single dependency is raised.
  • The log is full of deprecation messages nobody reads any more.
  • A bundle is no longer maintained and blocks the whole jump.
  • An earlier upgrade attempt was abandoned and is still lying around as a branch.
  • The PHP version does not match the Symfony branch you want.

Who this is for

For Symfony teams that must keep shipping while the framework catches up.

For CTOs and tech leads with a productive application on an older Symfony release. Product work continues while security support and compatible packages become scarce.

01

The application keeps evolving.

The system remains relevant and delivery cannot pause for a long upgrade programme.

02

Dependencies define the effort.

Bundles, extensions and old libraries need an evidence-based order rather than one version jump.

03

Every branch should remain deployable.

Tests, deprecations and small releases create a controlled path to a supported target.

What I do

What happens along the way

01

Set the target branch and the order

InventoryComposer analysisPHP matrix

Not everyone jumps to the newest release. Anyone on 5.4 today sensibly goes via 6.4 to 7.4, and whether the 8.x line is the target hangs on whether PHP 8.4 is within reach. The result is a chain of intermediate steps, each with its own prerequisite.

02

Clear the deprecations before the jump

Deprecation logRectorPHPStan

Deprecations accumulate over the lifetime of a major version. Those messages get collected, sorted by frequency and effort, and worked through while still on the old major. This is the part that makes the actual upgrade small: every change can be rolled out on its own while the application keeps running on the current version. It is not risk-free, production code gets touched, but it breaks down into small steps you can check one at a time.

03

Check and replace the bundles

ComposerReplacing abandoned packagesAnti-corruption layer

Per dependency: does it exist for the target branch, is it still maintained, and what takes its place if not. Abandoned bundles get a maintained alternative, a narrow implementation of what is actually used, or a boundary behind which they carry on encapsulated.

04

A safety net where tests are missing

PHPUnitCharacterization tests

Where no tests exist, characterization tests go in for the paths that get touched and that money hangs on. They record what the application does today, regardless of whether that is right.

05

One major version after another

Staged rolloutA way back per step

Every branch is a step of its own with a way back of its own, and each one goes into production separately. Taking two major versions in one go saves time on paper and hands it back at the first fault, because nobody can say which jump it came from any more.

06

Afterwards: do not fall behind again

CI checksDependabotMaintenance plan

At the end, the things that keep the gap small in future: deprecation messages as errors in the pipeline, static analysis, automated dependency checks, and a note of when the branch you picked now drops out of maintenance.

Is your Symfony sitting on an unmaintained branch?

Send me the key facts. You get the chain of intermediate steps and the effort before you commission anything.

How it runs

How this runs

Four steps, and after the first one you know the route and its stops along the way. No step assumes that you commission the next one.

STEP 01

Key facts and access

Symfony version, PHP version, rough size, test coverage, list of bundles. Read access to the repository is enough for the assessment.

STEP 02

Assessment

Target branch, intermediate steps, deprecations by effort, bundles by replaceability. That is enough for you to decide, including against me.

STEP 03

Clear up and secure

Work through the deprecations on the current branch, put the test net in place. Both happen before the first version number goes up.

STEP 04

Roll out branch by branch

One jump, one rollout, one way back. At the end checks in the pipeline and the handover.

Entry offer

First upgrade step. From 950 €

Starting price for the assessment. Implementation is quoted by scope, at a fixed price, before it begins.

The entry point is an assessment, not an implementation: you find out which intermediate steps the route runs through and what each of them costs.

What you get

  • The target branch and the chain of intermediate steps, with the PHP version each stage needs
  • The deprecations collected, sorted by frequency and effort
  • A bundle check: available, maintained, replaceable
  • A list of the places where your own code sits on internals
  • An assessment of test coverage and the safety net needed
  • One hour discussing the results, recorded on request

What you do not get

  • No implementation of the upgrade, no refactoring, no new features
  • No PHP upgrade, that is a project of its own with a page of its own
  • No review of the infrastructure, the AWS cost analysis covers that
  • No security review in the sense of a penetration test
  • Read access to the repository is enough, production access is not needed
  • Price excludes VAT
  • From around 200,000 lines or several applications the scope is agreed beforehand
  • The amount is credited if you commission the implementation afterwards
  • You are under no obligation. Some clients implement the assessment themselves, and that is a valid outcome

The outcome

What is different afterwards

Maintained again

Bug fixes and security fixes come back, and the question in the next audit is answered.

Dependencies that move again

A new package can be installed without three others blocking it. That was the real standstill before.

The next jump is small

With deprecations as errors in the pipeline nothing piles up any more. The next major jump is then routine rather than a project, because the work happened along the way instead of all at the end.

A net that stays

The tests written for the upgrade belong to you afterwards and protect every further change.

Technologies I use

What I work with

Framework
  • Symfony 6.4
  • Symfony 7.4
  • Symfony 8.1
  • Flex
Components
  • Doctrine ORM
  • Twig
  • Messenger
  • Security
  • Console
Language
  • PHP 8.1
  • PHP 8.2
  • PHP 8.3
  • PHP 8.4
Analysis
  • Rector
  • PHPStan
  • Psalm
  • PHP-CS-Fixer
Tests
  • PHPUnit
  • Panther
  • Pest
  • Xdebug
Packages
  • Composer
  • Packagist
  • Composer Audit
  • Dependabot
Data
  • MySQL
  • MariaDB
  • PostgreSQL
  • Valkey / Redis
Delivery
  • Docker
  • GitHub Actions
  • GitLab CI
  • AWS

Evidence

PHP and Zend Framework certified.

Most suppliers know the destination. With an old system, what decides the outcome is whether someone also knows the starting point: why a passage is written the way it is, and what replacing it sets off. Zend Technologies no longer exists under that name, and neither do the exams of the time. For the database side there is an Oracle certification on MySQL 5, because that is where the quieter traps sit: character sets, collations and a strict mode that starts refusing what used to pass.

Zertifikat: Tim Rutte, Zend Certified Engineer PHP 5.3, ausgestellt von Zend Technologies
Zend Certified Engineer – PHP 5.3
Zertifikat: Tim Rutte, Zend Certified Engineer Zend Framework, ausgestellt von Zend Technologies
Zend Certified Engineer – Zend Framework
Tim Rutte, Cloud & Software Architect

Who you are talking to

Directly with me as a freelancer. No agency in between.

I am Tim Rutte. More than 20 years in software development, and Symfony has been with me since its early versions. You talk to the person who touches your code, from the first call to the handover.

  • 20+years in software development
  • 50+successful projects
  • 2003working remotely since then
More about me

Common questions

Common questions about the Symfony upgrade

Which Symfony versions are still maintained?

As of August 2026 the maintained branches are 6.4, 7.4, 8.1 and 8.2. Symfony 5.4 gets security fixes only, everything below it and the branches 6.0 to 6.3 and 7.0 to 7.3 get nothing at all. As a target I usually recommend the current LTS branch 7.4: long support, and the libraries have caught up with it.

Can you skip several versions at once?

Technically yes, in practice rarely sensibly. Symfony only removes things with a major version, and it announces that through the minors before it. That is exactly why the intermediate stop pays off: whoever is deprecation-free on the last minor of a major jumps almost without surprises. Taking two majors in one go skips that station twice, and after a fault nobody can say which jump it came from.

What does a Symfony upgrade cost?

The first upgrade step costs from 950 euros excluding VAT and tells you what the implementation costs. The range is wide, and it does not hang on the size of the codebase but on two other numbers: how many bundles are abandoned, and whether there are tests. Implementation is quoted at a fixed price after the assessment.

What if a bundle is no longer maintained?

That is the most common hard case. Three answers come into question: a maintained alternative doing the same job, a narrow implementation of exactly what you actually use, or a boundary behind which the old bundle carries on encapsulated until it is replaced. Which one holds is in the assessment, with the effort it carries.

Do I need a PHP upgrade first?

Often yes, because the branches set minimum versions: 6.4 needs PHP 8.1, 7.4 needs 8.2, the 8.x line needs 8.4. Changing both at once is the most reliable way to end up unable to trace a fault. Which step comes first depends on the starting point and is in the assessment.

Does the application have to be taken offline for this?

No. Working through the deprecations happens on the running branch and is invisible anyway. Every version jump after that is a rollout of its own with a way back of its own, like any other change.

We have an abandoned upgrade branch. Does it help?

Usually as a source of findings, rarely as a foundation. It shows what the last attempt failed on, and that is a valuable shortcut in the assessment. I would only carry on working on it if it is younger than a few months; otherwise the distance to the main branch is greater than the gain.

Do you do the PHP upgrade and the bundles together as well?

Yes, but as separate steps in an agreed order, not as one project. That order is exactly the part you bring someone in for: it decides whether the whole thing takes three weeks or three months.