Realistic concurrent user estimates for Moodle with SCORM + quizzes?

Realistic concurrent user estimates for Moodle with SCORM + quizzes?

by Alex Brooke -
Number of replies: 3

Hi everyone,

We’re trying to work out the right server capacity and architecture for a Moodle deployment, and would really appreciate some real-world guidance.

Context

We’re building a Moodle platform for paid courses with:

  • SCORM tracking

  • quizzes (including peak exam periods)

  • international users across multiple timezones

We expect gradual growth over 2–3 years, but with spikes during exams.

Current thinking 

From Moodle documentation, we understand a rough guideline of:

~1GB RAM per ~50 concurrent users

However, given SCORM + quiz-heavy usage, network speed etc, we’re being more conservative and working closer to:

~10–15 concurrent users per 1GB RAM

We’re also planning to use:

  • Redis (object + session caching)

  • OPcache

Rough sizing model

Based on that, we’re currently thinking along these lines:

  • 100 concurrent → ~16GB VPS

  • 200 concurrent → ~32GB VPS

  • 300–400 concurrent → ~64GB VDS

  • 500–700 concurrent → ~128GB VDS (upper limit of single server)

  • ~700+ concurrent → begin splitting into:

    • app server (handles user activity: pages, quizzes, logins)

    • database server (handles data: courses, users, results)

Does this general progression — and especially the ~700 concurrent split point — match real-world experience for quiz/SCORM-heavy workloads?

Key questions

  1. What actually becomes the bottleneck first in practice?
    (RAM vs database vs CPU vs disk I/O)

  2. Are we being too conservative — or not conservative enough — for this type of workload?

  3. At what point did you need to split the database onto a separate server?
    (e.g. number of concurrent users or specific issues)

  4. Is there anything important we’re missing in this model?
    (e.g. caching layers, DB tuning, storage performance, etc.)

  5. Any recommendations for load testing tools for Moodle?
    (JMeter, k6, etc.)

Goal

We’re trying to strike a balance between:

  • avoiding performance issues during peak usage

  • not over-engineering too early


Real-world numbers or “we hit issues at X concurrent users” would be hugely appreciated.

Thanks in advance

Average of ratings: -
In reply to Alex Brooke

Realistic concurrent user estimates for Moodle with SCORM + quizzes?

by Emilio Penna -
Hi Alex,

Your questions are very relevant — we've been doing systematic load testing on a Moodle 4.5 quiz deployment and our findings challenge some of the assumptions in the standard documentation. I'll share what we observed, though keep in mind our context is quiz-only (no SCORM), so some points may not transfer directly.

*RAM is not the bottleneck — CPU is*

With PHP-FPM + OPcache + a separated DB server, we found that RAM consumption was surprisingly modest. At 2000 simultaneous virtual users completing a 16-question quiz, peak used RAM on the app server (12 vCPU / 12 GB) was around 1.6 GB. The working set per PHP-FPM worker is roughly 60–70 MB private RSS, with the OPcache shared once across all workers. Swap use was zero throughout. Keep in mind that some RAM is used by SO buffers and caches, and that is important because we use the default file cache for MUC. In our environment, 12gb was enough for all in the app server.

The actual bottleneck was CPU — specifically during the synchronized exam start spike, when all students click "Start attempt" within a short window.
That's when load average spiked to ~8 on 12 vCPUs (~65% saturation) at 2000 VUs, recovering within 2 minutes. All subsequent quiz navigation remained stable.

This matters for your sizing model: the ~1 GB per 50 users guideline (and even your more conservative 10–15 users/GB) appears to be a legacy of mod_php architectures without OPcache, where each Apache process carries a full PHP interpreter. With PHP-FPM + OPcache, that model overestimates RAM needs significantly. (Maybe is time to update that moodle docs)

*What actually becomes the bottleneck first*

In our architecture (PHP-FPM 8.3, OPcache, MySQL on a separate server):
CPU on the app server was the first constraint, driven by the synchronized exam start. The DB server was not a functional bottleneck, The key for DB performance was ensuring the working dataset fits in the buffer pool — our DB server has 16 GB RAM, which was sufficient.

*When to split the DB*

We had the DB on a separate server from the start, so we can't give you a "we hit a wall at X users and then split" data point. What we can say is that with a separated DB and adequate buffer pool, the DB was a non-issue at 2000 VUs. At 3000 VUs the app server CPU was clearly stressed during the exam start spike, but the DB server still had significant headroom.
Separating the DB early seems worthwhile mainly because it gives you independent scaling levers — not because RAM on a combined server runs out.

*The exam start spike is the critical design point*

For quiz-heavy deployments, the worst-case scenario isn't sustained concurrent load — it's the moment when hundreds of students all start an exam simultaneously. This produces a very sharp, short CPU spike that is disproportionate to the steady-state load. A system that handles 2000 users comfortably during exam navigation can still struggle at the synchronized start. Worth factoring this into your capacity planning,
especially if you run large scheduled exams.

We also analyzed entry patterns from real exam data. Looking at exams with 200 -1500 participants, we found that in roughly 10% of cases more than 67% of students started within the first 30 seconds. That's the figure we used to calibrate the Gaussian Random Timer in our JMeter script — so the simulated spike reflects an actual worst-case observed in production, not just a theoretical scenario.

*On your sizing progression*

Your numbers seem very conservative for RAM if you're using PHP-FPM + OPcache + Redis. You may be significantly over-provisioning RAM while under-provisioning CPU cores. I'd suggest thinking in terms of vCPU count relative to expected concurrent exam starts, rather than GB of RAM per user. Adding Redis for object/session caching is a good call and should reduce PHP processing per request noticeably.

