We upgraded fourteen sites to Drupal 11 last quarter without one minute of unplanned downtime. None of it was clever. It was a boring, repeatable process, and here it is.
1. Audit before you touch anything
Run upgrade_status on every site and export the report. We put all fourteen into one spreadsheet, and it showed us that 80% of the blockers came from just six contrib modules. Fixing those once unblocked almost everything.
drush pm:install upgrade_status
drush upgrade_status:analyze --all --format=csv > reports/$(drush php:eval 'echo \Drupal::config("system.site")->get("name");').csv
2. Fix deprecations in the open
Every patch we needed went to Drupal.org first. Where maintainers were slow, we used cweagans/composer-patches with a link to the issue, and we tracked each patch so we could remove it later.
3. Upgrade the platform, then the sites
We moved the shared hosting image to PHP 8.3 and the new database minimums first, and ran Drupal 10 on it for two weeks. That separated platform problems from Drupal problems, and it saved us more debugging time than anything else.
4. Use the same rollback plan every time
- Database snapshot and code tag before each deploy
- A feature flag for the new theme layer
- A named person with authority to roll back, for every release
Gotchas
CKEditor 5 plugin configuration doesn't always migrate cleanly. Diff your text format config before and after the upgrade.
The full checklist is in the resource library. If you're planning your own upgrade, ask in Development & DevOps and we'll help.



