Skip to main content
Engineering Manual • Infrastructure

Moodle on AWS, Architected for Exam Day.

Moodle fails at the worst moment because one server holds everything: app, database, files, sessions. This guide separates the layers on AWS so each scales on its own — and says plainly when a single good instance is the smarter architecture.

By Baber Sheikh, Tech Lead at LMSOps · Published October 17, 2026 · Updated October 17, 2026

The short answer: Run Moodle on AWS as separate layers: an Application Load Balancer in front of two or more EC2 app nodes, RDS or Aurora for the database, S3 for moodledata, and ElastiCache Redis for sessions and the MUC cache. App nodes stay stateless so autoscaling can add them during exam peaks. Below roughly 300 concurrent users, one well-tuned instance plus RDS is usually the better spend.

The four layers and why each exists

  • Load balancer (ALB) — spreads learners across app nodes and survives a node failure
  • App nodes (EC2) — PHP-FPM tuned Moodle code only; no user files, no sessions
  • Database (RDS / Aurora) — managed MySQL-compatible storage with automated backups
  • Files (S3) — moodledata filedir in object storage, shared by every node

Sessions and cache are the layer everyone forgets: with more than one app node, PHP sessions and Moodle's cache must live in Redis (ElastiCache), or learners get logged out mid-quiz as the balancer moves them between nodes.

The config.php that makes it work

The heart of the setup is a handful of configuration lines. S3 storage uses the object storage plugin; Redis handles sessions and caching:

$CFG->dboptions = ['dbpersist' => false];
// Sessions in Redis
$CFG->session_handler_class = '\core\session\redis';
$CFG->session_redis_host = 'your-elasticache-endpoint';
// MUC cache store: Redis (configured in Site admin > Plugins > Caching)
// Files: tool_objectfs plugin pointing at your S3 bucket

Keep config.php identical on every node (deploy it, do not hand-edit), and put the code itself under version control so a replacement node is a launch, not a rebuild.

Autoscaling rules that match school traffic

School traffic is spiky in predictable ways: morning logins, exam windows, assignment deadlines. Scale on a schedule where you can (exam weeks), on CPU and PHP-FPM saturation where you cannot. Two rules carry most institutions:

  • Minimum 2 app nodes during term time — one can die without an outage
  • Scale-out trigger: sustained CPU above 65% or FPM queue growth for 5 minutes
  • Scale-in slowly (30+ minutes) — flapping nodes churn sessions and caches

Load test before the first real exam window: simulate your expected concurrent quiz attempts, not page views. Quizzes are the heaviest thing Moodle does, and they arrive all at once.

Backups, monitoring and the boring essentials

RDS automated backups with point-in-time recovery, S3 versioning on the file bucket, and a weekly restore test — a backup never test-restored is a hope, not a backup. Monitor the things that predict pain: database connections, slow query log, Redis memory, and Moodle cron/task failures, with alerts to a human.

When you should not build this

Under a few hundred concurrent users, this architecture is resume decoration. A single well-tuned EC2 or VPS instance with RDS (or even local MariaDB), Redis on the same box, daily backups and OPcache will outperform a badly-run cluster at a tenth of the cost and complexity. We deploy both shapes; the honest recommendation depends on your peak concurrency, which is why every AWS engagement starts with sizing questions, not a shopping list.

Frequently asked questions

How much does Moodle on AWS cost per month?

It depends on size. A single-instance setup commonly runs $25–$80/month in AWS charges. The multi-node architecture in this guide typically starts around $150–$300/month. Our deployment is a fixed $200, migration $300 — AWS bills are yours, in your account, with no markup from us.

Do we need Aurora, or is plain RDS enough?

Plain RDS (MariaDB or MySQL) is enough for most institutions. Aurora earns its price at high write concurrency — very large exam sittings — or when you want its faster failover. We size from your numbers, not from AWS marketing.

Can we start small and scale later?

Yes — that is the recommended path. Deploy single-instance with S3 and Redis from day one, and adding the load balancer plus a second node later becomes an afternoon's work instead of a migration.

Is our student data safe in S3?

With the right configuration, yes: private bucket, no public access, encryption at rest, and access only through Moodle's signed delivery. We configure and verify permissions as part of deployment.

Who manages this after setup?

You can, or our support plans from $79/month cover updates, monitoring, backups and emergency response on AWS-hosted Moodle.

About the author

Baber Sheikh is the senior Moodle engineer and Tech Lead behind LMSOps — deployment, migration, upgrades and custom plugin work for schools, training providers and universities, at fixed published prices.

Want this architecture without the learning curve?

Tell us your learner count and peak exam concurrency. We reply with a right-sized AWS design and a fixed setup quote — including if the right design is one instance.

Design My AWS Setup

The service page: Moodle AWS hosting · See fixed rates