*Load testing*

We used Apache JMeter 5.6.3 with a custom script that covers the full quiz flow: login, course navigation, exam start (with a Synchronizing Timer to simulate the simultaneous start spike), answering all questions, and finishing the attempt. The synchronized start is the most important thing to simulate — generic load tests that don't model it will give you an unrealistically optimistic picture.

We've documented our test setup, script, and results here if it's useful:
https://www.proyectos.udelar.edu.uy/redmine/projects/moodleperf/wiki/


The results page covers infrastructure metrics (CPU, RAM, PHP-FPM pool, DB I/O) across multiple load levels, and the setup page includes the JMeter script and quiz backup for anyone who wants to replicate the tests.

One caveat: our tests cover quiz workloads only. SCORM tracking adds different patterns (more frequent small write requests for xAPI/SCORM data, different DB access patterns) that we haven't characterized. Your conservative approach there is probably warranted until you have workload-specific measurements.

The script covers the main interactions well enough for capacity planning purposes, but there is room for improvement — in particular, better coverage of AJAX calls and a more realistic static resource model. I'm planning a revised version for Moodle 5 when time allows. If you have suggestions or feedback for that future version, I'd appreciate hearing them.

Beyond the load tests, we also have 6 years of production experience with this infrastructure. We have run exams with up to 1500 simultaneous students without issues. That real-world data point aligns well with what the load tests show: the system handles that scale comfortably, with headroom to spare.

Hope this helps — happy to answer questions about the test methodology or results.
Average of ratings: Useful (5)
In reply to Emilio Penna

Realistic concurrent user estimates for Moodle with SCORM + quizzes?

by Alex Brooke -

Hi Emilio,

Thank you SO much for your detailed and relevant response. This is incredibly helpful and I really appreciate the detail and time you put into your response. 

We are a small team new to server infrastructure, and the level of detail you shared — real production numbers, actual RAM usage at 2,000 virtual users, the exam start spike analysis, the 67% in 30 seconds figure from real exam data — that's changed our approach. We had been building an entire plan around RAM as the primary constraint. Your response made us rebuild it from scratch around CPU cores, which seems to be the right way to think about it.

Thanks also for the link to your test data, that's extremely useful! 

For anyone following this thread, here is what we landed on based on the advice received:

Case 1 projection: — Hosting.com VDS Premium 64, 24 dedicated cores / 64GB RAM / NVMe SSD, single server, up to 400 concurrent users. PostgreSQL 16 from day one for future cloud migration, Redis for session and object caching.

Case 2 projection: — Upgrade to VDS Premium 128 (32 cores) when CPU hits 70%+ at exam spikes. Same single-server architecture.

Case 3 projection:  — Split app and database onto separate VDS servers at around 700+ concurrent, likely 1-2 years from now.

We sized everything using 20 users per vCPU core as the worst-case figure for exam spike load, with the 67% simultaneous start figure as the design scenario. The VDS 64 gives us 71% CPU headroom above the minimum for a 400-user deployment which feels right. (Feel free to blast these figures out of the water if you feel these are wrong) 

It’s possible we’ll split the server from the start of this project as you had done but we’re going to see how far a single server can take us for now. 

Thank you again — your years of production experience distilled into one forum post is an incredibly generous contribution. It’s most appreciated! 

In reply to Alex Brooke

Realistic concurrent user estimates for Moodle with SCORM + quizzes?

by Visvanath Ratnaweera -
Picture of Particularly helpful Moodlers Picture of Translators
Hi

The big obstacle in estimating infrastructure for large Moodle deployments is that, every deployment is different - in terms of the infrastructure and the architecture as well as the user loads and patterns. In your case we know that it is a) about a single server - a large VPS b) you have targets on N, N being the number of candidates you can send to a synchronous exam (on Quiz module). Well, you said something about SCORM - still in the subject line. I think, you were forced to forget it, for the sake of simplicity.

You were lucky. Emilio could give you custom tailored and exact (with numbers) advice, as he has done in the past in this forum and also presented in Moodle Moots. I've added his post to my collection, suggest adding it to the Performance documentation as well. Rather than reiterating those topics here are some observations from an administrative point of view.

About the timing of the exams: You talk of a world-wide audience. Do they belong to the same institution? If not, it is highly unlikely that synchronous exams of different institutions will start exactly at the same universal time.

About the readiness of the server: Do you expect the N candidate exam will be conducted the day you deploy the server? What I want to point out is that deploying a Moodle server is fundamentally different from building a fortress or a battleship. a) It won't be stormed the day it goes in operation. b) Even if that happens, you can still make corrections. In other words, a gradual start and corrections as you go on are (luckily) possible.

My interest is not primarily getting big absolute numbers of load, rather getting the maximum load from given resources resp. servicing a given load with minimum resources. Throughout the years I have observed people (including myself) overestimate the future load resp. astronomically overestimate the infrastructure necessary. OK, some have the money. But I plead for the environment, the time of "My car, my patrol" is long over.
 
Don't read between the lines: Nowhere I say, you are wasting resources. In fact, you made a favourable decision by going for VPS over dedicated hardware (which would idle, still burn energy, until the load arrives). My point at the beginning with fortresses and battleships is that singe or dual (web+DB) Moodle servers are flexible, you can shift them easily, once you've got the experience. That is exactly what I advised more than once, start in the available/existing infrastructure, monitor deeply, once signs of overloading appears, move to the next level. Not to commit to a five year plan NOW - although it is technically challenging and therefore interesting. You can have the same fun by squeezing smaller machines. Do you need a Porsche for the kick of speed, when downhill on a racing bicycle would do?
smile