Moodle is one of the most popular open source learning management platform empowering educators and researchers across the world to disseminate their work efficiently. It is also one of the most matured and robust OSS application which is developed and improvised by the community over the years. We have seen customers deploying Moodle in Azure from small, medium and large enterprises to schools, public sector and government organizations. In this blog post, I will be sharing some of the best practices and tips for deploying Moodle on Azure based on our experience working with some of our customers.
If you have Azure account, you can deploy Moodle via the Azure portal using the button below, or you can deploy Moodle via the CLI. Please note that while you can use an Azure free account to get started depending on which template configuration you choose you will likely be required to upgrade to a paid account.
Below is a list of pre-defined deployment options based on typical deployment scenarios (i.e. dev/test, production etc.). All configurations are fixed, and you just need to pass your ssh public key to the template for logging in to the deployed VMs. For production deployments, large size or Maximum template below is highly recommended which provisions high performance SKUs and configures the environment for high availability.
This deployment will use NFS, Azure Database for MySQL, and smaller autoscale web frontend VM sku (1 core) that'll give faster deployment time (less than 30 minutes) and requires only 2 VM cores currently that'll fit even in a free trial Azure subscription.
This maximal deployment will use Gluster (for high availability, adding 2 VMs for a Gluster cluster), MySQL with highest SKU, redis cache, elastic search (3 VMs), and pretty large storage sizes (both data disks and DB).
NOTE: Depending on the region you choose to deploy the stack in - the deployment might fail due to SKUs being hardcoded in the template where they are not available. If your deployment fails, please revert to the fully configurable template and change the SKU parameter to one that exists in your region (i.e. Gen-5).
The template deploys the following architecture in Azure.
Configuring Azure Database for MySQL for performance and scale
Moodle supports multiple databases like MySQL, PostgreSQL or SQL Server but the best performance and scale for Moodle is observed with MySQL database. As a result, MySQL is a preferred choice for customers and community when deploying Moodle for large number of concurrent users (1K – 10K). Azure Database for MySQL is a fully managed database service with built-in high availability, elastic scaling and automatic backups. Leveraging a managed service ensures you do not have to worry about managing your database for backups, high availability and setting up additional database monitoring.
When provisioning Azure Database for MySQL server for Moodle deployments, following is the recommended tier which provides best price to performance ratio.
< 1000 Users
8 vCores – General Purpose tier
1K – 2K Users
16 vCores – General Purpose Tier
2K – 5K Users
32 vCores – General Purpose Tier
> 5K Users
32 - 64 vCores – General Purpose Tier
If you notice, the recommendation for Storage tier is 2TB for higher concurrenct users irrespective of the size of the database. This is due to fact that in Azure Database for MySQL service, IOPs is not charged separately and it increases progressively with storage size provisioned (~3 IOPs/GB). With 2TB, you get 6000 provisioned IOPs which is recommended and required for Moodle when the number of concurrent users exceeds 1000 users.
In addition to server scaling, configuring the right server parameters also plays an important role in the performance of Moodle application as recommended in the official documentation. You can leverage Azure portal or Azure CLI to configure the following server parameters
Increase the size of open table cache table_open_cache = 1024
If you are migrating or restoring an existing Moodle database to Azure Database for MySQL service, it is recommended to perform OPTIMIZE ALL on the tables in the database following the restore. If it is a new deployment with no preexisting data, you can skip this step mysqlcheck -a moodle
Lastly, we would highly recommend to enable Query Performance Insights on your Azure Database for MySQL server which is an opt-in monitoring feature available at no additional cost. This will enable you to monitor and identify long running and slow performing queries on the database which might lead to poor performance or slowness in the application
Query Performance Insights can be enabled by enabling query store which requires setting the following server parameters from Azure Portal Set query_store_capture_mode to ALL Set query_store_wait_sampling_capture_mode to ALL
To give you an example of relevance of this feature in performance tuning, I want to share the following screenshot of the Long Running Queries report for a Moodle application running 3K concurrent users which was seeing an avg response time of > 100 seconds which was unacceptable.
After turning ON Query Performance Insights, we were able to identify the top query (Query ID 1065) in the report below which further enabled us to discover that we are hitting a known bug in Moodle causing slow performance in the application. On applying the workaround suggested in the bug tracker of truncating the expired cache in mdl_cache_flags table and creating indexes on expiry and timemodified columns, the performance was back to < 10 seconds which was expected.
It is also important to check and validate that binlog and slow_query_log is disabled as it may cause additional IO overhead and adds slowness to the server for high concurrent users. Ensure log_bin is set to OFF Ensure slow_query_log is set to OFF
Finally, it is important to leverage Redis Cache for Session handling and OPCache to ensure MySQL database is not flooded with queries as caching can help alleviate a lot of pressure on the backend database and improve the overall performance and scale for the application.
Get started by deploying your Moodle application on Azure using the above template.