Tuning Moodle for Speed: PHP, OPcache & MySQL/MariaDB (2026)

The exact PHP, OPcache and MySQL/MariaDB settings that make Moodle fast in 2026 - with copy-paste config, a Redis caching setup, and the deploy gotcha that trips everyone up. Spoke 2 of our Moodle performance series.

MJ
Mihir Jana
·9 July 2026·9 min read
⚡ Quick answer

After right-sizing your server, the two biggest Moodle speed levers are PHP OPcache and the database. Give OPcache enough memory (256MB+), raise max_accelerated_files to ~16000, and set validate_timestamps=0 in production so PHP stops re-checking files on every request. On the database, size the InnoDB buffer pool to hold your working set (60-70% of a dedicated DB server's RAM) and set innodb_flush_log_at_trx_commit=2. Add Redis for Moodle's MUC application cache. Together these routinely cut page-generation time by half or more. edzlms ships Moodle pre-tuned with these settings as a managed service.

50%+
page-generation time a well-tuned OPcache + InnoDB buffer pool routinely removes
256MB+
OPcache memory a busy Moodle site should allocate (opcache.memory_consumption)
60-70%
of a dedicated DB server's RAM to give the InnoDB buffer pool
0
opcache.validate_timestamps in production - stop re-stat-ing files every request

Key takeaways

  • OPcache and the database are where Moodle spends most of its time - tune them before chasing micro-optimisations.
  • OPcache: allocate 256MB+, raise max_accelerated_files to ~16000, and set validate_timestamps=0 in production (re-cache manually on deploy).
  • PHP realpath cache and a modern PHP version (8.2/8.3) give free wins - Moodle is heavily filesystem- and CPU-bound.
  • The InnoDB buffer pool is the single most important database setting: size it to hold your working data set in RAM.
  • Turn on Redis for Moodle's Universal Cache (MUC) and sessions so repeated lookups never touch the database.
  • This is Spoke 2 of the Moodle performance series - pair it with the architecture spoke and the pillar guide.

This is Spoke 2 of our Moodle Performance Optimization Guide (2026). Spoke 1 covered hosting and server architecture; here we tune the software running on it.

Where Moodle actually spends its time

Once your server is the right size, a slow Moodle almost always comes down to two things: PHP recompiling code it should have cached, and the database reading from disk instead of memory. Fix those two and most sites feel dramatically faster without any new hardware. Here's the request path and the two levers that matter most:

BrowserNginx / PHP-FPMPHP + OPcache(compiled code cached)MariaDB / MySQLInnoDB buffer pooltune: memory_consumption, validate_timestamps=0tune: innodb_buffer_pool_size

Every page view runs PHP (which OPcache should be serving from memory) and hits the database (which should be answering from the InnoDB buffer pool, not disk). The rest of this guide tunes exactly those two stages, then adds Redis so repeated work is skipped entirely.

1. PHP & OPcache

OPcache compiles your PHP once and keeps the bytecode in memory. Out of the box its limits are too small for Moodle, which has thousands of PHP files. The fix is more memory, a higher file cap, and - crucially in production - telling it to stop checking whether files changed on every single request.

; /etc/php/8.3/fpm/conf.d/10-opcache.ini
opcache.enable=1
opcache.memory_consumption=256        ; MB - raise to 512 on large sites
opcache.interned_strings_buffer=32    ; MB
opcache.max_accelerated_files=16000   ; Moodle has thousands of files
opcache.validate_timestamps=0         ; PROD: don't re-stat files each request
opcache.save_comments=1               ; required by Moodle
opcache.revalidate_freq=60            ; only used if validate_timestamps=1

Important: with validate_timestamps=0, PHP will not notice code changes until you reload it. After every deploy or plugin update you must clear OPcache - reload PHP-FPM (systemctl reload php8.3-fpm) or purge caches. That trade is worth it: on a busy site, skipping the per-request file check is one of the biggest single wins available.

Realpath cache and PHP version

Moodle touches many files, so the realpath cache matters too. And simply running a current PHP release buys measurable speed - if you're on PHP 7.x or early 8.0, upgrading to 8.2/8.3 is free performance.

; php.ini
realpath_cache_size=4096K
realpath_cache_ttl=600
memory_limit=256M            ; Moodle needs headroom for imports/reports
max_input_vars=5000          ; large quiz/grade forms

2. MySQL / MariaDB

The database is the shared bottleneck every request touches. The goal is simple: keep your working data set in memory so queries never wait on disk. That is what the InnoDB buffer pool does, and sizing it correctly is the highest-impact database change you can make.

# my.cnf  [mysqld]  (MariaDB / MySQL)
# Give InnoDB ~60-70% of a dedicated DB server's RAM
innodb_buffer_pool_size = 12G          # on a 16GB DB box
innodb_buffer_pool_instances = 8
innodb_log_file_size = 1G              # bigger = fewer flushes
innodb_flush_log_at_trx_commit = 2     # faster; tiny durability trade-off
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
max_connections = 300                  # >= peak PHP-FPM workers
tmp_table_size = 64M
max_heap_table_size = 64M
# MySQL 5.7 only: query_cache_type = 0 (removed in 8.0; leave OFF)

Why these matter

Buffer pool holds table and index data in RAM - too small and MariaDB reads from disk on every query. flush_log_at_trx_commit=2 flushes the log once per second rather than per transaction, a big write win for an LMS where a lost second of logs on a crash is acceptable. Bigger log files reduce checkpoint churn under load. Keep the old MySQL query cache OFF - it hurts concurrency and is gone in 8.0.

Run a tuning check with a tool like MySQLTuner after a few days of real traffic, and add indexes only for confirmed slow queries from the slow-query log - never guess.

3. Redis for Moodle's MUC & sessions

Moodle's Universal Cache (MUC) stores things like language strings, configuration and course structures. By default these use the database or filesystem; moving them to Redis means repeated lookups are answered from memory and never hit MariaDB. Point sessions at Redis too - essential once you run more than one app node.

// config.php - Redis session handler
$CFG->session_handler_class = '\\core\\session\\redis';
$CFG->session_redis_host = '127.0.0.1';
$CFG->session_redis_port = 6379;
$CFG->session_redis_acquire_lock_timeout = 120;
$CFG->session_redis_lock_expire = 7200;

Then, in Site administration → Plugins → Caching → Configuration, add a Redis store and map the Application and Session cache definitions to it. The deeper caching and CDN layer - media offload, static asset caching, MUC strategy at scale - is the subject of Spoke 3 in this series.

  1. 1
    Baseline before you touch anything

    Note current page-load and DB time (Moodle's Performance info in the footer, or a tool like New Relic) so you can prove the gain.

  2. 2
    Tune OPcache first

    Set memory 256MB+, max_accelerated_files ~16000, validate_timestamps=0, then reload PHP-FPM. Remember to clear OPcache on every deploy.

  3. 3
    Upgrade PHP if behind

    Move to PHP 8.2/8.3 and set the realpath cache. It's free, measurable speed on a filesystem-heavy app.

  4. 4
    Size the InnoDB buffer pool

    Give it 60-70% of a dedicated DB server's RAM, enlarge the log files, and set flush_log_at_trx_commit=2.

  5. 5
    Move caches to Redis

    Point MUC application cache and sessions at Redis so repeated lookups skip the database entirely.

  6. 6
    Measure, then index

    Re-check page-generation time, enable the slow-query log, and add indexes only for confirmed slow queries.

Untuned Moodle

  • OPcache tiny / re-checks files every request
  • PHP re-compiles code repeatedly
  • DB reads from disk - buffer pool too small
  • MUC + sessions on database/filesystem
  • Page time balloons under concurrency

Tuned Moodle (edzlms defaults)

  • OPcache 256MB+, validate_timestamps=0
  • Current PHP 8.3 + realpath cache
  • InnoDB buffer pool holds the working set in RAM
  • Redis-backed MUC + sessions
  • Page time stays low as users scale

Want this tuned for you?

edzlms runs Moodle with these OPcache, InnoDB and Redis settings pre-configured and monitored, on performance-tuned hosting with India data residency. Share your site size and we'll benchmark it.

💡

Clear OPcache on every deploy

The single most common 'why isn't my change showing' trap: with validate_timestamps=0, PHP won't see new code until you reload PHP-FPM or purge caches. Bake an OPcache clear into your deploy step.

Frequently asked questions

What are the most important Moodle performance settings?

PHP OPcache (memory 256MB+, max_accelerated_files ~16000, validate_timestamps=0 in production) and the database InnoDB buffer pool (sized to hold your working set, 60-70% of a dedicated DB server's RAM). Adding Redis for Moodle's MUC and sessions is the next biggest win.

What OPcache settings should I use for Moodle?

Enable OPcache with opcache.memory_consumption=256 (or 512 on large sites), opcache.max_accelerated_files=16000, opcache.interned_strings_buffer=32, opcache.save_comments=1, and opcache.validate_timestamps=0 in production - then clear OPcache on every deploy.

How big should the InnoDB buffer pool be for Moodle?

On a dedicated database server, roughly 60-70% of total RAM, so the buffer pool can hold your frequently accessed tables and indexes in memory. If the DB shares a box with PHP, size it more conservatively and plan to split the database out as you grow.

Does Redis really speed up Moodle?

Yes. Moving Moodle's Universal Cache (MUC) and sessions to Redis means repeated lookups for config, language strings and course data are served from memory instead of the database, cutting load and latency - and it's required for a multi-node setup.

Why isn't my Moodle change showing after I edit code?

With opcache.validate_timestamps=0, PHP keeps serving the cached bytecode until you clear OPcache. Reload PHP-FPM (systemctl reload php8.3-fpm) or purge caches after every deploy or plugin update.

Does upgrading PHP improve Moodle performance?

Yes - Moodle is CPU- and filesystem-heavy, and each modern PHP release is faster. Moving from PHP 7.x or 8.0 to 8.2/8.3, plus a properly sized realpath cache, delivers free, measurable speed gains.

Get Moodle tuned without the trial and error

These settings deliver most of the win, but the exact numbers depend on your RAM, traffic pattern and plugin mix. We tune, benchmark and monitor all of it as part of managed edzlms Moodle - so your team gets a fast site without becoming database administrators.

More in this series: the performance pillar and Spoke 1: hosting & server architecture.

Book a Free Demo

Prefer to pick a slot directly? Grab a time here, or email marketing@edzlms.com.

Written by Mihir Jana, founder of edzlms - connect on LinkedIn.

Tags

Moodle performanceOPcacheMySQL tuningMoodle hostingedzlms

See EdzLMS in action.

Book a 45-minute demo tailored to your industry.

Book a Free Demo →