Performance recommendations

Performance

Moodle can be made to perform very well, at small usage levels or scaling up to many thousands of users. The factors involved in performance are basically the same as for any PHP-based database-driven system. When trying to optimize your server, try to focus on the factor which will make the most difference to the user. For example, if you have relatively more users browsing than accessing the database, look to improve the webserver performance.



Contents


Obtain a baseline benchmark

Before attempting any optimization, you should obtain a baseline benchmark of the component of the system we are trying to improve. For Linux try LBS and for Windows use the Performance Monitor. Once you have quantitative data about how your system is performing currently, you'll be able to determine if the change you have made has had any real impact.

The overall aim of adjustments to improve performance is to use RAM (cacheing) and to reduce disk-based activity. It is especially important to try to eliminate swap file usage as much as we can. If your system starts swapping, this is a sign that you need more RAM.

The optimization order preference is usually: primary storage (more RAM), secondary storage (faster hard disks/improved hard disk configuration), processor (more and faster).


Scalability

Moodle's design (with clear separation of application layers) allows for strongly scalable setups. (Please check the list of large Moodle installations.)

Large sites usually separate the web server and database onto separate servers, although for smaller installations this is typically not necessary.

It is possible to load-balance a Moodle installation, for example by using more than one webserver. The separate webservers should query the same database and refer to the same filestore and cache areas (see Caching), but otherwise the separation of the application layers is complete enough to make this kind of clustering feasible. Similarly, the database could be a cluster of servers (e.g. a MySQL cluster), but this is not an easy task and you should seek expert support, e.g. from a Moodle Partner.


Server cluster

Using Moodle forum discussions:


Hardware configuration

Note: The fastest and most effective change that we can make to improve performance is to increase the amount of RAM on your web server - get as much as possible (e.g. 4GB or more). Increasing primary memory will reduce the need for processes to swap to disk and will enable your server to handle more users.


Operating System


Web server performance

Installing Firefox and the firebug extension will allow us to watch the time it takes for each page component to load. Also, the Yslow extension will evaluate your page against Yahoo's 14 rules, full text Best Practices for Speeding Up Your Web Site, (video) for fast loading websites.


PHP performance


Install HowTo


Apache performance

MaxRequestWorkers = Total available memory * 80% / Max memory usage of apache process

Memory usage of apache process is usually 10MB but Moodle can easily use up to 100MB per process, so a general rule of thumb is to divide your available memory in megabytes by 100 to get a conservative setting for MaxClients. You are quite likely to find yourself lowering the MaxRequestWorkers from its default of 150 on a Moodle server. To get a more accurate estimate read the value from the shell command:
#ps -ylC httpd --sort:rss

If you need to increase the value of MaxRequestWorkers beyond 256, we will also need to set the ServerLimit directive.

Warning: Do not be tempted to set the value of MaxRequestWorkers higher than your available memory as your server will consume more RAM than available and start to swap to disk.

DirectoryIndex index.php index.html index.htm

Options -Indexes FollowSymLinks

  1. Install and enable mod_deflate - refer to documentation or man pages
  2. Add this code to the virtual server config file within the <directory> section for the root directory (or within the .htaccess file if AllowOverrides is On):
<ifModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/x-js text/javascript text/css application/javascript
</ifmodule>


IIS performance

All alter this location in the registry:

HKLM\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\


Lighttpd, NginX and Cherokee performance

We can increase server performance by using a light-weight webserver like lighttpd, nginx or cherokee in combination with PHP in FastCGI-mode. Lighttpd was originally created as a proof-of-concept[2] to address the C10k problem and while primarily recommended for memory-limited servers, its design origins and asynchronous-IO model make it a suitable and proven[3] alternative HTTP server for high-load websites and web apps, including Moodle. See the MoodleDocs Lighttpd page for additional information, configuration example and links.

Alternatively, both lighttpd and nginx are capable of performing as a load-balancer and/or reverse-proxy to alleviate load on back-end servers[4], providing benefit without requiring an actual software change on existing servers.

Do note that these are likely to be the least tested server environments of all particularly if we are using advanced features such as web services and/or Moodle Networking. They are probably best considered for heavily used Moodle sites with relatively simple configurations.


X-Sendfile

X-Sendfile modules improve performance when sending large files from Moodle. It is recommended to configure your web server and Moodle to use this feature of available.

Configure web server:

Enable support in config.php (see config-dist.php):

//     $CFG->xsendfile = 'X-Sendfile';           // Apache {@see https://tn123.org/mod_xsendfile/}
//     $CFG->xsendfile = 'X-LIGHTTPD-send-file'; // Lighttpd {@see http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file}
//     $CFG->xsendfile = 'X-Accel-Redirect';     // Nginx {@see http://wiki.nginx.org/XSendfile}

Configure file location prefixes if your server implementation requires it:

//     $CFG->xsendfilealiases = array(
//         '/dataroot/' => $CFG->dataroot,
//         '/cachedir/' => '/var/www/moodle/cache',    // for custom $CFG->cachedir locations
//         '/localcachedir/' => '/var/local/cache',    // for custom $CFG->localcachedir locations
//         '/tempdir/'  => '/var/www/moodle/temp',     // for custom $CFG->tempdir locations
//         '/filedir'   => '/var/www/moodle/filedir',  // for custom $CFG->filedir locations
//     );


