Moodle Performance Optimization: The Complete 2026 Guide

A complete 2026 guide to Moodle performance - architecture, PHP and OPcache, MySQL/MariaDB tuning, Redis caching and CDNs - with the settings that actually move the needle for any LMS.

ET
EdzLMS Team
·28 June 2026·10 min read
⚡ Quick answer

Moodle performance comes down to five levers: a right-sized hosting architecture, PHP with OPcache, a tuned database (InnoDB buffer pool), in-memory caching with Redis (sessions + MUC), and a CDN for static media. The biggest single wins are enabling OPcache, setting innodb_buffer_pool_size to about 70% of RAM, and moving sessions and Moodle's cache to Redis. And it is not cosmetic: every 100ms of latency measurably cuts engagement and course completion. edzlms offers fully managed, performance-tuned Moodle hosting so you never fear exam day.

~1%
Drop in user actions for every 100ms of added latency
~70%
Of RAM to give innodb_buffer_pool_size - the biggest DB win
<10 min
Session length that sees ~80% completion - speed keeps sessions short
400M+
Learners on Moodle worldwide - a proven, tunable platform

Key takeaways

  • Performance is a learning-outcome issue: slow pages raise drop-off and lower completion.
  • Five levers drive Moodle speed: architecture, PHP/OPcache, database, caching and CDN/web server.
  • Enable OPcache, size the InnoDB buffer pool to ~70% RAM, and move sessions + MUC to Redis first.
  • Always benchmark before and after - measure, don't guess, and load-test the real workflows.
  • Scale by separating services (DB, cache) and, eventually, load-balancing web nodes.
  • These principles apply to any PHP-based LMS, not just Moodle - edzlms can run it all for you.

Why LMS performance is not cosmetic

Two Moodle sites on identical hardware can feel completely different: one is smooth during finals week, the other buckles at login. The difference is configuration - and the stakes are higher than they look. In web performance, every extra 100ms of latency costs roughly 1% of conversions; on a learning platform, that same friction shows up as learners abandoning a quiz, skipping a module, or never finishing the course.

Fast, reliable delivery keeps sessions short and focused - and short, interactive sessions under ten minutes see the highest completion rates. So performance tuning is really completion tuning. Everything below is written for Moodle, but the same five levers apply to any PHP-based LMS or learning application. If you are also planning a move, pair this with our Moodle migration guide and Moodle deployment options.

The five levers of Moodle performance

Get these right, in this order, and most Moodle sites become fast and predictable:

  1. Architecture - match your server layout to your concurrent users.
  2. PHP + OPcache - modern PHP, a tuned FPM pool, and OPcache so code isn't re-parsed every request.
  3. Database - a correctly sized InnoDB buffer pool and sane connection limits.
  4. Caching - Redis for sessions and Moodle's cache (MUC) instead of disk or database.
  5. Web server + CDN - Nginx/PHP-FPM, compression, a CDN for static media, and CLI cron.

Each lever gets its own deep-dive in this series; here is the working overview of all five.

Lever 1: Right-size your architecture

Moodle behaves like a serious web application, not a brochure site. Choose a layout for your concurrency:

  • Single server (up to a few hundred concurrent users) - web server, PHP-FPM, MySQL/MariaDB and Redis on one VPS or dedicated box with fast NVMe storage. A 2-4 vCPU / 4-8 GB box is often enough when tuned well.
  • Separated database and cache (hundreds to ~1,000 concurrent) - one node for web + PHP-FPM, a dedicated database node, and optionally a separate Redis node. Expect 4-8 vCPU and 8-16 GB RAM as you grow.
  • High availability / clustering (multi-thousand concurrent) - multiple web + PHP nodes behind a load balancer, a primary/replica database, and a highly available Redis cluster.

Rule of thumb: size for concurrent users, not total accounts, and separate the database once contention appears (usually past ~1,000 concurrent learners).

Lever 2: PHP and OPcache

Moodle is a large PHP codebase, so PHP execution is one of the easiest wins. Run a modern PHP 8.x with PHP-FPM (not mod_php), set sensible limits, and - most importantly - enable OPcache so hundreds of files aren't re-parsed on every request.

