Drupal 9 to Drupal 10 upgrade

A Drupal 9 site needs a controlled path to Drupal 10 with a clear rollback point at each stage. Drupal 10 requires PHP 8.1 or later and reaches end of life on December 9, 2026, so the upgrade also sets up the next step to Drupal 11.

On this page

What a Drupal 9 to Drupal 10 upgrade involves before Drupal 10 ends

A Drupal 9 site that is out of support needs a staged path, not a single jump. The supported sequence is to first move the site to the Drupal 9.4 or 9.5 minor release, then upgrade to Drupal 10, and then plan the immediate step to Drupal 11. The timing matters because the Drupal core release schedule gives December 9, 2026 as the end of life date for Drupal 10, so a Drupal 9 site that lands on Drupal 10 late in that window will have little time before it faces the same problem again. Before any work starts, the team should confirm the current core and contributed module versions against the Drupal core release schedule, since release timing and support dates are the inputs that set the plan.

Drupal 10 requires PHP 8.1 or later, so the server upgrade is a gating item and not an afterthought. Confirm the PHP version, the web server and the database version on every environment, including staging and the build server that runs Composer. Many contributed modules that were stable on Drupal 9 will need new releases to run on Drupal 10, and some may have been abandoned. Each one needs a named owner and a decision: upgrade, replace or remove. Sites that have drifted from their Composer lock file tend to take longer here, so a reproducible build should be in place before the first upgrade branch is cut. The work is services and labor. Drupal and its contributed projects are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself, so the cost of the upgrade sits in the people who inventory the site, fix custom code and themes, rebuild the content and configuration tests, and run the cutover. Ask any provider, including DeployOpen, for a written scope that lists the core and contributed upgrades, custom module and theme changes, environment work, testing, and the planning for the Drupal 11 step. Ask which items are one-time and which recur, such as security update routines after launch.

What changes in a Drupal 9 to Drupal 10 upgrade and what each change asks of you

This table lists the changes that matter when moving a Drupal 9 site to Drupal 10, with the action each one asks of your team. Take each entry from the Drupal 10 release notes, then confirm it against your own modules, theme, hosting and content before you schedule the work. The main takeaway is that code, contributed modules and server versions must be scoped together, because a change in one often blocks the others.

ChangeWhat it asks of youWhat to confirm in your environment
PHP 8.1 minimumRun every web and command-line host on PHP 8.1 or later before the code upgrade.PHP version on each web node, cron host and build server, checked against the PHP requirements page.
Deprecated APIs removed in the 9.x lineFix custom module and theme code that calls APIs deprecated in 9.x and removed in Drupal 10.Upgrade Status and Drupal Rector reports, plus the removal list in the Drupal 10 release notes.
CKEditor 4 replacementMove text formats to CKEditor 5 and rework toolbars, custom plugins and stored markup.Sample content with embeds, tables and custom markup in each text format, tested on staging.
Seven and Claro themesConfirm the admin theme after upgrade and rebuild any custom overrides or subthemes of Seven.The admin theme setting in the release notes, and any custom templates that depend on Seven markup.
Contributed module releases requiring Drupal 10Update each contributed module to a release that supports Drupal 10, or replace or remove modules that have none.Compatibility on each project page, Composer constraints and any modules with no Drupal 10 release.
Database and web server versionsUpgrade MariaDB, MySQL, PostgreSQL or SQLite, and Apache or Nginx, where the current versions fall below the listed minimums.Current versions against the system requirements page for Drupal 10, with the sequence agreed for server changes.
Drupal 10 end of lifePlan the next step to Drupal 11 soon after the Drupal 10 upgrade, since Drupal 10 reaches end of life on December 9, 2026.Whether the target Drupal 11 release needs PHP 8.3 and which modules still need a Drupal 11 release.

What to inventory, back up and build before the first change

Four preparation streams run in parallel before any Drupal 9 to Drupal 10 change is made. Each produces an artifact the upgrade depends on: a restorable backup, a release inventory, a production-like environment and a record of editorial workflows. Skipping one usually shows up later as a failed rollback, a surprise module conflict or content editors who cannot publish after the CKEditor 4 change.

Restorable backup of code and data

