Skip to content
Skip to content
How to Update and Upgrade Moodle in 2026: A Risk-Free Playbook blog illustration

How to Update and Upgrade Moodle in 2026: A Risk-Free Playbook

Security patches arrive every two months, LTS releases every two years, and each jump introduces new PHP requirements, database changes, and plugin compatibility risks. One wrong move and you face emergency rollbacks at 2 AM.

The difference between a smooth upgrade and a disaster isn't luck -- it's process. The playbook below reflects the repeatable staging, compatibility, backup, and rollback steps used in production Moodle upgrade work.

1. DIY or Managed? Start Here

Before diving into the technical process, determine the right approach for your situation:

Your ScenarioDIY UpgradeManaged Upgrade (MooDIY)
Single site, under 500 usersFeasible with this guideWorthwhile if time-strapped
Multiple sites or 1,000+ usersRisky without dedicated DevOpsStrongly recommended
Custom plugins or integrationsRequires development expertiseWe scan and patch compatibility
Mission-critical uptime (exams, compliance)High stakes for DIYZero-downtime guarantee
No staging environmentNever upgrade without stagingStaging or validation workflow available by plan and upgrade scope
Limited PHP/database skillsHire expertise or go managedFull automation + support
Annual budget under $500DIY carefully with backupsEvaluate the cost of downtime first

2. Build Your Upgrade Calendar (Plan 6-12 Weeks Ahead)

Successful upgrades start with calendar alignment, not code changes.

Track Supported Versions

VersionReleasedStatusSupport endsNotes
4.1 LTSNov 2022EOLDec 2025Upgrade immediately
4.3 / 4.42023-2024EOLPassedNo security patches
4.5 LTSOct 2024Current securityOct 2027Stable LTS option, security-only support
5.0Apr 2025Current securityOct 2026General support ended Apr 20, 2026; PHP 8.2 min, no Oracle
5.1Oct 2025Current stableApr 2027General support to Oct 2026; /public web root required
5.2Apr 2026Current stableOct 2027Current stable as of May 2026; PHP 8.3 min
5.3 LTSOct 2026Future releaseOct 2029Next LTS target

Source checked May 2026: Moodle's official release support table.

Critical Migration Notes for Moodle 5.0+

If upgrading to Moodle 5.0 or later, three architectural changes require attention before you begin:

PHP version requirement: Moodle 5.0 and 5.1 raised the floor from PHP 8.1 to PHP 8.2. Moodle 5.2 raises the current install baseline to PHP 8.3. Confirm the exact target-version requirements before touching production.

Oracle database support removed: Moodle 5.0 permanently dropped Oracle. If your site runs on Oracle, migrate to MySQL/MariaDB or PostgreSQL before upgrading to 5.0+. Plan this as a separate project with its own testing cycle.

Moodle 5.1 /public web root migration: Moodle 5.1 restructured the web root so only a /public subdirectory is web-accessible. Your web server configuration must point to /path/to/moodle/public instead of /path/to/moodle.

This requires manual reconfiguration of the web server -- update your Apache DocumentRoot or Nginx root to point to /public. Custom plugins installed via Git remain in Moodle's normal plugin directories under the main codebase; do not move plugin trees into /public. Test on staging first, and specifically check custom plugin URLs, theme assets, web service endpoints, and reverse-proxy rules after the document-root change.

Routing engine note: The routing engine (available since Moodle 4.5) is strongly recommended but not compulsory in 5.1 -- a backwards compatibility layer is included. Standard and custom plugins are unaffected unless they depend on specific URL rewriting rules.

Upgrade Strategy Decision

  • LTS-to-LTS (every 2 years): Minimize disruption, maximize stability, ideal for risk-averse organizations
  • Iterative (every 6-12 months): Stay current with features, smaller change windows, requires more frequent testing

Coordinate Stakeholder Schedules

  • Academic institutions: Upgrade during semester breaks, never mid-term or during exam windows
  • Corporate training: Align with quarter-end or project lulls
  • Compliance-driven orgs: Schedule 30+ days before audit cycles