; php.ini - core Moodle settings
memory_limit = 512M
max_execution_time = 300
upload_max_filesize = 512M
post_max_size = 512M
max_input_vars = 5000        ; big question banks / permissions forms

; OPcache - mandatory for serious Moodle performance
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 256   ; 256-512 for large sites
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0    ; 0 in prod; purge OPcache on deploy

For PHP-FPM, size pm.max_children from your real average process memory (check RSS under load, reserve RAM for the OS/DB/cache, divide the rest). If FPM workers are always maxed and requests queue, users feel slowness even when CPU isn't full.

Lever 3: Database (MySQL / MariaDB)

Moodle is write-heavy (logs, quiz attempts, tracking), so the database is often the biggest gain after PHP caching. The single most impactful change is sizing the InnoDB buffer pool so hot data stays in RAM.

[mysqld]
innodb_buffer_pool_size      = 4G     ; ~50-70% of RAM on a DB-focused server
innodb_buffer_pool_instances = 4      ; 2-8 for larger pools
innodb_log_file_size         = 512M   ; smooth checkpoints for write-heavy load
innodb_flush_log_at_trx_commit = 2
max_connections              = 200    ; just above total PHP-FPM children
thread_cache_size            = 50
wait_timeout                 = 600
query_cache_type             = 0      ; disable legacy query cache
query_cache_size             = 0

Disable the legacy query cache (a contention point on write-heavy sites), enable the slow query log, and review it - custom reports and third-party plugins are the usual source of unindexed, slow queries. Put the database and logs on NVMe/SSD.

Lever 4: Caching with Redis (sessions + MUC)

By default Moodle can store sessions in the database and many caches on disk - both slow under load. Move sessions and Moodle's Universal Cache (MUC) to Redis (Memcached also works, but Redis adds persistence). Point PHP sessions at Redis in config.php:

// config.php - store sessions in Redis
$CFG->session_handler_class = '\\core\\session\\redis';
$CFG->session_redis_host = '127.0.0.1';
$CFG->session_redis_port = 6379;
$CFG->session_redis_database = 0;

Then, in Site administration > Plugins > Caching, map high-traffic cache definitions (language strings, config, core data) to a Redis store, keep small low-frequency ones on file, and check hit rates with Moodle's cache diagnostics. For heavy read pages served to guests, a short microcache (1-5 seconds) at the reverse proxy can cut PHP load dramatically - just be careful with logged-in users.

Lever 5: Web server, CDN and cron

Use Nginx with PHP-FPM for large sites (Apache is fine for small ones), keep HTTP keep-alive on, and enable gzip/Brotli compression. Offload static assets - CSS, JS, images, course media - to a CDN (for example Cloudflare) with long cache TTLs and asset versioning; unoptimised media is one of the most common causes of slow Moodle pages. Finally, always run Moodle's cron from the command line, not web-initiated:

# system crontab - run Moodle cron every minute from CLI
* * * * * /usr/bin/php /var/www/moodle/admin/cli/cron.php >/dev/null 2>&1

CLI cron avoids web timeouts and keeps background work (notifications, cleanup, analytics) from clashing with real users. Watch that cron runtime doesn't regularly overlap itself.

Benchmark before and after (and pick your runtime)

Never tune blind. Capture a baseline, change one thing, and re-measure the same workflows (login, quiz start, quiz submit, reports) with a load-testing tool like k6. In head-to-head tests, traditional stacks - Apache (mod_php or PHP-FPM) and Nginx + PHP-FPM - run Moodle reliably across load levels, while newer runtimes like Nginx Unit and FrankenPHP are not officially supported. Nginx + PHP-FPM tends to hold throughput best as concurrency climbs.