Take a full backup of the codebase, the database and the uploaded files directory, then prove it works by restoring it to a separate host. A backup that has never been restored is an assumption, not a rollback plan. Record the exact Drupal core and contributed versions in the backup manifest, and keep the Composer lock file with it so the code can be rebuilt. Confirm who approves a rollback and how long it takes to restore in your environment, since that time becomes the window you must accept during cutover.

Release inventory with target versions

List every custom module, custom theme and contributed project with its current release and the release that supports Drupal 10. Mark projects that have no Drupal 10 release, because those block the upgrade or need a replacement decision. Include the PHP version on each web node and the database engine and version. This inventory is the input for the effort estimate and for the change request your governance team will need to approve.

Production-like test environment

Build a staging environment that mirrors production in web server, PHP version, database engine, cron setup and file storage. Drupal 10 requires PHP 8.1 or later, so the test stack must run that version before the first code change is tested. Use a sanitized copy of production data so content, aliases and configuration reflect real use. Decide who owns the environment after the project ends, because the same stack is needed for the next upgrade.

Editorial workflow record

Document how editors create, format and publish content today, including every text format, embedded media, custom toolbar button and content type that uses CKEditor 4. The CKEditor 4 replacement will change how these fields behave, so the record becomes your acceptance list. Capture which roles can edit which formats and where editors rely on custom markup or shortcuts. Share the list with the content owners and agree on which behaviors must match before go-live.

The Drupal 9 to Drupal 10 upgrade sequence, with a rollback point at each step

This sequence moves an end-of-life Drupal 9 site onto Drupal 10 one controlled change at a time, so each stage has a verified state the team can return to if something fails. It finishes with a tested production cutover and a plan for the next step to Drupal 11.

  1. Restore a current backup into staging

    The team restores a full database and files backup from production into an isolated staging environment that matches production's PHP version, web server and database engine. The team confirms that the restored site loads, that cron runs and that content counts match production. The restored copy becomes the baseline. If the restore fails or drifts from production, the rollback action is to discard staging and repeat the restore from a fresh backup. Production is not touched at this stage.

  2. Update core to the Drupal 9.4 or 9.5 release

    Before any Drupal 10 work, the site moves to the latest Drupal 9.4 or 9.5 minor release through Composer, with the lock file committed. A developer runs database updates, clears caches and reviews the status report for errors. The step passes when the status report is clean, the site's critical paths work and the Composer diff contains only the core update. Rollback means restoring the code and lock file from the previous commit and restoring the baseline database backup taken in the first step.

  3. Update contributed modules to Drupal 10 compatible releases

    Each contributed module is checked against Drupal.org for a release that supports the current minor version and, where possible, Drupal 10. The team applies the updates in small batches, runs database updates after each batch and records any module without a compatible release as a blocker. Modules with no release for Drupal 10 are flagged for replacement or removal. The step passes when every enabled module reports a supported release and the site still passes the staging smoke test. Rollback means reverting the batch's Composer change and database backup for that batch.

  4. Replace CKEditor 4 and review the Seven theme

    CKEditor 4 must be replaced with CKEditor 5 for Drupal 10, so the team migrates text format configurations, editor toolbars and any custom editor plugins, then tests stored content for markup that the new editor changes. The team also reviews the Seven administration theme and any custom admin styling, since the Drupal 10 admin experience depends on it. The step passes when editors can create and edit representative content in every text format and the admin screens render correctly. Rollback means restoring the previous editor configuration from version control and the batch's database backup.

  5. Run the Drupal 10 upgrade with Composer

    The developer changes the core constraint to Drupal 10 in a branch, resolves dependencies with Composer and fixes conflicts that the resolver reports. Custom modules and themes are updated for Drupal 10 deprecations, and Upgrade Status reports should be reviewed before the change is merged. The step passes when Composer resolves cleanly, the lock file is reproducible from a fresh build and database updates complete without errors on staging. Rollback means abandoning the branch and redeploying the last Drupal 9 build from the artifact store.

  6. Run automated and manual test passes

    The team runs the project's automated tests, including custom module unit and functional tests, then works through a scripted manual checklist covering login, content workflows, forms, search, integrations and cron. Editors and site owners sign off on the checklist results. The step passes when automated tests are green, no critical or high defects remain open and sign-off is recorded. If a defect blocks sign-off, the rollback action is to hold the production change and keep the Drupal 9 site live.

  7. Cut over to production in a planned window

    The team schedules the production change in a window agreed with the business and avoids the Wednesday release days where possible, because the Drupal core release schedule sets bugfix releases on the first Wednesday and security releases on the third Wednesday of each month. The team takes a fresh backup, deploys the tested build, runs database updates and checks the status report and key journeys. The step passes when production matches staging and monitoring shows normal behavior. Rollback means redeploying the saved Drupal 9 build and restoring the pre-cutover backup.

  8. Plan the next step to Drupal 11

    Because Drupal 10 reaches end of life on December 9, 2026, according to the Drupal core release schedule, the team starts the Drupal 11 plan as soon as the Drupal 10 site is stable. Drupal 11 requires PHP 8.3 or later, so hosting and contributed module readiness should be checked early. The step passes when the team has a written plan that confirms the target PHP version and the module list to review. Confirm the current support dates on the Drupal.org release schedule before committing to a timeline.