Database performance


MySQL performance

The following are MySQL specific settings which can be adjusted for better performance in your my.cnf (my.ini in Windows). The file contains a list of settings and their values. To see the current values use these commands

SHOW STATUS;
SHOW VARIABLES; 

Important: You must make backups of your database before attempting to change any MySQL server configuration. After any change to the my.cnf, restart mysqld.

If we are able, the MySQLTuner tool can be run against your MySQL server and will calculate appropriate configuration values for most of the following settings based on your current load, status and variables automatically.

query_cache_type = 1. 

For most Moodle installs, set the following:

query_cache_size = 36M 
query_cache_min_res_unit = 2K. 

The query cache will improve performance if we are doing few updates on the database.

table_cache = 256 #(table_open_cache in MySQL > 5.1.2)

(min), and for Moodle 1.7 set

table_cache = 512 #(table_open_cache in MySQL > 5.1.2)

(min). The table cache is used by all threads (connections), so monitor the value of opened_tables to further adjust - if opened_tables > 3 * table_cache(table_open_cache in MySQL > 5.1.2) then increase table_cache upto your OS limit. Note also that the figure for table_cache will also change depending on the number of modules and plugins you have installed. Find the number for your server by executing the mysql statement below. Look at the number returned and set table_cache to this value.

mysql>SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='yourmoodledbname';

thread cache utilization (%) = (threads_created / connections) * 100

key_read / key_read_requests < 0.01
key_write / key_write_requests <= 1.0

mysql>CHECK TABLE mdl_tablename;
mysql>OPTIMIZE TABLE mdl_tablename;

The common tables in Moodle to check are mdl_course_sections, mdl_forum_posts, mdl_log and mdl_sessions (if using dbsessions). Any errors need to be corrected using REPAIR TABLE (see the MySQL manual and this forum script).

#myisamchk -a -S /pathtomysql/data/moodledir/*.MYI

Warning: You must stop the mysql database process (mysqld) before running any myisamchk command. If you do not, you risk data loss.


PostgreSQL performance

There are some good papers around on tuning PostgreSQL (like this one), and Moodle's case does not seem to be different to the general case.

The first thing to recognise is that if you really need to worry about tuning you should be using a separate machine for the database server. If we are not using a separate machine then the answers to many performance questions are substantially muddied by the memory requirements of the rest of the application.

You should probably enable autovacuum, unless you know what we are doing. Many e-learning sites have predictable periods of low use, so disabling autovacuum and running a specific vacuum at those times can be a good option. Or perhaps leave autovacuum running but do a full vacuum weekly in a quiet period.

Set shared_buffers to something reasonable. For versions up to 8.1 my testing has shown that peak performance is almost always obtained with buffers < 10000, so if we are using such a version, and have more than 512M of RAM just set shared_buffers to 10,000 (8MB).

The buffer management had a big overhaul in 8.2 and "reasonable" is now a much larger number. I have not conducted performance tests with 8.2, but the recommendations from others are generally that you should now scale shared_buffers much more with memory and may continue to reap benefits even up to values like 100,000 (80MB). Consider using 1-2% of system RAM.

PostgreSQL will also assume that the operating system is caching its files, so setting effective_cache_size to a reasonable value is also a good idea. A reasonable value will usually be (total RAM - RAM in use by programs). If we are running Linux and leave the system running for a day or two we can look at 'free' and under the 'cached' column we will see what it currently is. Consider taking that number (which is kB) and dividing it by 10 (i.e. allow 20% for other programs cache needs and then divide by 8 to get pages). If we are not using a dedicated database server we will need to decrease that value to account for usage by other programs.

Some other useful parameters that can have positive effects, and the values I would typically set them to on a machine with 4G RAM, are:

work_mem = 10240

That's 10M of RAM to use instead of on-disk sorting and so forth. That can give a big speed increase, but it is per connection and 200 connections * 10M is 2G, so it can theoretically chew up a lot of RAM.

maintenance_work_mem = 163840

That's 160M of RAM which will be used by (e.g.) VACUUM, index rebuild, cluster and so forth. This should only be used periodically and should be freed when those processes exit, so I believe it is well worth while.

wal_buffers = 64

These buffers are used for the write-ahead log, and there have been a number of reports on the PostgreSQL mailing lists of improvement from this level of increase.

This is a little out of date now (version 8.0) but still worth a read: http://www.powerpostgresql.com/Docs

And there is lots of good stuff here as well: http://www.varlena.com/GeneralBits/Tidbits/index.php

Based on Andrew McMillan's post at Tuning PostgreSQL forum thread.


Other database performance links


Performance of different Moodle modules

Moodle's activity modules, filters, and other plugins can be activated/deactivated. If necessary, you may wish to deactivate some features (such as chat) if not required - but this isn't necessary. Some notes on the performance of certain modules:

See Performance settings for more information on performance-related Moodle settings.


See also

There have been a lot of discussions on moodle.org about performance, here are some of the more interesting and (potentially) useful ones: