Performance
From MoodleDocs
Jump to: ,
Location: Administration > Server > 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
Before attempting any optimization, you should obtain a baseline
benchmark of the component of the system you are trying to improve. For
Linux try
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 as has 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).
Scalability
Moodle's design (with clear separation of application layers) allows for strongly scalable setups. (Please check the list of .)
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 area,
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.
See also:
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 (eg 4GB). 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 .
- 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.
- 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.
- 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 on network traffic and server loads.
Operating System
- You can use (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 .
- Check your own OS and vendor specific instructions for optimization steps.
- For Linux look at the 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 for optimization documents.
Web server performance
Installing and the extension will allow you to watch the time it takes for each page component to load. Also, the extension will evaluate your page against Yahoo's () for fast loading websites.
PHP performance
- You are strongly recommended to use a PHP accelerator to ease CPU load, such as , , or . (Take care to choose a PHP accelerator that is known to work well with your version of PHP and note that Turck MMCache is and can cause failures with PHP 5).
- Improvements in read/write performance can be improved by putting the cached PHP pages on a 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/IIS ISAPI module (rather than a CGI).
- Also check the memory_limit in php.ini, reduce it to 16M for Moodle version earlier than 1.7 (See this forum discussion). For Moodle 1.7 or later, it is recommended that the value of memory_limit should be 40M. As of the default value for the memory_limit directive is 128M.
Apache performance
- If you are using Apache on a Windows server, use the build from 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 MaxClients directive correctly. 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
- Memory usage of apache process is usually 10MB, so a general
rule of thumb is to divide your available memory in megabytes by 10 to
get the value of MaxClients. To find the max memory usage of apache
processes read the value from the shell command:
#ps -ylC httpd --sort:rss
- 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
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.
- 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 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.
- 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 to 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
- Caching - Apache can be told to make pages load a lot
faster by specifying that the browser should cache some various page
elements such as images and reuse them from local memory rather than
ask for them again every time a page is requested. How to do this
varies slightly between OSes but there are two basic steps:
- Install and enable mod_expires - refer to documentation or man pages
- Add this code to the virtual server config file within the
section for the root directory (or within the
.htaccess file if AllowOverrides is On):
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType text/html "access plus 1 seconds"
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/jpeg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType text/css "access plus 1 week"
ExpiresByType text/javascript "access plus 1 week"
ExpiresByType application/x-javascript "access plus 1 week"
ExpiresByType text/xml "access plus 1 seconds"
The effect is to make everything stay in the cache except HTML and
XML, which change dynamically. It's possible to gain a several hundred
percent decrease in load times this way. Adjust the cache times
according to how often your images etc change.
More info:
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 to 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).
Lighttpd performance
You can increase web server performance by using the light-weight webserver
in combination with PHP in fastCGI-mode. Lighttpd has a lower memory
consumption than Apache - typically 10M for each process. See this for configuration and administration links.
Database performance
Moodle contains a script which will display some key database performance statistics from the . Run the script in your browser as in the following example:
Use the data displayed as a guide to tune and improve the performance of your database server.
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 you are able, the
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
(min), and for Moodle 1.7 set
table_cache = 512
(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 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';
- 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.
- Moodle's tables are in the MyISAM format, so turn InnoDB off as there is no performance gain. Add
skip-innodb
to your my.cnf
file. If you must use InnoDB, you'll have to convert all of Moodle's tables. To do this run the innodb script:
- See also this forum discussion which looks at the MyISAM vs InnoDB options.
PostgreSQL performance
There are some good papers around on tuning PostgreSQL, 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.
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
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:
And there is lots of good stuff here as well:
Based on Andrew McMillan's post at Tuning PostgreSQL forum thread.
Other database performance links
Moodle Admin settings
- In Moodle 1.7 or later, set the Cache type for your server: Site Admin -> Server -> Performance -> Cache type. There are several options available.
- If you do not have eaccelerator or mmemcached
installed, choose "internal" (which makes use of the record/internal
cache - see the next bullet point).
- If you have a single server and have compiled eaccelerator with shared memory support, set the cache type to the eaccelerator option.
- If you have a separate memcached server, set the cache type to memcached and enter a csv list of server IP addresses.
- Enable the record/internal cache: Site Admin ->
Server -> Performance -> Record cache = True. Set the maximum
amount of memory allocated to the cache in the Int Cache Max box. This
will enable a primary cache for database records, without using any
database engine cache, e.g. MySQL/PostgreSQL cache. See for a full discussion.
- Enable the language cache.
- Large log files can cause overall performance to degrade over
time. If you observe that the site has gradually got slower loading
pages in the browser, reduce your Log life time setting (Admin/Server/Cleanup).
- Performance can be greatly improved by allowing Moodle to use the system zip/unzip
commands (rather than PHP-based zip libraries) - visit
Admin/Server/System Paths and enter the path to the relevant
executables. (Similarly, filling in the path to du will improve Moodle's speed at listing directory contents.)
- Note that using secure web connections (https rather than http)
carries a higher processing burden, both for the webserver and the
client - particularly because cacheing cannot be used as effectively,
so the number of file requests is likely to increase dramatically. For
this reason using https for all Moodle pages is not recommended. You
can enable https just for the login screen, simply from Moodle's config
page.
- Check your filters. Having too many filters active
can have serious effects on server load, especially on lower-end
systems. The number of active filters has a direct effect on the
perceived latency of your site; that is the time taken for each page
impression.
- Enable the text cache but do not "Filter all
strings" unless you have a specific need. If in doubt profile the
performance, and see how your changes affect the processing time.
- Check your anti-virus measures on the server.
Although they are useful for preventing security holes being exploited,
some "On-Demand" scanners can affect performance by scanning page
content (word, ppt files etc).
- If there are performance problems loading course pages, check the Resource module settings. The setting resource_filterexternalpages is known to slow-down course pages and should be set to 'No' for better performance.
- Check your forum settings. To improve performance set
forum_trackreadposts = No and forum_usermarksread = Yes (this will
impact on the convenience of your users' forum experience). Also
consider setting the time of the day when old posts are cleared from
the read table (forum_cleanreadtime) to when your site is less busy.
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 Quiz module is known to stretch database performance. Try to optimise your database server by tuning. See for a brief report on performance for 55 students simultaneously using quizzes
- See this Case Study for an extensive server stress test with 300 quiz users.[1] And this accompanying report on network traffic and server loads.
- 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/cron.php) efficiency can be much improved.
- The Recent activities block is consuming to much resources if you have huge number of records
mdl_log
. this is being tested to optimize the SQL query.
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 for PNGs, for GIFs and for JPGs. Optimized graphics transfer faster and provide a faster perceived response for clients,
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.
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 {} \;
Both and are provided in the base repositories of most newer Linux distributions; must be downloaded and installed manually.