How the code arrives on your servers for the Drupal 10 step

In a Composer-managed build, the site's code is described by composer.json and frozen by composer.lock, which pins exact versions of Drupal core, contributed modules and themes. The team proposes the Drupal 10 step as a set of changes to these files, reviews them in a merge request, and deploys only the artifact built from the committed lock file. Drupal 10 requires PHP 8.1 or later according to the Drupal.org PHP requirements page, so the build should also be checked against the server PHP version before merge.

  • Lock file review: Each lock file change shows which core and contributed versions move, so reviewers can check the exact change instead of relying on a summary.
  • Reproducible builds: A clean install from the committed lock file should produce the same code tree that was tested, which gives auditors a stable reference.
  • Approval points: Merge approval, a check of pinned contributed projects against security advisories, and a recorded decision for any module without a Drupal 10 release.
  • What you gain: Precise version control and a clear audit trail for each change.
  • What you give up: One-click updates. Your team must maintain Composer skills and a build pipeline.

Before approving, confirm that the lock file is committed, that production deploys only from build artifacts, and that every server meets the PHP version the build targets.

How to test the upgrade and roll it back if a stage fails

Test the upgrade in layers, from the cheapest and most automated checks to the most expensive, and decide in advance which failures mean restoring the backup and which mean patching in staging. The first layer is automated tests on custom code: the custom modules and themes your team owns should have unit or kernel tests that run against the upgraded core and the Drupal 9.4 or 9.5 baseline. Run them in CI on every branch, and treat any deprecation or type error they expose as a blocking defect before the site is touched. The second layer is a scripted smoke test of key user journeys: anonymous browsing, login through your identity provider, content creation, publishing, search, forms that submit to your CRM, and the cron run that clears queued work. Keep the script in version control so it runs unchanged against every stage.

The third layer is a review of every contributed module that changed major or minor version, checked against its release notes and the Drupal.org project page, not only against whether the site loads. Editorial sign-off is the fourth layer: editors should test the replacement for CKEditor 4 with real content, including embedded media, tables, links and any custom plugins, and confirm that stored markup still renders. The fifth layer is load and performance checks on production-like hosting, comparing response times and database load against the pre-upgrade baseline. Rollback is the decision that matters most. Restore the backup when the failure touches data integrity, authentication, or the database schema, or when the fix is not understood within the change window. Patch in staging when the failure is cosmetic, isolated to one contributed module, or fixed by a configuration change. After any restore, compare the site with the pre-upgrade record: the exported configuration, the composer.lock file, the enabled module list, the PHP version, and a row count check on key content types. Confirm these with your own change records before reopening the site.

What drives the cost and length of a Drupal 9 to Drupal 10 upgrade

This table lists the factors that most change the effort of moving a Drupal 9 site to Drupal 10, with why each one matters and what to check first. Use it to scope the audit and to ask partners for a quote that breaks effort down by driver rather than as a single figure.

