A Magento 2 upgrade is not a button click. It is a Composer-driven code and database update that has to be done on a staging copy first, because the server stack, your extensions and your custom code all have to be compatible with the target version. The short version: audit, clone to staging, align PHP, MySQL and OpenSearch, run composer require-commerce and composer update, then setup:upgrade, compile, deploy static content, test everything, and only then repeat on production with a rollback ready. This is the process I follow for Magento Open Source and Adobe Commerce 2.4.x.
Step 1: the pre-upgrade audit
Most failed upgrades I am called in to fix failed before anyone ran a command, because nobody knew what was installed. Before touching anything, I record:
- Current version:
bin/magento --version. - Target version and its release notes, especially backward-incompatible changes. Going several minor versions at once (say 2.4.3 to 2.4.8) is fine with Composer, but you inherit every breaking change in between.
- Every third-party module:
bin/magento module:statusplus therequireblock ofcomposer.json. Modules copied intoapp/codeby hand are the ones that bite, because Composer cannot check them. - Custom code: your own modules, theme overrides of core templates, and plugins or preferences on core classes.
- Server stack: PHP version and extensions, MySQL or MariaDB, OpenSearch or Elasticsearch, Redis or Valkey, RabbitMQ, Composer version.
On Adobe Commerce, Adobe's Upgrade Compatibility Tool (bin/uct upgrade:check) scans custom code against the target version and reports deprecated or removed APIs. It saves hours on a heavily customized store.
Step 2: check PHP, MySQL and OpenSearch compatibility
The server stack is the most common blocker for an Adobe Commerce upgrade. At the time of writing, these are the main requirements for recent releases (always confirm against Adobe's official system requirements page, because patch releases add and drop versions):
| Version | PHP | Database | Search | Composer |
|---|---|---|---|---|
| 2.4.6 | 8.1, 8.2 | MySQL 8.0, MariaDB 10.6 | OpenSearch 2.x (Elasticsearch 8 still supported) | 2.2+ |
| 2.4.7 | 8.2, 8.3 | MySQL 8.0, MariaDB 10.6 | OpenSearch 2.x (Elasticsearch deprecated) | 2.7+ |
| 2.4.8 | 8.3, 8.4 | MySQL 8.4, MariaDB 11.4 | OpenSearch 2.x only | 2.8+ |
Two practical points. First, change the stack on staging before upgrading Magento, and only in combinations both the old and new versions tolerate, otherwise you can end up with a store that runs on neither. Second, if you are still on Elasticsearch, plan the move to OpenSearch as its own step: install OpenSearch, switch the engine, reindex, and confirm search works before starting the Magento upgrade itself.
bin/magento config:set catalog/search/engine opensearch
bin/magento config:set catalog/search/opensearch_server_hostname localhost
bin/magento config:set catalog/search/opensearch_server_port 9200
bin/magento indexer:reindex catalogsearch_fulltextStep 3: sort out extension compatibility
For each third-party extension, find the version that supports your target Magento release and update its constraint in composer.json. Vendors usually publish a compatibility matrix. Where there is no compatible version, you have three choices: replace it, remove it if the feature is now in core, or patch it yourself. Abandoned extensions are the real cost of a magento upgrade checklist, and it is better to find them now than halfway through a failed composer update.
Also check your custom theme. Overridden core templates (.phtml files copied into your theme) do not receive upstream fixes, so diff them against the new core versions.
Step 4: clone to staging and take backups
Clone production to a staging server running the target stack: code from Git, a fresh database dump and a copy of pub/media. Point staging at sandbox payment and shipping credentials, disable outgoing customer email, and block it from search engines.
mysqldump --single-transaction --quick --routines --triggers magento_db | gzip > magento-pre-upgrade.sql.gz
git tag pre-upgrade-2.4.6
cp composer.json composer.json.bak
cp composer.lock composer.lock.bakThe same backups get taken again on production right before the real upgrade. Without a database backup, there is no rollback, because setup:upgrade changes the schema.
Step 5: the Composer upgrade commands
This is the core of any upgrade Magento 2.4 job. Put the store in maintenance mode and stop cron and queue consumers so nothing writes to the database mid-upgrade:
bin/magento maintenance:enable
crontab -e # comment out the Magento cron lines
bin/magento deploy:mode:showInstall Adobe's root update plugin, which provides the require-commerce command. It updates the root composer.json metapackage and the related dependency constraints for you, which is much safer than editing them by hand:
composer require magento/composer-root-update-plugin ~2.0 --no-update
composer update magento/composer-root-update-pluginThen require the target version. For Magento Open Source:
composer require-commerce magento/product-community-edition 2.4.8 --no-updateFor Adobe Commerce, use magento/product-enterprise-edition instead. For a security patch on the same line, use the patch version, for example 2.4.7-p5. Now update your extension constraints in composer.json and run the actual update:
composer updateIf Composer reports conflicts, read them from the bottom up. Nearly always the message names a third-party package that requires an older magento/framework or PHP version. Fix that constraint and run it again. Do not reach for --ignore-platform-reqs to force it through; that just moves the failure to runtime.
Step 6: setup:upgrade, di:compile and static content deploy
With the new code in place, clear generated files and run the upgrade:
rm -rf var/cache/* var/page_cache/* var/view_preprocessed/* generated/code/* generated/metadata/*
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f en_US
bin/magento indexer:reindex
bin/magento cache:flushsetup:upgrade applies schema and data patches for core and every module. setup:di:compile generates interceptors and factories and is where incompatible custom code usually surfaces as a fatal error, so read its output carefully. For static content deploy, list every locale your store views use (for example en_US de_DE). The -f flag forces deployment outside production mode; in production mode you can drop it.
Check that no module is left pending, then bring the store back:
bin/magento setup:db:status
bin/magento --version
bin/magento maintenance:disableRe-enable cron afterwards. A common post-upgrade surprise is a store that looks fine but has stale indexes and unsent emails because cron was never turned back on.
Step 7: test like a customer, then like an admin
On staging, before production, I test at least:
- Browse, search, layered navigation and product pages with configurable and bundle products.
- Cart, coupons, shipping rates, tax, and a full checkout with every payment method in sandbox mode.
- Customer registration, login, password reset and transactional emails.
- Admin: create and invoice an order, issue a credit memo, edit products, run imports.
- Integrations: ERP, PIM, feeds, marketplaces and anything talking to the REST or GraphQL API.
- The logs:
var/log/exception.log,var/log/system.logand the PHP error log should be quiet.
Only when staging passes do I schedule the production run, in a low-traffic window, with the exact commands already proven. Ideally production is not upgraded in place at all: the code is built in CI and deployed as an artifact, as described in my GitHub Actions deployment guide, and only setup:upgrade runs against the live database.
Step 8: the rollback plan
Write it down before you start. If production breaks and cannot be fixed within the maintenance window:
- Keep maintenance mode on.
- Restore the code to the pre-upgrade Git tag, along with
composer.json,composer.lockand thevendordirectory (or redeploy the previous build artifact). - Restore the pre-upgrade database dump. Rolling code back without the database does not work, because the schema and patch records now belong to the new version.
- Revert any server stack changes made that night.
- Clear caches and generated code, disable maintenance and check orders placed before the window are intact.
Any orders taken on the new version between go-live and rollback will be lost by the database restore, so decide in advance how long you are willing to run before rolling back, and export those orders first.
When it is worth getting help
A clean store with a handful of well-maintained extensions can be upgraded in a day using the steps above. It is worth bringing someone in when you are several versions behind, run Elasticsearch or an old PHP version, have modules in app/code nobody remembers writing, or cannot afford a failed night. My Magento development service covers upgrades end to end: audit, stack changes, extension fixes, staging and a production run with a tested rollback. If the server itself needs rebuilding for the new PHP and OpenSearch versions, that falls under server setup and configuration. Upgrades are quoted as a fixed price agreed in writing after the audit; small fixes are $20/hour. For moving the store to a new server at the same time, see my guide to migrating without downtime, and talk to me about a Magento 2 upgrade if you want it handled.
Frequently asked questions
How long does a Magento 2 upgrade take?
A patch release on a clean store can take a few hours. A minor-version jump with a server stack change, several extensions to update and custom code to fix usually takes several days of work, most of it in auditing and testing rather than running commands.
Can I skip versions when upgrading Magento 2?
Yes. Composer can take you directly from, say, 2.4.4 to 2.4.8 without installing each version in between. You do still need to handle every backward-incompatible change and stack requirement between the two versions.
Do I need to upgrade Magento for security patches?
Yes. Adobe publishes security patch releases (the -p versions, such as 2.4.7-p5) for supported release lines. Once a line reaches end of support it stops getting security fixes, which is a strong reason to stay on a supported version.
Will a Magento upgrade break my theme?
It can. Themes that override core templates or rely on removed JavaScript or LESS files may break. Luma-based themes with light customization usually survive; heavily customized or third-party themes need their vendor's compatible version and a careful review on staging.