Pre-exam checklist: confirm OPcache is on and not restarting; sessions and key caches are on Redis; the InnoDB buffer-pool hit ratio is high; PHP-FPM slow logs are clean; and you've load-tested the real workflows.

  1. 1
    Baseline first

    Load-test login, quiz start/submit and reports so you can prove each change actually helped.

  2. 2
    Enable and size OPcache

    The fastest single win - stop PHP re-parsing Moodle's code on every request.

  3. 3
    Tune the InnoDB buffer pool

    Set innodb_buffer_pool_size to ~50-70% of RAM and enable the slow query log.

  4. 4
    Move sessions and MUC to Redis

    Get sessions and hot caches off disk/database and into memory.

  5. 5
    Add a CDN and compression

    Offload static media and enable gzip/Brotli to cut origin load and latency.

  6. 6
    Load-test and monitor

    Re-run the tests, then watch CPU, RAM, iowait, FPM queue, DB hit ratio and cache evictions.

Under-tuned Moodle

  • No/undersized OPcache
  • Sessions and caches on disk or DB
  • Tiny InnoDB buffer pool, slow queries
  • Struggles the moment a class starts a quiz

Performance-tuned Moodle

  • OPcache sized to the codebase
  • Redis for sessions + MUC
  • Buffer pool ~70% RAM, slow log reviewed
  • CDN + compression; calm on exam day

edzlms managed Moodle

  • We tune PHP, DB and caching for you
  • Right-sized architecture + monitoring
  • Load-tested before peak events
  • Or move to the managed edzlms platform
💡

Let edzlms keep your Moodle fast

edzlms provides managed, performance-tuned Moodle hosting - PHP/OPcache, database and Redis caching configured and monitored, load-tested before exam season. Prefer to hand it off entirely? Move to the fully managed edzlms platform and stop worrying about servers.

The bottom line

Fast Moodle isn't about exotic tweaks - it's the fundamentals done consistently: modern PHP with OPcache, a right-sized InnoDB buffer pool, Redis for sessions and cache, a CDN for media, and CLI cron. Get the architecture right, measure, and make small targeted changes. Your learners feel it as smoother pages - and finish more of what they start.

This is Part 1 of our Moodle & LMS performance series. Next up: hosting architecture, deep PHP/database tuning, and caching with Redis and CDNs.

Book a Free Demo →

Frequently asked questions

How much CPU and RAM does a Moodle server need?

It depends on concurrent users, not total accounts. Up to ~50-100 concurrent: 2-4 vCPU and 4-8 GB RAM with NVMe, well tuned. For 200-500 concurrent: 4-8 vCPU and 8-16 GB, often with a separate database server. Beyond that, add web nodes, a dedicated DB and a Redis cache. Always load-test real workflows.

What is the single biggest Moodle performance win?

Two things: enable OPcache so PHP isn't re-parsed each request, and size innodb_buffer_pool_size to about 50-70% of RAM so hot data stays in memory. Then move sessions and Moodle's cache to Redis.

Should I use Redis or Memcached for Moodle?

Redis is the better default - it supports persistence and richer data types, so you can safely hold sessions and multiple cache definitions. Memcached is fast but loses everything if the process restarts. Many admins use Redis for both sessions and MUC.

Nginx or Apache for Moodle?

Both work. Apache is fine for small to medium sites; Nginx with PHP-FPM tends to scale better under high concurrency. In benchmarks, Nginx + PHP-FPM holds throughput well as load climbs. Avoid unsupported runtimes (Nginx Unit, FrankenPHP) for production.

Do I need a CDN for Moodle?

For small sites, strong PHP/DB/Redis tuning may be enough, but a CDN significantly cuts latency and origin load by serving static assets - CSS, JS, media - from edge servers, especially for geographically spread learners.

Why does Moodle slow down only under load?

Usually an undersized OPcache evicting scripts, PHP-FPM workers maxing out and queuing, a too-small InnoDB buffer pool causing disk reads, or sessions/caches on disk. Benchmark under load to find which one, then fix that lever.

Does this apply to other LMS platforms?

Yes. The same levers - architecture, PHP/OPcache, database tuning, in-memory caching and a CDN - speed up any PHP-based LMS or learning app. edzlms applies them across the platforms we manage.

See EdzLMS in action.

Book a 45-minute demo tailored to your industry.

Book a Free Demo →