DriverWhy it changes effortWhat to check
Contributed modules: number and ageEach contributed project needs a release that supports Drupal 10, and older or unmaintained projects may need replacing or forking before the core update can proceed.List every contributed project, its installed version, whether a Drupal 10 compatible release exists, and when it last had a release.
Custom code and deprecated API useCustom modules that call APIs deprecated in Drupal 9 must be fixed before or during the move, and the volume of changes scales with the size of the codebase.Run Upgrade Status against custom modules and themes and count reported deprecations by module.
Custom themesEach custom theme must be checked against Drupal 10 changes and its templates, libraries and any Seven or Bartik dependencies reviewed.Count custom themes, note which base theme each one uses, and confirm whether the Seven theme is referenced anywhere.
CKEditor 4 content and configurationCKEditor 4 must be replaced, so text formats, plugins and stored markup need review, and the amount of rich text content drives the testing effort.Count text formats that use CKEditor 4, list custom plugins, and sample stored content for markup the new editor will handle differently.
Multisite and multilingual scopeEach site in a multisite estate is upgraded and tested separately, and each language adds content and interface translation checks.Confirm the number of sites, shared codebase or separate codebases, and the languages and translation files in use.
Hosting and PHP upgradeDrupal 10 requires PHP 8.1 or later, so server, container and database upgrades may need to happen before or alongside the code change.Check the PHP version on each environment, the web server and database versions, and whether build pipelines run on the same PHP version.
Data volume and backup restore timeLarger databases and file stores lengthen the database update run, staging refreshes and rollback tests, and affect how long the site must be paused.Measure database size, file directory size, and the time a full restore takes in a non-production environment.
Integrations and SSO modulesIdentity, CRM and search integrations depend on contributed modules and external services that must be tested against the upgraded site, and SSO modules may have their own version constraints.List each integration, the module that provides it, its Drupal 10 compatibility, and the test accounts and sandbox services available.

What buyers ask about cost, time and their own role in the upgrade

Does Drupal itself have a license cost for an upgrade?

No. Drupal has no paid edition, and Drupal core and contributed projects that are derivative works of Drupal are licensed under GPL-2.0-or-later. Your costs come from people and services: assessing the site, changing custom code, updating contributed modules, testing, hosting changes and any support you buy afterward. Check the license terms of any commercial module, theme or hosting service you add to the site, because those carry their own terms. You can confirm the core position on the Drupal.org licensing page.

How is the cost and duration of a Drupal 9 to 10 upgrade set?

Cost and duration follow from a written scope that both sides agree before work starts, and most engagements are fixed-scope. The main drivers are the number of custom modules and themes, the amount of deprecated API use they contain, and whether each contributed module has a release compatible with Drupal 10. Other drivers are the volume of content that uses CKEditor 4, how much of the Seven theme is customized, the PHP and server changes your hosting needs, the number of integrations, and how many test environments you need. DeployOpen does not publish a price list. Ask for a quote that itemizes these drivers so you can see what changes if one of them moves.

What does our team need to provide for the upgrade?

The upgrade needs access and decisions from your side, and delays usually start there. Expect to provide:

  • Read and write access to the code repository, including the current composer.lock file
  • Staging environments that resemble production, with a current copy of the database and files, handled under your data rules
  • An editorial contact who can review content, editor settings and CKEditor 4 replacements
  • A named decision maker who approves scope changes and signs off each release to production
  • Access to hosting, DNS and change windows for PHP and server updates

Agree these owners and dates in the written scope so the schedule has a clear basis.

Can our own engineers complete the Drupal 9 to 10 upgrade?

Yes. An internal team can do the upgrade if it has time, engineers familiar with Composer and Drush, and a written test plan. Start with the release notes for the target Drupal version, then use Upgrade Status to find deprecated code and contributed modules that need work. The test plan should cover content editing, forms, permissions, search, cron, and every integration the site uses, and it should be run again after each change. A partner adds capacity, prior experience with these failure modes, and a fixed scope, which matters most when the internal team is also running daily operations.

What happens if Drupal 10 reaches end of life during our project?

Drupal 10 reaches end of life on December 9, 2026, according to the Drupal core release schedule. After that date, the Drupal Security Team's regular security releases for Drupal 10 stop, so a site that stays on it accumulates unpatched risk. Plan the timeline so the site moves to Drupal 11 before that date, and treat the date as a fixed constraint in the written scope. If a project is at risk of running late, the scope should state how a schedule change affects cost, which phases move first, and who decides. Confirm the current dates on the release schedule before you commit to a plan.

Does the upgrade also cover the move from Drupal 10 to Drupal 11?