Document accountability with clear role assignments:

  • Staging tests: Who validates functionality?
  • Plugin compatibility: Who contacts vendors or patches custom code?
  • Rollback decision: Who has the authority to abort and restore?
  • Communications: Who notifies faculty, learners, and leadership?
  • Post-upgrade monitoring: Who watches logs for 48 hours?

3. The Pre-Upgrade Checklist (Never Skip These 8 Steps)

Budget 8-12 hours for thorough preparation. This phase separates successful upgrades from disasters.

#StepWhat to doTime budget
1Verify infrastructureCheck PHP version, extensions, and DB version against target requirements30 min
2Complete backups (3-2-1)DB dump + code tar + moodledata rsync. Store one copy offsite. Retain 30+ days.1-2 hrs
3Clone to stagingExact OS + PHP + DB mirror of production with recent data snapshot2-3 hrs
4Audit plugins and themesBuild a compatibility matrix against the target version. Flag incompatible plugins.1-3 hrs
5Test upgrade on stagingRun the full upgrade procedure. Test auth, quizzes, integrations, cron.2-4 hrs
6Draft rollback planDocument failure signals, decision authority, restore procedure, and time estimate.30 min
7Communicate proactivelyT-14 days, T-48 hours, T-0 maintenance messages to users1 hr
8Schedule a low-traffic windowAnalyze logs to find the weekly low point. Match downtime estimate to DB size.30 min

Step 1: Verify Infrastructure Prerequisites

Before touching code, confirm your server meets the target version requirements:

bash
# Check current PHP version
php -v

# Verify required PHP extensions
php -m | grep -E "curl|gd|intl|mbstring|mysqli|opcache|soap|xml|zip"

# Check database version (MySQL 8.0+ or PostgreSQL 13+ for Moodle 4.5+)
mysql --version

See Critical Migration Notes in Section 2 for PHP, Oracle, and database version requirements specific to each target version.

Step 2: Create Complete Backups (The 3-2-1 Rule)

3 copies, 2 different storage types, 1 copy offsite:

bash
# Database backup
mysqldump -u moodleuser -p moodledb > moodle_backup_$(date +%F).sql

# Application code backup
tar -czf moodle_code_$(date +%F).tar.gz /var/www/html/moodle/

# Moodledata backup
rsync -av /var/moodledata/ /backup/moodledata_$(date +%F)/

Store at least one backup copy off-site and retain it for 30 days post-upgrade. 90% of rollback requests happen within 72 hours, but edge cases surface weeks later.

Step 3: Clone to Staging (Non-Negotiable)

Staging must mirror production exactly:

  • Same OS version
  • Same PHP version
  • Same database engine and version
  • Recent data snapshot (production backup from within the last 7 days)

Step 4: Audit Plugins and Themes

Build a compatibility matrix for every installed plugin. Check:

  • Moodle Plugins Directory -- official compatibility badges
  • Plugin developer GitHub repositories -- release notes
  • Moodle community forums -- search "[plugin name] [version] upgrade issues"

Plugin incompatibility causes 60% of failed Moodle upgrades. Custom code warning: in-house plugins or modified core files may need 2-3x longer for testing -- core API changes between major versions often break custom code.

Step 5: Test the Upgrade on Staging

Run the exact upgrade process you'll use in production:

bash
sudo -u www-data php admin/cli/maintenance.php --enable
mv /var/www/html/moodle /var/www/html/moodle_old
git clone -b MOODLE_405_STABLE git://git.moodle.org/moodle.git /var/www/html/moodle
cp /var/www/html/moodle_old/config.php /var/www/html/moodle/config.php
sudo -u www-data php admin/cli/upgrade.php --non-interactive
sudo -u www-data php admin/cli/purge_caches.php
sudo -u www-data php admin/cli/maintenance.php --disable

Time budget: 2-4 hours for thorough testing.

Step 6: Draft a Rollback Plan

Document before upgrading production:

Failure signals: login failures >5%, cron stopped, database errors in logs

Decision authority: Name one person -- avoid committees during a crisis

Rollback procedure:

bash
mysql -u moodleuser -p moodledb < moodle_backup_2026-10-20.sql
rm -rf /var/www/html/moodle
tar -xzf moodle_code_2026-10-20.tar.gz -C /var/www/html/
sudo -u www-data php admin/cli/purge_caches.php

