Performance recommendations: Difference between revisions

From MoodleDocs
m (clean up, typos fixed: it's own → its own)
 
(35 intermediate revisions by 16 users not shown)
Line 1: Line 1:
{{Performance}}
{{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.
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.
==Obtain a baseline benchmark==
==Obtain a baseline benchmark==
 
Before attempting any optimization, you should obtain a baseline benchmark of the component of the system you are trying to improve. For Linux try [http://lbs.sourceforge.net/ LBS] (Note: Last updated May 2002) 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.
Before attempting any optimization, you should obtain a baseline benchmark of the component of the system you are trying to improve. For Linux try [http://lbs.sourceforge.net/ 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 you can. If your system starts swapping, this is a sign that you need more RAM.  
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 you can. If your system starts swapping, this is a sign that you need more RAM.  
Line 11: Line 8:
The '''optimization order preference''' is usually: primary storage (more RAM), secondary storage (faster hard disks/improved hard disk configuration), processor (more and faster).
The '''optimization order preference''' is usually: primary storage (more RAM), secondary storage (faster hard disks/improved hard disk configuration), processor (more and faster).


It can be interesting to install and use the [https://moodle.org/plugins/report_benchmark Benchmark plugin] in order to find the bottlenecks of your system that specifically affect Moodle or do a load test / stress test with tool like JMeter. See [https://docs.moodle.org/dev/JMeter moodledev JMeter documentation]
==Scalability==
==Scalability==
Moodle's design (with clear separation of application layers) allows for strongly scalable setups. (Please check the list of [[Large installations|large Moodle installations]].)
Moodle's design (with clear separation of application layers) allows for strongly scalable setups. (Please check the list of [[Large installations|large Moodle installations]].)


Line 19: Line 16:
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.
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.


On very large, load-balanced, systems the performance of the shared components become critical. It's important that your shared file areas are properly tuned and that you use an effective cache (Redis is highly recommended). A good understanding of these areas of system administration should be considered a minimum requirement.
===Server cluster===
===Server cluster===
Using Moodle forum discussions:
Using Moodle forum discussions:
*[http://moodle.org/mod/forum/discuss.php?d=57202 Moodle clustering]
*[http://moodle.org/mod/forum/discuss.php?d=57202 Moodle clustering]
*[http://moodle.org/mod/forum/discuss.php?d=44470 Software load balancing]
*[http://moodle.org/mod/forum/discuss.php?d=44470 Software load balancing]
*[http://moodle.org/mod/forum/discuss.php?d=49986 TCP load balancing]
*[http://moodle.org/mod/forum/discuss.php?d=49986 TCP load balancing]
*[http://moodle.org/mod/forum/discuss.php?d=88214 Installation for 3000 simultaneous users]
*[http://moodle.org/mod/forum/discuss.php?d=88214 Installation for 3000 simultaneous users]
==Hardware configuration==
==Hardware configuration==
'''Note''': The fastest and most effective change that you 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.
'''Note''': The fastest and most effective change that you 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.
* Better performance is gained by obtaining the best '''processor capability''' you can, i.e. dual or dual core processors. A modern BIOS should allow you to enable hyperthreading, but check if this makes a difference to the overall performance of the processors by using a [http://en.wikipedia.org/wiki/Super_PI CPU benchmarking tool].
* Better performance is gained by obtaining the best '''processor capability''' you can, i.e. dual or dual core processors. A modern BIOS should allow you to enable hyperthreading, but check if this makes a difference to the overall performance of the processors by using a [http://en.wikipedia.org/wiki/Super_PI CPU benchmarking tool].
* If you can afford them, use '''SCSI hard disks''' instead of SATA drives. SATA drives will increase your system's CPU utilization, whereas SCSI drives have their own integrated processors and come into their own when you have multiple drives. If you must have SATA drives, check that your motherboard and the drives themselves support NCQ (Native Command Queuing).
* If you can afford them, use '''SCSI hard disks''' instead of SATA drives. SATA drives will increase your system's CPU utilization, whereas SCSI drives have their own integrated processors and come into their own when you have multiple drives. If you must have SATA drives, check that your motherboard and the drives themselves support NCQ (Native Command Queuing).
* Purchase hard disks with a '''low seek time'''. This will improve the overall speed of your system, especially when accessing Moodle's reports.
* Purchase hard disks with a '''low seek time'''. This will improve the overall speed of your system, especially when accessing Moodle's reports. Naturally these days Solid State Drives outperform rotating media immensely, especially Enterprise-Grade SSD's.
* Size your '''swap file''' correctly. The general advice is to set it to 4 x physical RAM.
* Size your '''swap file''' correctly. The general advice is to set it to 4 x physical RAM.
* Use a '''RAID disk system'''. Although there are many different RAID configurations you can create, the following generally works best:
* Use a '''RAID disk system'''. Although there are many different RAID configurations you can create, the following generally works best:
Line 38: Line 33:
** the operating system and swap drive on one set of disks configured as RAID-1.
** the operating system and swap drive on one set of disks configured as RAID-1.
** Moodle, Web server and Database server on another set of disks configured as RAID-5.
** Moodle, Web server and Database server on another set of disks configured as RAID-5.
* If your 'moodledata' area is going to be on relatively slow storage (e.g. NFS, SAN) you will probably have performance issues with the default cache configuration (which writes to this storage). See the page on [[Caching]] and consider an alternative.  
* If your 'moodleData' area is going to be on relatively slow storage (e.g. NFS mount on to a NAS device) you will have performance issues with the default cache configuration (which writes to this storage). See the page on [[Caching]] and choose an alternative. [[Redis cache store|Redis]] is recommended. Using [https://en.wikipedia.org/wiki/GlusterFS GlusterFS] / [https://en.wikipedia.org/wiki/OCFS2 OCFS2] / [https://en.wikipedia.org/wiki/GFS2 GFS2] on a [https://en.wikipedia.org/wiki/Storage_Area_Network SAN] device and [https://en.wikipedia.org/wiki/Fibre_Channel Fiber Channel] could improve performance (See more info on the Moodle [https://moodle.org/mod/forum/discuss.php?d=214680#p1123124 forum thread], [https://moodle.org/mod/forum/discuss.php?d=310501#p1242382 NFS performance tuing] )
* Use '''gigabit ethernet''' for improved latency and throughput. This is especially important when you have your webserver and database server separated out on different hosts.
* Use '''gigabit ethernet''' for improved latency and throughput. This is especially important when you have your webserver and database server separated out on different hosts.
* Check the settings on your '''network card'''. You may get an improvement in performance by increasing the use of buffers and transmit/receive descriptors (balance this with processor and memory overheads) and off-loading TCP checksum calculation onto the card instead of the OS.
* Check the settings on your '''network card'''. You may get an improvement in performance by increasing the use of buffers and transmit/receive descriptors (balance this with processor and memory overheads) and off-loading TCP checksum calculation onto the card instead of the OS.
Line 44: Line 39:
* See this [http://elearning.sgu.ac.jp/doc/PT/ accompanying report] on network traffic and server loads.
* See this [http://elearning.sgu.ac.jp/doc/PT/ accompanying report] on network traffic and server loads.
* Also see this SFSU presentation at Educause (using VMWare): [http://www.educause.edu/Resources/AnOpenSourceLMSforaMissionCrit/162843]
* Also see this SFSU presentation at Educause (using VMWare): [http://www.educause.edu/Resources/AnOpenSourceLMSforaMissionCrit/162843]
==Operating System==
==Operating System==
* You can use [http://en.wikipedia.org/wiki/Linux Linux](recommended), Unix-based, Windows or Mac OS X for the server '''operating system'''. *nix operating systems generally require less memory than Mac OS X or Windows servers for doing the same task as the server is configured with just a shell interface. Additionally Linux does not have licensing fees attached, but can have a big learning curve if you're used to another operating system. If you have a large number of processors running SMP, you may also want to consider using a highly tuned OS such as [http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris].
* You can use [http://en.wikipedia.org/wiki/Linux Linux](recommended), Unix-based, Windows or Mac OS X for the server '''operating system'''. *nix operating systems generally require less memory than Mac OS X or Windows servers for doing the same task as the server is configured with just a shell interface. Additionally Linux does not have licensing fees attached, but can have a big learning curve if you're used to another operating system. If you have a large number of processors running SMP, you may also want to consider using a highly tuned OS such as [http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris].
* Check your own OS and '''vendor specific instructions''' for optimization steps.
* Check your own OS and '''vendor specific instructions''' for optimization steps.
** For Linux look at the [http://linuxperf.sourceforge.net/ Linux Performance Team] site.  
** For Linux look at the [http://linuxperf.sourceforge.net/ Linux Performance Team] site.  
** For Linux investigate the hdparm command, e.g. hdparm -m16 -d1 can be used to enable read/write on multiple sectors and DMA. Mount disks with the async and noatime options.
** For Linux investigate the hdparm command, e.g. hdparm -m16 -d1 can be used to enable read/write on multiple sectors and DMA. Mount disks with the [https://moodle.org/mod/forum/discuss.php?d=310501#p1242382 "async" and "noatime"] options.
** For Windows set the sever to be optimized for network applications (Control Panel, Network Connections, LAN connection, Properties, File & Printer Sharing for Microsoft Networks, Properties, Optimization). You can also search the [http://technet.microsoft.com/ Microsoft TechNet site] for optimization documents.
** For Windows set the sever to be optimized for network applications (Control Panel, Network Connections, LAN connection, Properties, File & Printer Sharing for Microsoft Networks, Properties, Optimization). You can also search the [http://technet.microsoft.com/ Microsoft TechNet site] for optimization documents.
==Caching Performance==
Caching in Moodle can default to disk for a lot of the different caches which is rather slow overall, and so pretty solid gains can be made by moving this to RAM, by use of a Memory Caching Application such as [[Redis cache store|Redis]] or Memcached. In fact I'd go as far to say the single biggest improvement we made to our (relatively small) Moodle site was installing Redis, and this is amplified when you're using classic Hard Drives rather than SSD's, and especially when they slowly but surely begin to fail (the classic slow to write, but no SMART errors or write errors - just reeeeaaallly slow).


==Web server performance==
These will also cache some database queries, meaning that they don't have to be re-run, again improving performance there. Personally, I would recommend Redis over Memcached due to better security features and being more up to date/developed. For more information/how to install Redis in particular, visit the [[Redis cache store]] page.
 
==Web Server Performance==
Installing [http://www.mozilla.com/en-US/ Firefox] and the [https://addons.mozilla.org/en-US/firefox/addon/1843 firebug] extension will allow you to watch the time it takes for each page component to load. Also, the [https://addons.mozilla.org/en-US/firefox/addon/5369 Yslow] extension will evaluate your page against Yahoo's [http://www.skrenta.com/2007/05/14_rules_for_fast_web_pages_by_1.html 14 rules], full text [http://developer.yahoo.com/performance/rules.html Best Practices for Speeding Up Your Web Site], <strike>([http://video.yahoo.com/video/play?vid=1040890 video])</strike> for fast loading websites.
Most web browsers these days feature Inspector elements which will allow you to watch the time it takes for each page component to load, typically found under the "Network" tab. Also, the [https://addons.mozilla.org/en-US/firefox/addon/5369 Yslow] extension will evaluate your page against Yahoo's [http://www.skrenta.com/2007/05/14_rules_for_fast_web_pages_by_1.html 14 rules], full text [http://developer.yahoo.com/performance/rules.html Best Practices for Speeding Up Your Web Site], <s>([http://video.yahoo.com/video/play?vid=1040890 video])</s> for fast loading websites.
 
===PHP Performance===
===PHP performance===
* PHP contains a built-in accelerator (for more recent versions of PHP, this is OpCache). Make sure it is enabled.
* You are strongly recommended to use a '''PHP accelerator''' to ease CPU load, such as [http://pecl.php.net/apc APC], [http://www.php-accelerator.co.uk/ PHPA], [http://trac.lighttpd.net/xcache/ Xcache], [http://sourceforge.net/projects/wincache WinCache] or [http://eaccelerator.net/ eAccelerator]. (Take care to choose a PHP accelerator that is known to work well with your version of PHP and note that Turck MMCache is [http://turckmmcache.exeprod.com/TheManifestoEnglish no longer maintained] and can cause failures with PHP 5). PHP 5.5 (and newer) includes OpCache and is fully supported and recommended by Moodle
* Improvements in read/write performance can be improved by putting the cached PHP pages on a [[TMPFS]] filesystem - but remember that you'll lose the cache contents when there is a power failure or the server is rebooted.
* Improvements in read/write performance can be improved by putting the cached PHP pages on a [[TMPFS]] filesystem - but remember that you'll lose the cache contents when there is a power failure or the server is rebooted.
* Performance of PHP is better when installed as an '''Apache/IIS6 ISAPI module''' (rather than a CGI). IIS 7.0/7.5 (Windows Server 2008/R2) users should choose a FastCGI installation for best performance.
* Performance of PHP is better when installed as an '''Apache/IIS6 ISAPI module''' (rather than a CGI). IIS 7.0/7.5 (Windows Server 2008/R2) users should choose a FastCGI installation for best performance.
* Also check the '''memory_limit''' in php.ini, reduce it to 16M for Moodle version earlier than 1.7 ([http://moodle.org/mod/forum/discuss.php?d=39656 See this forum discussion]). For Moodle 1.7 or later, it is recommended that the value of memory_limit should be 40M. As of [http://www.php.net/ChangeLog-5.php PHP 5.2.1] the default value for the memory_limit directive is 128M.
* Also check the '''memory_limit''' in php.ini. The default value for the memory_limit directive is 128M. On some sites, it may need to be larger - especially for some backup operations.
* Also see [[PHP_settings_by_Moodle_version]]
* Also see [[PHP settings by Moodle version]]
* Use [http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html PHP-FPM] (with apache).
* Use [http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html PHP-FPM] (with apache).
 
====APC====
===Install HowTo===
* [http://2bits.com/articles/installing-php-apc-gnulinux-centos-5.html APC on CentOS 5.x (linux)]
* [http://2bits.com/articles/installing-php-apc-gnulinux-centos-5.html APC on CentOS 5.x (linux)]
* [http://fplanque.com/dev/linux/install-apc-php-cache-debian-lenny APC on Debian (linux)]
* [http://fplanque.com/dev/linux/install-apc-php-cache-debian-lenny APC on Debian (linux)]
* [http://www.linuxtuts.net/211-installing-memcached-php5-memcache-module-debian-apache2.html MemCache module on Debian (Apache2 and PHP5) ]
* [http://noveckg.blogspot.com/2010/03/installing-memcached-on-centos-5x.html Installing Memcache on CentOS 5.x (linux)]
* [http://noveckg.blogspot.com/2010/02/installing-eaccelerator-cache-for-php.html Installing eAccelerator on CentOS 5.x (linux)]
* [https://docs.moodle.org/en/Installing_eAccelerator_In_Ubuntu_Server/ Installing eAccelerator on Ubuntu Server (linux)]


===Apache performance===
===Apache Performance===
* If you are using Apache on a Windows server, use the build from [http://www.apachelounge.com Apache Lounge] which is reported to have [http://moodle.org/mod/forum/discuss.php?d=93358 performance and stability improvements] compared to the official Apache download. Note that this is an unofficial build, so may not keep up with official releases.
* If you are using Apache on a Windows server, use the build from [http://www.apachelounge.com Apache Lounge] which is reported to have [http://moodle.org/mod/forum/discuss.php?d=93358 performance and stability improvements] compared to the official Apache download. Note that this is an unofficial build, so may not keep up with official releases.
* Set the '''MaxClients''' directive correctly. Use this formula to help (which uses 80% of available memory to leave room for spare):
* Set the '''MaxRequestWorkers''' directive correctly ('''MaxClients''' before Apache 2.4). Use this formula to help (which uses 80% of available memory to leave room for spare):
  MaxClients = Total available memory * 80% / Max memory usage of apache process
  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 MaxClients from its default of 150 on a Moodle server. To get a more accurate estimate read the value from the shell command:
: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
  #ps -ylC httpd --sort:rss
:If you need to increase the value of '''MaxRequestWorkers''' beyond 256, you will also need to set the '''ServerLimit''' directive.


:If you need to increase the value of '''MaxClients''' beyond 256, you 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.  
 
* Consider reducing the '''number of modules''' that Apache loads in the httpd.conf file to the minimum necessary to reduce the memory needed.  
:'''Warning''': Do not be tempted to set the value of MaxClients higher than your available memory as your server will consume more RAM than available and start to swap to disk.  
* Consider reducing the '''number of modules''' that Apache loads in the httpd.conf file to the minumum necessary to reduce the memory needed.  
* Use the '''latest version of Apache''' - Apache 2 has an improved memory model which reduces memory usage further.
* Use the '''latest version of Apache''' - Apache 2 has an improved memory model which reduces memory usage further.
* For Unix/Linux systems, consider lowering '''MaxRequestsPerChild''' in httpd.conf to as low as 20-30 (if you set it any lower the overhead of forking begins to outweigh the benefits).  
* For Unix/Linux systems, consider lowering '''MaxConnectionsPerChild''' ('''MaxRequestsPerChild''' before Apache 2.4) in httpd.conf to as low as 20-30 (if you set it any lower the overhead of forking begins to outweigh the benefits).  
* For a heavily loaded server, consider setting '''KeepAlive Off''' (do this only if your Moodle pages do not contain links to resources or uploaded images) or lowering the '''KeepAliveTimeout''' to between 2 and 5. The default is 15 (seconds) - the higher the value the more server processes will be kept waiting for possibly idle connections. A more accurate value for KeepAliveTimeout is obtained by observing how long it takes your users to download a page. After altering any of the KeepAlive variables, monitor your CPU utilization as there may be an additional overhead in initiating more worker processes/threads.
* For a heavily loaded server, consider setting '''KeepAlive Off''' (do this only if your Moodle pages do not contain links to resources or uploaded images) or lowering the '''KeepAliveTimeout''' to between 2 and 5. The default is 15 (seconds) - the higher the value the more server processes will be kept waiting for possibly idle connections. A more accurate value for KeepAliveTimeout is obtained by observing how long it takes your users to download a page. After altering any of the KeepAlive variables, monitor your CPU utilization as there may be an additional overhead in initiating more worker processes/threads.
* As an alternative to using KeepAlive Off, consider setting-up a '''Reverse Proxy server''' infront of the Moodle server to cache HTML files with images. You can then return Apache to using keep-alives on the Moodle server.
* As an alternative to using KeepAlive Off, consider setting-up a '''Reverse Proxy server''' in front of the Moodle server to cache HTML files with images. You can then return Apache to using keep-alives on the Moodle server.
* If you do not use a .htaccess file, set the '''AllowOverride''' variable to AllowOverride None to prevent .htaccess lookups.
* If you do not use a .htaccess file, set the '''AllowOverride''' variable to AllowOverride None to prevent .htaccess lookups.
* Set '''DirectoryIndex''' correctly so as to avoid content-negotiation. Here's an example from a production server:
* Set '''DirectoryIndex''' correctly so as to avoid content-negotiation. Here's an example from a production server:
Line 92: Line 81:
* Unless you are doing development work on the server, set '''ExtendedStatus Off''' and disable mod_info as well as mod_status.
* Unless you are doing development work on the server, set '''ExtendedStatus Off''' and disable mod_info as well as mod_status.
* Leave '''HostnameLookups Off''' (as default) to reduce DNS latency.
* Leave '''HostnameLookups Off''' (as default) to reduce DNS latency.
* Consider reducing the value of '''TimeOut''' to between 30 to 60 (seconds).  
* Consider reducing the value of '''TimeOut''' to between 30 and 60 (seconds).  
* For the '''Options directive''', avoid Options Multiviews as this performs a directory scan. To reduce disk I/O further use
* For the '''Options directive''', avoid Options Multiviews as this performs a directory scan. To reduce disk I/O further use
  Options -Indexes FollowSymLinks
  Options -Indexes FollowSymLinks
* Compression reduces response times by reducing the size of the HTTP response
* Compression reduces response times by reducing the size of the HTTP response
# Install and enable mod_deflate - refer to documentation or man pages
# Install and enable mod_deflate - refer to documentation or man pages
Line 104: Line 92:
* Use Apache [http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html event] [http://httpd.apache.org/docs/current/mpm.html MPM] (and not the default Prefork or Worker)
* Use Apache [http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html event] [http://httpd.apache.org/docs/current/mpm.html MPM] (and not the default Prefork or Worker)


===IIS performance===
===IIS Performance===
All alter this location in the registry:
All alter this location in the registry:
  HKLM\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\
  HKLM\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\
* The equivalent to KeepAliveTimeout is '''ListenBackLog''' (IIS - registry location is HKLM\ SYSTEM\ CurrentControlSet\ Services\ Inetinfo\ Parameters). Set this to between 2 to 5.
* The equivalent to KeepAliveTimeout is '''ListenBackLog''' (IIS - registry location is HKLM\ SYSTEM\ CurrentControlSet\ Services\ Inetinfo\ Parameters). Set this to between 2 and 5.
*Change the '''MemCacheSize''' value to adjust the amount of memory (Mb) that IIS will use for its file cache (50% of available memory by default).
*Change the '''MemCacheSize''' value to adjust the amount of memory (Mb) that IIS will use for its file cache (50% of available memory by default).
*Change the '''MaxCachedFileSize''' to adjust the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).
*Change the '''MaxCachedFileSize''' to adjust the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).
*Create a new DWORD called '''ObjectCacheTTL''' to change the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).
*Create a new DWORD called '''ObjectCacheTTL''' to change the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).


===Lighttpd, NginX and Cherokee performance===
=== OpenLiteSpeed ===
You can increase server performance by using a '''light-weight''' webserver like [http://www.lighttpd.net/ lighttpd],  [http://nginx.net/ nginx] or [http://www.cherokee-project.com/ cherokee] in combination with PHP in FastCGI-mode. Lighttpd was originally created as a proof-of-concept[http://www.lighttpd.net/story] to address the [http://www.kegel.com/c10k.html C10k problem] and while primarily recommended for memory-limited servers, its design origins and asynchronous-IO model make it a suitable and proven[http://blog.lighttpd.net/articles/2006/12/28/lighttpd-powers-5-alexa-top-250-sites] alternative HTTP server for high-load websites and web apps, including Moodle. See the [[lighttpd | MoodleDocs Lighttpd page]] for additional information, configuration example and links.
OpenLiteSpeed has its own built in cache called [https://docs.litespeedtech.com/lscache/ LSCache], which is controlled through the Web GUI, and also is compatible with PHP OpCache. More info on optimizing OpenLiteSpeed can be found on the [[OpenLiteSpeed]] page.


Alternatively, both [http://www.lighttpd.net/ lighttpd] and [http://nginx.net/ nginx] are capable of performing as a load-balancer and/or reverse-proxy to alleviate load on back-end servers[http://www.linuxjournal.com/article/10108], providing benefit without requiring an actual software change on existing servers.
===Lighttpd, NginX and Cherokee Performance===
You can increase server performance by using a '''light-weight''' webserver like [http://www.lighttpd.net/ lighttpd], [http://nginx.net/ nginx] or [http://www.cherokee-project.com/ cherokee] in combination with PHP in FastCGI-mode. Lighttpd was originally created as a proof-of-concept [http://www.lighttpd.net/story] to address the [http://www.kegel.com/c10k.html C10k problem] and while primarily recommended for memory-limited servers, its design origins and asynchronous-IO model make it a suitable and proven [http://blog.lighttpd.net/articles/2006/12/28/lighttpd-powers-5-alexa-top-250-sites] alternative HTTP server for high-load websites and web apps, including Moodle. See the [[lighttpd|MoodleDocs Lighttpd page]] for additional information, configuration example and links.
 
Alternatively, both [http://www.lighttpd.net/ lighttpd] and [http://nginx.net/ nginx] are capable of performing as a load-balancer and/or reverse-proxy to alleviate load on back-end servers [http://www.linuxjournal.com/article/10108], 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 you 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.
Do note that these are likely to be the least tested server environments of all particularly if you 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===
 
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 if available.
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:
Configure web server:
Line 127: Line 116:
* Lighttpd - http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file
* Lighttpd - http://redmine.lighttpd.net/projects/lighttpd/wiki/X-LIGHTTPD-send-file
* Nginx - http://wiki.nginx.org/XSendfile
* Nginx - http://wiki.nginx.org/XSendfile
* OpenLiteSpeed - https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:config:internal-redirect


Enable support in config.php (see config-dist.php):
Enable support in config.php (see config-dist.php):
<code php>
<syntaxhighlight lang="php">
//    $CFG->xsendfile = 'X-Sendfile';          // Apache {@see https://tn123.org/mod_xsendfile/}
//    $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-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}
//    $CFG->xsendfile = 'X-Accel-Redirect';    // Nginx {@see http://wiki.nginx.org/XSendfile}
</code>
</syntaxhighlight>
 
Configure file location prefixes if your server implementation requires it:
Configure file location prefixes if your server implementation requires it:
<code php>
<syntaxhighlight lang="php">
//    $CFG->xsendfilealiases = array(
//    $CFG->xsendfilealiases = array(
//        '/dataroot/' => $CFG->dataroot,
//        '/dataroot/' => $CFG->dataroot,
Line 144: Line 134:
//        '/filedir'  => '/var/www/moodle/filedir',  // for custom $CFG->filedir locations
//        '/filedir'  => '/var/www/moodle/filedir',  // for custom $CFG->filedir locations
//    );
//    );
</code>
</syntaxhighlight>
== Cron Performance ==
Cron is a very important part of the overall performance of Moodle as many asynchronous processes are offloaded to Cron, so it needs to be running and have enough through put to handle the work being given to it by the front ends.


==Database performance==
See [[Cron with Unix or Linux#High performance cron tasks]]


===MySQL performance===
==Database Performance==
 
=== MariaDB Performance ===
MariaDB Optimizations are similar to MySQL, but at the same time different due to the way MariaDB operates. Performance as a whole is typically better than MySQL using MariaDB, so if you're looking for Database Optimization, potentially switching from MySQL to MariaDB may help with performance, otherwise if you're already using MariaDB and looking to Optimize it, Performance Recommendations can be found on the [[MariaDB]] Page.
 
===MySQL Performance===
The '''number one thing''' you can do to improve MySQL performance is to read, understand and implement the recommendations in the [https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html Innodb Buffer Pool] article.
 
The [https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-resize.html buffer pool size] can safely be changed while your server is running, as long as your server has enough memory (RAM) to accommodate the value you set. On a machine that is dedicated to MySQL, you can safely set this value to 80% of available memory.
 
Consider setting [https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_buffer_pool_instances innodb_buffer_pool_instances] to the number of cores, vCPUs, or chips you have available. Adjust this value in accordance with the recommendations in the [https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-resize.html MySQL documentation].


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
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
Line 155: Line 157:
'''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.
'''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 you are able, the [http://mysqltuner.com/ 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.
If you are able, the [http://mysqltuner.pl/ 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.
 
* Enable the '''query cache''' with  
* Enable the '''query cache''' with  
  query_cache_type = 1.  
  query_cache_type = 1.  
Line 167: Line 168:
(min), and for Moodle 1.7 set  
(min), and for Moodle 1.7 set  
  table_cache = 512 #(table_open_cache in MySQL > 5.1.2)
  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.
(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 up to 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';
  mysql>SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema='yourmoodledbname';
* Set the '''thread cache''' correctly. Adjust the value so that your thread cache utilization is as close to 100% as possible by this formula:
* Set the '''thread cache''' correctly. Adjust the value so that your thread cache utilization is as close to 100% as possible by this formula:
Line 185: Line 186:
* Reduce the number of '''temporary tables saved to disk'''. Check this with the created_tmp_disk_tables value. If this is relatively large (>5%) increase tmp_table_size until you see a reduction. Note that this will have an impact on RAM usage.
* Reduce the number of '''temporary tables saved to disk'''. Check this with the created_tmp_disk_tables value. If this is relatively large (>5%) increase tmp_table_size until you see a reduction. Note that this will have an impact on RAM usage.


===PostgreSQL performance===
===PostgreSQL Performance===
 
There are some good papers around on tuning PostgreSQL (like [http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server this one]), and Moodle's case does not seem to be different to the general case.
There are some good papers around on tuning PostgreSQL (like [http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server this one]), and Moodle's case does not seem to be different to the general case.


Line 200: Line 200:


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:
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
  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.
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
  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.
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.
max_fsm_pages = 100000
max_fsm_relations = 5000
These are used to hold the free-space map, and if they are too small you will see performance degradation after the database has been operating for some time. The exact numbers to set can be gleaned from the output of VACUUM VERBOSE, which prints the required FSM pages at the end of it's run. The 5x increase seems to be useful for a Moodle installation, from experience.
  wal_buffers = 64
  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.
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.


Line 223: Line 212:


''Based on Andrew McMillan's post at [http://moodle.org/mod/forum/discuss.php?d=68558 Tuning PostgreSQL] forum thread.''
''Based on Andrew McMillan's post at [http://moodle.org/mod/forum/discuss.php?d=68558 Tuning PostgreSQL] forum thread.''
* Splitting '''mdl_log''' to several tables and using a VIEW with UNION to read them as one. (See Tim Hunt [https://moodle.org/mod/forum/discuss.php?d=243531#p1104165 explanation] on the Moodle forums)
=== Read replicas ===
Since Moodle 3.9 you can configure read replica's to be used where possible. For very large systems as much as 80-90% of the DB load can be moved away from the primary. For configuration see config-dist:
https://github.com/moodle/moodle/blob/master/config-dist.php#L84-L117


===Other database performance links===
===Other database performance links===
* Consider using a '''distributed cacheing system''' like [http://en.wikipedia.org/wiki/Memcached memcached] but note that memcached does not have any security features so it should be used behind a firewall.
* Consider using a '''distributed caching system''' like [http://en.wikipedia.org/wiki/Memcached memcached] but note that memcached does not have any security features so it should be used behind a firewall.
* Consider using PostgreSQL. See [[Arguments in favour of PostgreSQL]] and [http://moodle.org/mod/forum/discuss.php?d=49195 how to migrate from MySQL to PostgreSQL] (forum discussion).
* Consider using PostgreSQL. See [http://moodle.org/mod/forum/discuss.php?d=49195 how to migrate from MySQL to PostgreSQL] (forum discussion).
* [http://dev.mysql.com/doc/refman/5.0/en/server-parameters.html General advice on tuning MySQL parameters] (advice from the MySQL manual)
* [http://dev.mysql.com/doc/refman/5.0/en/server-parameters.html General advice on tuning MySQL parameters] (advice from the MySQL manual)
* [http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/ InnoDB performance optimization] taken from the [http://www.mysqlperformanceblog.com/ MySQL performance blog] site.
* [http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/ InnoDB performance optimization] taken from the [http://www.mysqlperformanceblog.com/ MySQL performance blog] site.


==Performance of different Moodle modules==
==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:
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:
* The '''Chat''' module is [http://moodle.org/mod/forum/discuss.php?d=37979&parent=175079 said] to be a hog in terms of frequent HTTP requests to the main server. This can be reduced by setting the module to use ''Streamed'' updates, or, if you're using a Unix-based webserver, by running the chat in daemon mode. When using the Chat module use the configuration settings to tune for your expected load. Pay particular attention to the ''chat_old_ping'' and ''chat_refresh'' parameters as these can have greatest impact on server load.
* The '''Chat''' module is [http://moodle.org/mod/forum/discuss.php?d=37979&parent=175079 said] to be a hog in terms of frequent HTTP requests to the main server. This can be reduced by setting the module to use ''Streamed'' updates, or, if you're using a Unix-based webserver, by running the chat in daemon mode. When using the Chat module use the configuration settings to tune for your expected load. Pay particular attention to the ''chat_old_ping'' and ''chat_refresh'' parameters as these can have greatest impact on server load.
* The '''Quiz''' module is known to stretch database performance. However, it has been getting better in recent versions, and we don't know of any good, up-to-date performance measurements. (Here is a [http://moodle.org/mod/forum/discuss.php?d=68579 case study from 2007 with 300 quiz users].)
* The Moodle '''Cron''' task is triggered by calling the script ''cron.php''. If this is called over HTTP (e.g. using wget or curl) it can take a large amount of memory on large installations. If it is called by directly invoking the php command (e.g. ''php -f /path/to/moodle/directory/admin/cli/cron.php'') efficiency can be much improved.
* The Moodle '''Cron''' task is triggered by calling the script ''cron.php''. If this is called over HTTP (e.g. using wget or curl) it can take a large amount of memory on large installations. If it is called by directly invoking the php command (e.g. ''php -f /path/to/moodle/directory/admin/cli/cron.php'') efficiency can be much improved.
* The '''Recent activities''' block is consuming too many resources if you have huge number of records <code>mdl_log</code>. This is being tested to optimize the SQL query.
* The '''Recent activities''' block is consuming too many resources if you have huge number of records <code>mdl_log</code>. This is being tested to optimize the SQL query.
 
* The '''Quiz''' module is known to stretch database performance. However, it has been getting better in recent versions, and we don't know of any good, up-to-date performance measurements. (Here is a [http://moodle.org/mod/forum/discuss.php?d=68579 case study from 2007 with 300 quiz users].). The following suggestions were described by [https://moodle.org/user/view.php?id=94615&course=5 Al Rachels] in [https://moodle.org/mod/forum/discuss.php?d=347126 this forum thread]:
** make sure both Moodle, and the operating system, are installed on a [https://en.wikipedia.org/wiki/Solid-state_drive solid state drive]
** upgrade to and use [https://docs.moodle.org/dev/Moodle_and_PHP7 PHP 7]
** run MySQLTuner and implement its recommendations
See [[Performance settings]] for more information on performance-related Moodle settings.
See [[Performance settings]] for more information on performance-related Moodle settings.
==Moodle Image Optimization==
The base images delivered in the original Moodle distribution package provide unoptimized graphics, most of which can benefit from lossless recompression utilizing [http://optipng.sourceforge.net/ optipng] for PNGs, [http://www.lcdf.org/gifsicle/ gifsicle] for GIFs and [http://www.kokkonen.net/tjko/projects.html jpegoptim] for JPGs.  Optimized graphics transfer faster and provide a faster perceived response for clients[http://www.websiteoptimization.com/speed/12/], especially distance learners.  The following example will recursively optimize (without any loss of quality) all the graphics and image files included in a base Moodle installation directory on a server with the above commands installed and available.
<pre>
find /example/directory/moodle-1.9 -iname *.png -exec optipng -o7 {} \;
find /example/directory/moodle-1.9 -iname *.gif -exec gifsicle -O2 -b {} \;
find /example/directory/moodle-1.9 -iname *.jpg -exec jpegoptim -p {} \;
</pre>
Both [http://optipng.sourceforge.net/ optipng] and [http://www.lcdf.org/gifsicle/ gifsicle] are provided in the base repositories of most newer Linux distributions; [http://www.kokkonen.net/tjko/projects.html jpegoptim] must be downloaded and installed manually.


==See also==
==See also==
*Using Moodle: [http://moodle.org/mod/forum/view.php?f=94 Hardware and Performance] forum
*Using Moodle: [http://moodle.org/mod/forum/view.php?f=94 Hardware and Performance] forum
*[http://opensourceelearning.blogspot.be/2012/10/why-your-moodle-site-is-slow-five.html Why Your Moodle Site is Slow: Five Simple Settings] blog post from Jonathan Moore  
*[http://opensourceelearning.blogspot.be/2012/10/why-your-moodle-site-is-slow-five.html Why Your Moodle Site is Slow: Five Simple Settings] blog post from Jonathan Moore  
*I teach with Moodle perfomance testing: http://www.iteachwithmoodle.com/2012/11/17/moodle-2-4-beta-performance-test-comparison-with-moodle-2-3/
*I teach with Moodle performance testing: http://www.iteachwithmoodle.com/2012/11/17/moodle-2-4-beta-performance-test-comparison-with-moodle-2-3/
*[http://jfilip.ca/2013/08/20/moodle-2-4-5-vs-2-5-1-performance-and-muc-apc-cache-store/ Moodle 2.4.5 vs 2.5.2 performance and MUC APC cahe store]
*[http://jfilip.ca/2013/08/20/moodle-2-4-5-vs-2-5-1-performance-and-muc-apc-cache-store/ Moodle 2.4.5 vs 2.5.2 performance and MUC APC cahe store]
*[http://jfilip.ca/2013/09/25/moodle-performance-testing-2-4-6-vs-2-5-2-vs-2-6dev/ Moodle performance testing 2.4.6 vs 2.5.2 vs 2.6dev]
*[http://jfilip.ca/2013/09/25/moodle-performance-testing-2-4-6-vs-2-5-2-vs-2-6dev/ Moodle performance testing 2.4.6 vs 2.5.2 vs 2.6dev]
Line 263: Line 245:
*[http://tjhunt.blogspot.ca/2013/05/performance-testing-moodle.html Tim Hunt's blog (May 2, 2013) on performance testing Moodle]
*[http://tjhunt.blogspot.ca/2013/05/performance-testing-moodle.html Tim Hunt's blog (May 2, 2013) on performance testing Moodle]
*[http://newrelic.com/ New Relic, Application Performance Monitoring]
*[http://newrelic.com/ New Relic, Application Performance Monitoring]
*[http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html Performance enhacements for Apache and PHP (Apache Event MPM and PHP-FPM)]
*[http://blog.bitnami.com/2014/06/performance-enhacements-for-apache-and.html Performance enhancements for Apache and PHP (Apache Event MPM and PHP-FPM)]
 
*[https://scholarlms.net/performance-recommendations/ Performance recommendations]
*[https://enovation.ie/moodle-performance-investigation-using-performance-info/ Moodle performance investigation – using performance info ]
*[https://docs.moodle.org/dev/images_dev/2/29/Caching_Moodle_at_Scale.pdf Moodle Caching at Scale]
There have been a lot of discussions on moodle.org about performance, here are some of the more interesting and (potentially) useful ones:
There have been a lot of discussions on moodle.org about performance, here are some of the more interesting and (potentially) useful ones:
* [http://moodle.org/mod/forum/discuss.php?d=83057 Performance woes!]
* [http://moodle.org/mod/forum/discuss.php?d=83057 Performance woes!]
* [http://moodle.org/mod/forum/discuss.php?d=57028 Performance perspectives - a little script]
* [http://moodle.org/mod/forum/discuss.php?d=57028 Performance perspectives - a little script]
Line 273: Line 256:
* [https://moodle.org/mod/forum/discuss.php?d=240391#unread Advice on optimising php/db code in moodle2+]
* [https://moodle.org/mod/forum/discuss.php?d=240391#unread Advice on optimising php/db code in moodle2+]
* [https://moodle.org/mod/forum/discuss.php?d=243531 Moodle 2.5 performance testing at the OU]
* [https://moodle.org/mod/forum/discuss.php?d=243531 Moodle 2.5 performance testing at the OU]
 
* [https://moodle.org/mod/forum/discuss.php?d=273602 100 active users limit with 4vCPU]
* [https://moodle.org/mod/forum/discuss.php?d=336603#p1356423 Performance Tip ... shared...]
[[es:Recomendaciones sobre desempeño]]
[[es:Recomendaciones sobre desempeño]]
[[fr:Performance]]
[[fr:Recommandations de performance]]
[[ja:パフォーマンス]]
[[ja:パフォーマンス]]
[[de:Geschwindigkeitsempfehlungen]]
[[de:Geschwindigkeitsempfehlungen]]

Latest revision as of 15:57, 11 January 2024

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.

Obtain a baseline benchmark

Before attempting any optimization, you should obtain a baseline benchmark of the component of the system you are trying to improve. For Linux try LBS (Note: Last updated May 2002) 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 you 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).

It can be interesting to install and use the Benchmark plugin in order to find the bottlenecks of your system that specifically affect Moodle or do a load test / stress test with tool like JMeter. See moodledev JMeter documentation

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.

On very large, load-balanced, systems the performance of the shared components become critical. It's important that your shared file areas are properly tuned and that you use an effective cache (Redis is highly recommended). A good understanding of these areas of system administration should be considered a minimum requirement.

Server cluster

Using Moodle forum discussions:

Hardware configuration

Note: The fastest and most effective change that you 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.

  • Better performance is gained by obtaining the best processor capability you can, i.e. dual or dual core processors. A modern BIOS should allow you to enable hyperthreading, but check if this makes a difference to the overall performance of the processors by using a CPU benchmarking tool.
  • If you can afford them, use SCSI hard disks instead of SATA drives. SATA drives will increase your system's CPU utilization, whereas SCSI drives have their own integrated processors and come into their own when you have multiple drives. If you must have SATA drives, check that your motherboard and the drives themselves support NCQ (Native Command Queuing).
  • Purchase hard disks with a low seek time. This will improve the overall speed of your system, especially when accessing Moodle's reports. Naturally these days Solid State Drives outperform rotating media immensely, especially Enterprise-Grade SSD's.
  • Size your swap file correctly. The general advice is to set it to 4 x physical RAM.
  • Use a RAID disk system. Although there are many different RAID configurations you can create, the following generally works best:
    • install a hardware RAID controller (if you can)
    • the operating system and swap drive on one set of disks configured as RAID-1.
    • Moodle, Web server and Database server on another set of disks configured as RAID-5.
  • If your 'moodleData' area is going to be on relatively slow storage (e.g. NFS mount on to a NAS device) you will have performance issues with the default cache configuration (which writes to this storage). See the page on Caching and choose an alternative. Redis is recommended. Using GlusterFS / OCFS2 / GFS2 on a SAN device and Fiber Channel could improve performance (See more info on the Moodle forum thread, NFS performance tuing )
  • Use gigabit ethernet for improved latency and throughput. This is especially important when you have your webserver and database server separated out on different hosts.
  • Check the settings on your network card. You may get an improvement in performance by increasing the use of buffers and transmit/receive descriptors (balance this with processor and memory overheads) and off-loading TCP checksum calculation onto the card instead of the OS.
  • Read this Case Study on a server stress test with 300 users.
  • See this accompanying report on network traffic and server loads.
  • Also see this SFSU presentation at Educause (using VMWare): [1]

Operating System

  • You can use Linux(recommended), Unix-based, Windows or Mac OS X for the server operating system. *nix operating systems generally require less memory than Mac OS X or Windows servers for doing the same task as the server is configured with just a shell interface. Additionally Linux does not have licensing fees attached, but can have a big learning curve if you're used to another operating system. If you have a large number of processors running SMP, you may also want to consider using a highly tuned OS such as Solaris.
  • Check your own OS and vendor specific instructions for optimization steps.
    • For Linux look at the Linux Performance Team site.
    • For Linux investigate the hdparm command, e.g. hdparm -m16 -d1 can be used to enable read/write on multiple sectors and DMA. Mount disks with the "async" and "noatime" options.
    • For Windows set the sever to be optimized for network applications (Control Panel, Network Connections, LAN connection, Properties, File & Printer Sharing for Microsoft Networks, Properties, Optimization). You can also search the Microsoft TechNet site for optimization documents.

Caching Performance

Caching in Moodle can default to disk for a lot of the different caches which is rather slow overall, and so pretty solid gains can be made by moving this to RAM, by use of a Memory Caching Application such as Redis or Memcached. In fact I'd go as far to say the single biggest improvement we made to our (relatively small) Moodle site was installing Redis, and this is amplified when you're using classic Hard Drives rather than SSD's, and especially when they slowly but surely begin to fail (the classic slow to write, but no SMART errors or write errors - just reeeeaaallly slow).

These will also cache some database queries, meaning that they don't have to be re-run, again improving performance there. Personally, I would recommend Redis over Memcached due to better security features and being more up to date/developed. For more information/how to install Redis in particular, visit the Redis cache store page.

Web Server Performance

Most web browsers these days feature Inspector elements which will allow you to watch the time it takes for each page component to load, typically found under the "Network" tab. 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

  • PHP contains a built-in accelerator (for more recent versions of PHP, this is OpCache). Make sure it is enabled.
  • Improvements in read/write performance can be improved by putting the cached PHP pages on a TMPFS filesystem - but remember that you'll lose the cache contents when there is a power failure or the server is rebooted.
  • Performance of PHP is better when installed as an Apache/IIS6 ISAPI module (rather than a CGI). IIS 7.0/7.5 (Windows Server 2008/R2) users should choose a FastCGI installation for best performance.
  • Also check the memory_limit in php.ini. The default value for the memory_limit directive is 128M. On some sites, it may need to be larger - especially for some backup operations.
  • Also see PHP settings by Moodle version
  • Use PHP-FPM (with apache).

APC

Apache Performance

  • If you are using Apache on a Windows server, use the build from Apache Lounge which is reported to have performance and stability improvements compared to the official Apache download. Note that this is an unofficial build, so may not keep up with official releases.
  • Set the MaxRequestWorkers directive correctly (MaxClients before Apache 2.4). Use this formula to help (which uses 80% of available memory to leave room for spare):
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, you 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.
  • Consider reducing the number of modules that Apache loads in the httpd.conf file to the minimum necessary to reduce the memory needed.
  • Use the latest version of Apache - Apache 2 has an improved memory model which reduces memory usage further.
  • For Unix/Linux systems, consider lowering MaxConnectionsPerChild (MaxRequestsPerChild before Apache 2.4) in httpd.conf to as low as 20-30 (if you set it any lower the overhead of forking begins to outweigh the benefits).
  • For a heavily loaded server, consider setting KeepAlive Off (do this only if your Moodle pages do not contain links to resources or uploaded images) or lowering the KeepAliveTimeout to between 2 and 5. The default is 15 (seconds) - the higher the value the more server processes will be kept waiting for possibly idle connections. A more accurate value for KeepAliveTimeout is obtained by observing how long it takes your users to download a page. After altering any of the KeepAlive variables, monitor your CPU utilization as there may be an additional overhead in initiating more worker processes/threads.
  • As an alternative to using KeepAlive Off, consider setting-up a Reverse Proxy server in front of the Moodle server to cache HTML files with images. You can then return Apache to using keep-alives on the Moodle server.
  • If you do not use a .htaccess file, set the AllowOverride variable to AllowOverride None to prevent .htaccess lookups.
  • Set DirectoryIndex correctly so as to avoid content-negotiation. Here's an example from a production server:
DirectoryIndex index.php index.html index.htm
  • Unless you are doing development work on the server, set ExtendedStatus Off and disable mod_info as well as mod_status.
  • Leave HostnameLookups Off (as default) to reduce DNS latency.
  • Consider reducing the value of TimeOut to between 30 and 60 (seconds).
  • For the Options directive, avoid Options Multiviews as this performs a directory scan. To reduce disk I/O further use
Options -Indexes FollowSymLinks
  • Compression reduces response times by reducing the size of the HTTP response
  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>
  • Use Apache event MPM (and not the default Prefork or Worker)

IIS Performance

All alter this location in the registry:

HKLM\SYSTEM\CurrentControlSet\Services\Inetinfo\Parameters\
  • The equivalent to KeepAliveTimeout is ListenBackLog (IIS - registry location is HKLM\ SYSTEM\ CurrentControlSet\ Services\ Inetinfo\ Parameters). Set this to between 2 and 5.
  • Change the MemCacheSize value to adjust the amount of memory (Mb) that IIS will use for its file cache (50% of available memory by default).
  • Change the MaxCachedFileSize to adjust the maximum size of a file cached in the file cache in bytes. Default is 262,144 (256K).
  • Create a new DWORD called ObjectCacheTTL to change the length of time (in milliseconds) that objects in the cache are held in memory. Default is 30,000 milliseconds (30 seconds).

OpenLiteSpeed

OpenLiteSpeed has its own built in cache called LSCache, which is controlled through the Web GUI, and also is compatible with PHP OpCache. More info on optimizing OpenLiteSpeed can be found on the OpenLiteSpeed page.

Lighttpd, NginX and Cherokee Performance

You 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 you 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 if 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
//     );

Cron Performance

Cron is a very important part of the overall performance of Moodle as many asynchronous processes are offloaded to Cron, so it needs to be running and have enough through put to handle the work being given to it by the front ends.

See Cron with Unix or Linux#High performance cron tasks

Database Performance

MariaDB Performance

MariaDB Optimizations are similar to MySQL, but at the same time different due to the way MariaDB operates. Performance as a whole is typically better than MySQL using MariaDB, so if you're looking for Database Optimization, potentially switching from MySQL to MariaDB may help with performance, otherwise if you're already using MariaDB and looking to Optimize it, Performance Recommendations can be found on the MariaDB Page.

MySQL Performance

The number one thing you can do to improve MySQL performance is to read, understand and implement the recommendations in the Innodb Buffer Pool article.

The buffer pool size can safely be changed while your server is running, as long as your server has enough memory (RAM) to accommodate the value you set. On a machine that is dedicated to MySQL, you can safely set this value to 80% of available memory.

Consider setting innodb_buffer_pool_instances to the number of cores, vCPUs, or chips you have available. Adjust this value in accordance with the recommendations in the MySQL documentation.

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 you 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.

  • Enable the query cache with
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 you are doing few updates on the database.

  • Set the table cache correctly. For Moodle 1.6 set
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 up to 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';
  • Set the thread cache correctly. Adjust the value so that your thread cache utilization is as close to 100% as possible by this formula:
thread cache utilization (%) = (threads_created / connections) * 100
  • The key buffer can improve the access speed to Moodle's SELECT queries. The correct size depends on the size of the index files (.myi) and in Moodle 1.6 or later (without any additional modules and plugins), the recommendation for this value is key_buffer_size = 32M. Ideally you want the database to be reading once from the disk for every 100 requests so monitor that the value is suitable for your install by adjusting the value of key_buffer_size so that the following formulas are true:
key_read / key_read_requests < 0.01
key_write / key_write_requests <= 1.0
  • Set the maximum number of connections so that your users will not see a "Too many connections" message. Be careful that this may have an impact on the total memory used. MySQL connections usually last for milliseconds, so it is unusual even for a heavily loaded server for this value to be over 200.
  • Manage high burst activity. If your Moodle install uses a lot of quizzes and you are experiencing performance problems (check by monitoring the value of threads_connected - it should not be rising) consider increasing the value of back_log.
  • Optimize your tables weekly and after upgrading Moodle. It is good practice to also optimize your tables after performing a large data deletion exercise, e.g. at the end of your semester or academic year. This will ensure that index files are up to date. Backup your database first and then use:
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).
  • Maintain the key distribution. Every month or so it is a good idea to stop the mysql server and run these myisamchk commands.
#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.
  • Reduce the number of temporary tables saved to disk. Check this with the created_tmp_disk_tables value. If this is relatively large (>5%) increase tmp_table_size until you see a reduction. Note that this will have an impact on RAM usage.

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 you 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 you 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 you 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 you are running Linux and leave the system running for a day or two you can look at 'free' and under the 'cached' column you 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 you are not using a dedicated database server you 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.

  • Splitting mdl_log to several tables and using a VIEW with UNION to read them as one. (See Tim Hunt explanation on the Moodle forums)

Read replicas

Since Moodle 3.9 you can configure read replica's to be used where possible. For very large systems as much as 80-90% of the DB load can be moved away from the primary. For configuration see config-dist:

https://github.com/moodle/moodle/blob/master/config-dist.php#L84-L117

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:

  • The Chat module is said to be a hog in terms of frequent HTTP requests to the main server. This can be reduced by setting the module to use Streamed updates, or, if you're using a Unix-based webserver, by running the chat in daemon mode. When using the Chat module use the configuration settings to tune for your expected load. Pay particular attention to the chat_old_ping and chat_refresh parameters as these can have greatest impact on server load.
  • The Moodle Cron task is triggered by calling the script cron.php. If this is called over HTTP (e.g. using wget or curl) it can take a large amount of memory on large installations. If it is called by directly invoking the php command (e.g. php -f /path/to/moodle/directory/admin/cli/cron.php) efficiency can be much improved.
  • The Recent activities block is consuming too many resources if you have huge number of records mdl_log. This is being tested to optimize the SQL query.
  • The Quiz module is known to stretch database performance. However, it has been getting better in recent versions, and we don't know of any good, up-to-date performance measurements. (Here is a case study from 2007 with 300 quiz users.). The following suggestions were described by Al Rachels in this forum thread:
    • make sure both Moodle, and the operating system, are installed on a solid state drive
    • upgrade to and use PHP 7
    • run MySQLTuner and implement its recommendations

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: