For Moodle in 2026, Nginx paired with PHP-FPM is the throughput leader under concurrency and the mainstream recommendation. Apache with the event MPM plus PHP-FPM is a close, fully-supported second. Apache with mod_php (prefork) is the slowest and most memory-hungry option at scale and should be avoided for busy sites. Newer runtimes like FrankenPHP and Nginx Unit look promising in benchmarks but are not officially supported by Moodle, so keep them out of production. In practice the web server matters less than your PHP and database tuning - but the wrong choice (Apache prefork + mod_php) caps your ceiling no matter how well you tune the rest.
Key takeaways
- Moodle officially supports Apache and Nginx; both are solid when paired with PHP-FPM.
- Nginx + PHP-FPM generally holds throughput best under high concurrency and uses memory efficiently.
- Apache with the event MPM + PHP-FPM (proxy_fcgi) is competitive and fully supported - the key is avoiding prefork + mod_php.
- Apache prefork + mod_php ties a full PHP interpreter to every connection, so memory balloons and the ceiling drops under load.
- FrankenPHP and Nginx Unit show strong benchmark numbers but are not officially supported by Moodle - don't run them in production yet.
- This is Spoke 4, the finale of the Moodle performance series - the web server is the last lever after architecture, tuning and caching.
The final spoke of our Moodle Performance Optimization Guide (2026), after architecture, PHP/DB tuning and caching & CDN.
Does the web server really matter?
Honest answer first: for most Moodle sites the web server is not the biggest lever - OPcache, the database and caching move the needle far more. But the web server sets your concurrency ceiling: how many simultaneous requests you can serve before memory runs out or requests queue. Pick the wrong model and no amount of PHP tuning saves you under a traffic spike (think exam start, when everyone logs in at once). So it's worth getting right once, then forgetting about.
The deciding factor isn't really 'Apache vs Nginx' - it's how PHP is executed. Running PHP as a separate FPM pool (which both Nginx and modern Apache do) is efficient; baking PHP into the web server process with Apache's old mod_php + prefork is what causes the trouble.
The contenders
| Stack | Moodle support | Concurrency & memory | Verdict |
|---|---|---|---|
| Nginx + PHP-FPM | Supported | Event-driven; low memory per connection; excellent under load | Best all-round choice |
| Apache (event MPM) + PHP-FPM | Supported | Efficient event model; PHP runs as FPM | Great, fully supported alternative |
| Apache (prefork) + mod_php | Supported but discouraged at scale | One PHP interpreter per connection; heavy memory | Avoid for busy sites |
| FrankenPHP | Not official | Modern PHP app server; strong benchmarks | Promising - not for production Moodle yet |
| Nginx Unit | Not official | Multi-language app server; good numbers | Experimental for Moodle |
The pattern is clear: anything running PHP as a dedicated FPM pool (Nginx, or Apache event) performs well; the laggard is the legacy Apache prefork + mod_php combination that still ships as a default on some distros.
What the benchmarks show
Community load tests of Moodle across runtimes - for example the open moodle-runtime-compare project, which drives real Moodle with k6 - consistently point the same way: Nginx + PHP-FPM sustains the highest request throughput as concurrency climbs, with Apache event + PHP-FPM close behind. Apache prefork + mod_php falls off fastest because each connection carries a full PHP interpreter, so RAM is exhausted long before CPU. Newer runtimes like FrankenPHP post impressive raw numbers, but because they aren't officially supported you'd be trading a small speed gain for real compatibility and upgrade risk.
Treat any single benchmark as directional, not gospel - results shift with hardware, PHP version, OPcache and database tuning (see Spoke 2). The safe, evidence-backed default is Nginx + PHP-FPM, and the safe migration if you're on Apache is to move from prefork + mod_php to the event MPM + PHP-FPM without leaving Apache at all.
The recommended setup
A clean, fast Moodle front end on Nginx + PHP-FPM looks like this (pair it with the PHP-FPM pool sizing from Spoke 1):
# /etc/nginx/sites-available/moodle
server {
listen 443 ssl http2;
server_name lms.example.com;
root /var/www/moodle;
index index.php;
location / { try_files $uri $uri/ /index.php?$query_string; }
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}If you'd rather stay on Apache, switch the MPM to event and run PHP via FPM instead of mod_php:
# Apache: use event MPM + PHP-FPM (not prefork + mod_php) a2dismod php8.3 mpm_prefork a2enmod mpm_event proxy_fcgi setenvif a2enconf php8.3-fpm systemctl restart apache2
Either way, enable HTTP/2, keep TLS terminated efficiently, and let your CDN and caching layer serve static assets so the origin web server only handles dynamic PHP.
- 1Check how PHP is running
If it's Apache prefork + mod_php, that's your ceiling problem - plan to move to PHP-FPM.
- 2Default to Nginx + PHP-FPM
For a new build or a migration, this is the evidence-backed, low-memory, high-throughput choice.
- 3Or switch Apache to event + FPM
Staying on Apache is fine - just drop prefork + mod_php for the event MPM with proxy_fcgi.
- 4Turn on HTTP/2 and offload statics
Serve CSS/JS/media via CDN so the web server only processes dynamic requests.
- 5Load-test your real peak
Simulate an exam-start spike with k6 or similar and confirm throughput holds; don't rely on generic benchmarks.
- 6Skip unsupported runtimes in prod
Leave FrankenPHP / Nginx Unit for experiments until Moodle supports them officially.
Apache prefork + mod_php
- A full PHP interpreter per connection
- Memory balloons under concurrency
- Lowest ceiling at exam-time spikes
- Still a distro default in places
- Tune all you like - it caps you
Nginx + PHP-FPM (edzlms default)
- Event-driven, low memory per connection
- Highest sustained throughput in tests
- PHP runs as an independent FPM pool
- HTTP/2 + efficient static handling
- Scales cleanly with the FPM worker count
Not sure what your Moodle is running on?
Many slow Moodle sites are quietly on Apache prefork + mod_php. edzlms runs Moodle on tuned Nginx + PHP-FPM with HTTP/2 and a CDN, benchmarked for your real concurrency - we'll audit your stack and show the gap.
You don't have to leave Apache
If you're on Apache and it 'feels slow', you may only need to switch from prefork + mod_php to the event MPM with PHP-FPM. That single change removes the per-connection PHP memory cost - no platform migration required.
Frequently asked questions
What is the fastest web server for Moodle?
Nginx paired with PHP-FPM generally delivers the highest throughput for Moodle under concurrency while using memory efficiently, which is why it's the mainstream recommendation. Apache with the event MPM plus PHP-FPM is a close, fully-supported alternative.
Is Apache or Nginx better for Moodle?
Both are officially supported and perform well when PHP runs as a separate FPM pool. Nginx + PHP-FPM tends to lead on throughput and memory efficiency. The real mistake is Apache with prefork + mod_php, which caps concurrency; switching Apache to the event MPM + PHP-FPM closes most of the gap.
Why is Apache mod_php (prefork) slow for Moodle?
With prefork + mod_php, every connection carries its own full PHP interpreter, so memory is consumed per connection and the server runs out of RAM under load long before CPU. Running PHP as an FPM pool (with Nginx or Apache event) avoids that.
Can I run Moodle on FrankenPHP or Nginx Unit?
They show strong benchmark numbers, but neither is officially supported by Moodle, so they're not recommended for production. You'd risk compatibility and upgrade issues for a small speed gain. Stick with supported Nginx or Apache + PHP-FPM.
Does the web server matter more than PHP and database tuning?
No - OPcache, the InnoDB buffer pool and caching usually move performance more. But the web server sets your concurrency ceiling, so the wrong model (Apache prefork + mod_php) can cap you no matter how well you tune everything else.
How should I test which is faster for my Moodle?
Run a load test that simulates your real peak - for example an exam start where many users log in at once - using a tool like k6 against your actual content. Generic benchmarks are directional; your hardware, PHP version and tuning change the result.
Get the whole stack right, once
The web server is the last piece of the performance puzzle - and the easiest to get wrong by inheriting a distro default. edzlms runs Moodle on tuned Nginx + PHP-FPM with HTTP/2, Redis caching and a CDN, benchmarked for your real concurrency, so you never hit an avoidable ceiling.
The full series: pillar, architecture, PHP/DB tuning and caching & CDN.
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.