Rollback time estimate: 15-30 minutes for small sites, 1-2 hours for large databases

Communication plan: Who notifies users of the rollback and new timeline?

Rehearse the rollback on staging before production day.

Step 7: Communicate Proactively

  • T-14 days: "Planned upgrade on [date], new features include [list], expected downtime [window]"
  • T-48 hours: "Reminder: upgrade in 2 days, backup your course files if needed."
  • T-0: "Site in maintenance mode, expected completion [time], status updates at [URL]"

Step 8: Schedule for Low-Traffic Windows

Analyze your access logs to find the weekly low-traffic period:

bash
awk '{print $4}' /var/log/apache2/access.log | sed 's/\[//g' | cut -d: -f1-2 | uniq -c | sort -n
  • Academic: Saturday 2-6 AM
  • Corporate: Sunday 12-4 AM or Friday 6-10 PM

Downtime estimates by database size:

  • Small (<500 users, <10 GB): 30-60 minutes
  • Medium (500-2,000 users, 10-50 GB): 1-2 hours
  • Large (5,000+ users, 100+ GB): 2-4 hours -- consider zero-downtime strategies

4. Execute the Production Upgrade (The Critical 2-4 Hours)

You've tested on staging, communicated to users, and scheduled the maintenance window. Execute with precision.

Step 1: Enable Maintenance Mode

bash
sudo -u www-data php admin/cli/maintenance.php --enable

Customize the maintenance message: "Moodle is upgrading to deliver improved performance and security. We expect the site to return at approximately [Time]. Thank you for your patience."

Step 2: Swap Code Cleanly (Never Overwrite)

Deploy fresh code and restore only your config.php -- never copy new files over an existing installation:

bash
sudo mv /var/www/html/moodle /var/www/html/moodle_4.1.10
sudo git clone -b MOODLE_405_STABLE git://git.moodle.org/moodle.git /var/www/html/moodle
sudo cp /var/www/html/moodle_4.1.10/config.php /var/www/html/moodle/config.php
sudo cp -r /var/www/html/moodle_4.1.10/theme/mytheme /var/www/html/moodle/theme/
sudo chown -R www-data:www-data /var/www/html/moodle

Step 3: Run the CLI Upgrader

bash
sudo -u www-data php /var/www/html/moodle/admin/cli/upgrade.php --non-interactive 2>&1 | tee upgrade_log_$(date +%F_%H-%M).txt

Watch for: plugin update prompts, missing dependency errors, deprecated feature warnings. Time estimate: 5-30 minutes, depending on database size and plugin count.

Step 4: Purge All Caches

This resolves 80% of "the upgrade broke something" reports:

bash
sudo -u www-data php /var/www/html/moodle/admin/cli/purge_caches.php
sudo systemctl restart php8.1-fpm

Step 5: Smoke-Test Critical Workflows

CheckWhat to verify
Admin loginCan you access Site administration?
Teacher loginCan you edit a course and add an activity?
Student loginCan you view the course content and submit an assignment?
Quiz attemptStart and submit a quiz; verify the grade recorded
CronVisit admin/cron.php -- scheduled tasks running?
SSO/SAMLTest external authentication login flow
IntegrationsPayment gateways, SIS sync, and web services still connecting?

Time budget: 15-30 minutes.

Step 6: Disable Maintenance Mode and Notify Users

bash
sudo -u www-data php /var/www/html/moodle/admin/cli/maintenance.php --disable

Send the "upgrade complete" communication immediately: confirm the site is back online and list 2-3 user-facing improvements.

5. Post-Upgrade Monitoring (The Critical 48 Hours)

The upgrade isn't done when the site comes back online -- it's done when you've confirmed stability over 48 hours.

Monitor Logs Continuously

bash
tail -f /var/log/php8.1-fpm.log | grep -i error
mysql -u root -p -e "SELECT * FROM information_schema.processlist WHERE time > 5 ORDER BY time DESC;"
tail -f /var/moodledata/moodlecron.log

Red flags requiring immediate investigation:

  • Repeated "Can't connect to database" errors
  • Cron tasks are timing out or failing
  • Plugin errors about missing classes or functions
  • User reports of "white screen" or 500 errors