A Drupal 9 site cannot go straight to Drupal 11, so Drupal 10 is a required stop on the way. Drupal 11 is the current major version, and Drupal 10 reaches end of life on December 9, 2026. Decide early whether the next step is part of the same written scope or a separate phase, because the Drupal 11 work changes PHP requirements and contributed module versions again. Ask for the Drupal 11 step to be priced and scheduled alongside the Drupal 10 step, so the site does not sit on an end-of-life version while the second phase waits for approval.

Which PHP version does Drupal 10 need, and who changes it?

Drupal 10 requires PHP 8.1 or later, and no supported Drupal version runs on PHP 7. Drupal 11 requires PHP 8.3 or later, and Drupal 12 requires PHP 8.5 or later, so a PHP upgrade on a Drupal 9 site often has to happen before the code moves. Your hosting team or infrastructure provider usually makes the PHP change, while the upgrade work tests the site on the new runtime. Check the web server and database versions against the Drupal system requirements too, and confirm which server changes sit inside your change process. The Drupal.org PHP requirements page lists the current minimums.

Why the Drupal 10 step should lead straight into a Drupal 11 plan

The Drupal 10 step should come with a committed plan for Drupal 11, because Drupal 10 reaches end of life on December 9, 2026, and Drupal 11 is the current major version. A site that lands on Drupal 10 and then stops has bought a few months of supported code, not a durable platform. Treat the Drupal 11 move as part of the same project plan, with its own owner, budget line and go-live window, so the team is not starting a second discovery exercise when the first one is still fresh.

Start with PHP, because it sets the sequence. Drupal 10 requires PHP 8.1 or later and Drupal 11 requires PHP 8.3 or later, so any server that will run Drupal 10 must be checked against the PHP version on each web node, including staging, cron workers and any build runners. Ask your hosting team to confirm the PHP version in every environment and whether the web server and database versions still meet the requirements on the Drupal.org system requirements page. Changing PHP on the same night as the code change makes failures hard to trace, so plan the PHP change as its own step.

Then check contributed modules and the authentication stack. Every contributed module needs a release that supports Drupal 11, and modules without one need a replacement or a decision to drop the feature. If the site uses single sign-on, confirm the exact versions in use. The SAML Authentication module (samlauth) 8.x-3.14 supports Drupal 10.3 and later and Drupal 11, so a site on an earlier Drupal 10 minor release should schedule the core update before the module update. Confirm the same for the OpenID Connect module with your identity provider configuration and test sign-in on staging before cutover. Finally, set the timing decision now: choose a target window for Drupal 11 well before December 9, 2026, and record who approves that date.

How DeployOpen scopes, delivers and supports the Drupal upgrade

DeployOpen plans, implements, tests, documents and supports self-hosted open-source platforms inside your own infrastructure, including Drupal 9 to Drupal 10 upgrades. We start from a written scope so that the 9.4 or 9.5 stop, the CKEditor 4 and Seven theme work, and the contributed module decisions are agreed before any code changes.

How we scope

  • Inventory the Drupal 9 codebase, contributed modules, custom modules and themes, and the hosting stack in your environment.
  • Confirm PHP and database versions against the Drupal 10 requirements before agreeing any upgrade sequence.
  • Agree the written, fixed scope, including the 9.4 or 9.5 intermediate update and the planned step on to Drupal 11.

How we build

  • Replace CKEditor 4 and move off the Seven theme, with text formats and layouts checked against content editors' real workflows.
  • Resolve contributed module versions and deprecated API use in custom code, recording each change in version control.
  • Test on a staging copy of production data, covering content, forms, authentication and scheduled jobs before cutover.

How we hand over

  • Deliver a written record of the upgrade path, module decisions, custom code changes and known open items.
  • Document the Composer-managed build, lock file handling and the update routine your team will follow after go-live.
  • Walk your administrators and developers through rollback steps, backups and the Drupal 11 plan before the handover closes.

How we support

  • Offer ongoing support, upgrades and continuous testing as a retainer after the fixed-scope upgrade is complete.
  • Plan the Drupal 11 upgrade as a separate written scope, sequenced ahead of Drupal 10 end of life on December 9, 2026.
  • Ask your team to confirm the support window, security response expectations and who approves production changes before signing.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.