Hosting Moodle for Education: A Training Platform That Doesn't Crash on Exam Day

A Moodle platform succeeds or fails by how it handles the concurrent spike on exam day. Here is the spec for 100, 500, and 1000 concurrent learners, and why PHP OPcache and Redis sessions separate a resilient system from one that freezes.
A Moodle platform is not tested on an ordinary day, it is tested on exam day when hundreds of learners log in within the same minute. The practical rule is that every hundred concurrent learners need about two CPU cores and four to six gigabytes of RAM on a tuned server, so five hundred concurrent learners need six to eight cores and twelve gigabytes or more, and a thousand concurrent learners start with the database split onto its own server alongside a strong application server. The decisive factor is not plan size alone but three settings: enabling PHP OPcache to cache compiled code so CPU load drops by more than 50%, moving sessions to Redis instead of disk files so the platform survives the spike, and tuning the MariaDB database to serve repeated queries from memory. Hosting inside Saudi Arabia gives about 8ms latency from Riyadh, which means opening the exam page and saving an answer happen instantly rather than after a delay that worries the student. Add a scheduled backup before every semester starts, and keep student data on a Saudi server to respect data sovereignty, and you get a training platform that holds up when it matters.
The Education Load Pattern Is Entirely Different
Most websites receive traffic spread across the day, but a learning platform has load clustered in sharp spikes. Minutes before an exam, students open the page all at once, and when time ends everyone hits submit within seconds of each other. This pattern makes the daily average completely misleading: the server might run at 10% all day then jump to 100% for ten minutes. Sizing on the average is a disaster, and the correct approach is sizing on the expected peak plus a 30% safety margin.
There is a difference between an enrolled learner and a concurrent learner. A university with ten thousand students might peak at just fifteen hundred concurrent during its largest exam. Calculate the peak from the largest simultaneous exam expected, not the total enrolled, because this saves you from buying resources used only in theory.
The Spec for Every Size by the Numbers
The table below maps concurrent learners to Cloud plans with the mandatory tuning for each level:
| Concurrent | Plan | Suggested add-ons | Mandatory tuning | Approx. annual cost |
|---|---|---|---|---|
| Up to 100 | Business 4vCPU/8GB | Daily backup 30-day (2,000) | OPcache + Redis sessions | About 13,500 SAR |
| Up to 500 | Enterprise 8vCPU/16GB | +4GB RAM (1,200) + daily backup (2,000) | OPcache + Redis + MariaDB tuning | About 21,200 SAR |
| Up to 1000 | Enterprise + database on a second server | Growth DB server + daily backup + DDoS (1,200) | Tier separation + Redis cache | About 29,000 SAR |
Prices are annual including 15% VAT. Business starts at 11,500 SAR and Enterprise at 18,000, with automatic activation within seconds. See details on the pricing and plans page or start configuring from the Cloud Server page. Note our RAM add-on is +2GB at 600 SAR, so four gigabytes cost 1,200 SAR per year, and the bandwidth add-on is +1TB at 1,150 SAR if your platform streams heavy educational video.
PHP OPcache: The First Setting You Enable
Moodle is a large PHP application with thousands of files, and without OPcache the CPU recompiles the code on every request, which is plain waste. Enabling OPcache stores compiled code in memory, cutting CPU consumption by more than half under load. Suggested values: opcache.memory_consumption between 256 and 512 MB for a large platform, opcache.max_accelerated_files at least 20000 because Moodle has many files, and opcache.validate_timestamps off in production with a manual cache clear on update. This single setting can double the same server's capacity to absorb concurrency.
Redis for Sessions: The Difference on Peak Day
By default Moodle stores user sessions as files on disk, and this becomes a fatal bottleneck when five hundred students log in within a minute, because each request locks and opens the session file. Moving sessions to Redis keeps them in memory so they are served in fractions of a millisecond, and it eliminates lock contention entirely. Use Redis also as an application cache layer to greatly relieve database pressure. Redis is lightweight and runs on the same server for medium sizes, moving to a dedicated server at a thousand concurrent.
Tuning the MariaDB Database
The database is the first resource to collapse on exam day if neglected. The most important value is innodb_buffer_pool_size, ideally 60% to 70% of the database server's RAM, so repeated queries are served from memory not disk. Also set:
- innodb_buffer_pool_size = about 10GB on a sixteen-gigabyte server.
- innodb_log_file_size = 512 MB to 1 GB to absorb write waves at submission time.
- max_connections = 300 to 500 depending on expected concurrency.
- tmp_table_size and max_heap_table_size = 128 MB to reduce on-disk temporary tables.
At a thousand concurrent, split the database onto its own server so the application and database do not compete for the same cores and memory. This separation is the biggest performance jump after OPcache and Redis.
Backup Before Semesters and Data Sovereignty
A failed update or accidental deletion always happens at the worst time. Enable daily backup with 30-day retention, and take an extra manual backup before every semester starts and before any Moodle version upgrade. The backup must include the database and the moodledata folder together, because restoring one without the other is useless. Data sovereignty is a serious matter in education: student data, grades, and personal information must stay on a Saudi server, and about 8ms latency from Riyadh keeps the experience smooth for student and teacher alike. If you run AI tools to assist grading or summarizing, the AI Hosting page gives you a ready template on the same Saudi infrastructure.
Static Content and Cron Job Tuning
A large part of the Moodle load is not dynamic pages but static files: lesson images, PDFs, video clips, and JavaScript and CSS files. Serving these files directly from the web server without going through PHP processing relieves the load significantly, so enable browser caching via response headers with a long validity period for static files, so the student loads them once then serves them from their browser on subsequent visits. If your platform streams heavy educational video, watch bandwidth consumption, and our bandwidth add-on of +1TB at 1,150 SAR per year suffices for most medium platforms.
Scheduled cron jobs in Moodle are a sensitive matter that is often overlooked. Moodle relies on running cron every minute to send notifications, process queues, update indexes, and handle deferred tasks. If cron does not run regularly, tasks pile up and obscure problems appear on exam day such as notifications not sending or grades appearing late. Set cron to run exactly every minute, and give it enough resources so it does not compete with user requests at peak. At large sizes, direct heavy task processing (such as report generation or backups) to night hours away from exam times, so full resources remain for students during the day. Also watch the cron task log in the Moodle admin panel, because if you see a task taking unusually long it is a sign of a slow database query worth investigating before it worsens on peak day.
A Checklist Before Exam Day
Choose the plan by the largest expected concurrent exam, not total students, and add a 30% margin. Enable OPcache and move sessions to Redis before anything else, because they are cheaper than upgrading the plan and more impactful. Tune MariaDB with the buffer pool values above, and run a load test at a concurrency near the peak a week before the real exam. Take a manual backup on the morning of exam day. When you consistently exceed five hundred concurrent, split the database onto its own server from the Cloud Server page. Also review the session timeout settings so student sessions are not dropped during a long exam, because dropping a session mid-exam is a disaster avoidable with a simple setting. The bottom line: size for the peak, enable the cache, and separate the tiers as you grow.