Run a Stability Window

Freeze new changes for 7-14 days post-upgrade: no new plugin installations, no major configuration changes, no custom code deployments. This isolates upgrade-related issues from new changes and makes troubleshooting faster.

Document Lessons Learned

  • Actual downtime vs estimate
  • Issues discovered that staging didn't catch
  • User feedback on changes and confusion
  • Process improvements for next upgrade

6. When to Lean on MooDIY Cloud's Managed Upgrades

DIY upgrades work for small, simple sites with skilled administrators and flexible timelines. For everything else, MooDIY Cloud provides production-grade upgrade automation with staging rehearsals, plugin checks, backups, and rollback planning.

What's Included in Every Managed Upgrade

Automated staging rehearsal: Plugin compatibility scanning of 500+ common plugins, DB migration validation, performance regression testing, authentication flow testing

Plugin compatibility scanning and patching: Flags incompatibilities before production breaks. Custom plugins: line-by-line assessment + patching (2-4 hr turnaround) + vendor coordination

Coordinated scheduling: Academic, corporate, and global calendar coordination. Regional rollouts for multi-timezone organizations.

Low-downtime upgrades: Blue-green deployment, database replication sync before cutover, and rollback on health-check failure are available by plan and scope.

Rollback planning: Database snapshot restore, code revert, cache purge, and team notification should be rehearsed before the production window.

The Economics

DIY true cost (500-user site, annual upgrade): ~20 hours of administrator time = $600 at $30/hour, plus risk of extended downtime.

For managed upgrades, confirm the current plan scope on the pricing page: scheduling, staging, testing, execution, plugin scanning, monitoring, and rollback expectations vary by plan and custom-code complexity.

Operational Safeguards

  • Staging rehearsal before production changes
  • Verified backup and restore path before the upgrade starts
  • Plugin compatibility scan before the maintenance window
  • Written rollback trigger criteria
  • Post-upgrade monitoring window for authentication, cron, grades, and key activities

7. Moodle Upgrade FAQs

Q: Can I skip versions (e.g., upgrade from 4.1 directly to 5.1)? A: Yes, Moodle supports jumping directly to the latest version from any earlier version. However, if you're jumping multiple major versions (e.g., 4.1 to 5.1), test thoroughly on staging because cumulative changes are significant. In particular, upgrading past 5.0 removes Oracle support and raises the PHP floor to 8.2, and upgrading to 5.1 requires web server reconfiguration for the new /public directory structure.

Q: How often should I upgrade? A: At minimum, apply security updates every 2-3 months when Moodle releases them. For major version upgrades, choose between:

  • LTS-to-LTS (every 2 years): Minimal disruption, maximum stability
  • Annual upgrades: Stay reasonably current with features without constant change
  • Every release (twice yearly): Bleeding edge, requires dedicated resources

Q: What if a plugin I depend on isn't compatible with the target version? A: Three options:

  1. Wait for the plugin developer to release an update
  2. Hire a developer to patch it (typical cost: $500-$2,000 depending on complexity)
  3. Find an alternative plugin with similar functionality

MooDIY's plugin compatibility scanning identifies these issues during the staging phase, not after production breaks.

Q: Can I upgrade during the academic term or should I wait for semester break? A: Best practice is to upgrade during low-activity periods (semester breaks, summer, winter holidays). However, if a critical security vulnerability is announced, apply the security patch immediately via minor version update (e.g., 4.5.1 to 4.5.2) which carries lower risk than major version jumps.

Q: How long should I keep backups after an upgrade? A: Minimum 30 days. Most rollback requests occur within 72 hours, but edge cases (subtle gradebook calculation changes, hidden integration failures) can surface weeks later. Storage is cheap - keep backups for 60-90 days if space allows.

Q: What's the difference between a minor update and a major upgrade? A:

  • Minor update (e.g., 4.5.0 -> 4.5.3): Security patches and bug fixes only. Low risk, should apply within 1-2 weeks of release.
  • Major upgrade (e.g., 4.1 -> 4.5): New features, API changes, plugin compatibility concerns. Higher risk, requires full testing process.