MediaWiki Performance Optimisation
A MediaWiki installation running without any caching configuration will re-parse wikitext markup and re-query the database on every single page request. For a small wiki with light traffic this is often acceptable. For anything beyond that, it creates unnecessary load that limits how many concurrent users the server can handle and how quickly pages reach the browser.
Most MediaWiki performance problems are not hardware problems. They are caching configuration problems. The same installation that struggles under modest traffic can handle significantly more load once OPcache, APCu, and the database are correctly configured — without adding a single additional server.
This guide covers the optimisation steps in priority order, from the highest-impact changes to more advanced configurations for higher-traffic deployments. All settings are sourced from MediaWiki's official performance tuning documentation.
For background on choosing the right hosting environment for a MediaWiki installation, see "MediaWiki Hosting Guide: Choosing the Right Server for Your Wiki".
How MediaWiki Processes a Page Request
Understanding what happens when a user visits a wiki page helps explain why each caching layer matters.
When a page is requested by an unauthenticated visitor on a wiki with no caching configured, MediaWiki must: read the raw wikitext from the database, parse it through the wikitext parser (converting markup into HTML), retrieve localisation strings, check user permissions, assemble the full page output, and return it to the browser. This happens on every request, even if the page has not changed since the last time it was served.
Caching at each stage reduces or eliminates the repeated work:
| Cache Layer | What It Stores | Who Benefits |
|---|---|---|
| PHP OPcache | Compiled PHP bytecode — eliminates recompiling MediaWiki's PHP code on every request | All page requests; applies automatically once enabled |
| APCu (local object cache) | Parsed page output and internal MediaWiki objects in server memory | All page requests on single-server setups |
| Memcached or Redis (main cache) | Shared object cache across multiple servers; also handles session storage | Multi-server or high-traffic deployments |
| Parser cache | Rendered HTML output of individual wiki pages | Repeat views of unchanged pages |
| Reverse proxy (Varnish or Nginx FastCGI) | Complete HTTP responses for unauthenticated page views | Anonymous readers; highest impact for public wikis |
| CDN | Static assets (images, CSS, JavaScript) served from edge nodes geographically closer to the user | Public wikis with geographically distributed readership |
| Database buffer pool | MariaDB or MySQL table data and indexes held in RAM | All database operations |
MediaWiki's official performance tuning documentation summarises its own recommendation directly: bytecode cache for PHP, APCu as local object cache, and Memcached as the main cache — which is the configuration the Wikimedia Foundation uses for Wikipedia and its sister projects.[1]
Step 1: Confirm PHP OPcache Is Active
OPcache stores compiled PHP bytecode in memory, eliminating the need to re-parse and re-compile MediaWiki's PHP files on every request. It is included with PHP from version 5.5 onward and is the recommended PHP accelerator for MediaWiki. No MediaWiki configuration is required — OPcache operates transparently once it is installed and enabled at the PHP level.[2]
Confirm OPcache is active:
php -i | grep opcache.enable
On Ubuntu 24.04, OPcache is typically enabled by default when PHP is installed. If it is not active, install it:
sudo apt install php-opcache
Restart Apache to load the module:
sudo systemctl restart apache2
Verify it is now enabled:
php -i | grep opcache.enable
The output should show opcache.enable => On. A practical OPcache configuration for a production MediaWiki installation, set in /etc/php/8.3/apache2/conf.d/10-opcache.ini or equivalent:
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.revalidate_freq = 60
Restart Apache after changing PHP configuration:
sudo systemctl restart apache2
Step 2: Install and Configure APCu as the Local Object Cache
APCu stores MediaWiki's internal objects — parsed page output, user data, and other cached values — in shared memory on a single server. It is MediaWiki's recommended local object cache for single-server deployments and requires no separate service process to run.
Install the APCu PHP extension:
sudo apt install php-apcu
Restart Apache:
sudo systemctl restart apache2
Confirm APCu is available:
php -i | grep apcu
Then configure MediaWiki to use it as the main cache. Add the following to LocalSettings.php:
$wgMainCacheType = CACHE_ACCEL;
Important caveat. MediaWiki's official documentation notes that using CACHE_ACCEL as the main cache on a server with limited RAM — where no separate Memcached or Redis instance is running — can cause important objects to be evicted too often as the parser output cache fills available memory. In that situation, consider setting the parser cache to the database instead:
$wgParserCacheType = CACHE_DB;
This keeps parsed HTML output in the database (where it persists reliably across server restarts) while still using APCu for lighter, faster lookups of other objects.
Step 3: Configure Memcached for Multi-Server or High-Traffic Deployments
For wikis with significant traffic, or for any setup involving more than one web server, Memcached provides a shared, network-accessible cache that all application servers can use. MediaWiki's official performance documentation recommends Memcached as the main cache for larger deployments and notes that the Wikimedia Foundation runs it for Wikipedia.[3]
Install Memcached:
sudo apt install memcached php-memcached
Enable and start the service:
sudo systemctl enable memcached
sudo systemctl start memcached
Confirm it is running:
sudo systemctl status memcached
Configure MediaWiki to use Memcached in LocalSettings.php:
$wgMainCacheType = CACHE_MEMCACHED;
$wgMemCachedServers = [ '127.0.0.1:11211' ];
If Memcached is running on a separate server, replace 127.0.0.1 with its internal IP address. Do not expose Memcached on a public-facing IP address.
Redis as an alternative. Redis can replace Memcached as the main cache and offers additional capabilities including persistent storage (surviving server restarts), larger maximum object sizes, and a built-in job queue driver. For smaller to medium wikis, both Redis and Memcached are practical choices. Configuring Redis as the main cache requires adding a custom entry to $wgObjectCaches in LocalSettings.php and then pointing $wgMainCacheType to it — refer to MediaWiki's official $wgObjectCaches documentation for the exact configuration block.
Step 4: Tune the Database Buffer Pool
The InnoDB buffer pool is where MariaDB holds table data and indexes in memory. When a query's results can be served from the buffer pool rather than read from disk, response time drops significantly. The default buffer pool size is 128 MB, which is appropriate for a development environment but consistently too small for a production MediaWiki installation.
The general recommendation is to set innodb_buffer_pool_size to between 50% and 70% of available RAM when MariaDB is the primary workload on the server. On a server shared with Apache and PHP, a more conservative allocation — around 40% to 50% of RAM — leaves adequate headroom for the other processes.
Edit the MariaDB server configuration file, typically located at /etc/mysql/mariadb.conf.d/50-server.cnf:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Under the [mysqld] section, set the buffer pool size. The example below is for a server with 4 GB of RAM, allocating approximately half to the buffer pool:
innodb_buffer_pool_size = 2G
For a server with 8 GB of RAM:
innodb_buffer_pool_size = 4G
Also set the log file size, which affects write performance:
innodb_log_file_size = 256M
Restart MariaDB to apply the changes:
sudo systemctl restart mariadb
Verify the buffer pool size that is now active:
sudo mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
For MariaDB 10.9 and later, enabling buffer pool dump and restore allows the buffer pool to be pre-warmed from the previous session on startup, avoiding a cold-cache performance dip after a planned restart:
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
Step 5: Manage the Job Queue
By default, MediaWiki runs one background job from its internal job queue at the end of every web request. These jobs include tasks like updating links, purging cached pages when a template changes, and delivering email notifications. On a wiki with a backlog of pending jobs, running one job per request adds measurable latency to page responses for all users.
The recommended approach for production wikis is to disable in-request job execution and run the job queue via a scheduled cron job instead.[4]
In LocalSettings.php, disable in-request job execution:
$wgJobRunRate = 0;
Then schedule the job runner via cron. Open the crontab:
sudo crontab -e -u www-data
Add a line to run the job maintenance script every hour:
0 * * * * php /var/www/html/w/maintenance/run.php runJobs --maxtime=3600
For wikis where template changes need to propagate quickly — for example, a wiki where many pages share a common infobox template — a more frequent schedule such as every five or ten minutes is appropriate:
*/10 * * * * php /var/www/html/w/maintenance/run.php runJobs --maxtime=600
To check how many jobs are currently in the queue, visit Special:Statistics on the wiki, or run from the command line:
php /var/www/html/w/maintenance/run.php showJobs
Step 6: Enable HTTP Reverse Proxy Caching (Varnish)
A reverse proxy such as Varnish sits in front of MediaWiki and serves complete HTML responses to unauthenticated visitors without invoking PHP at all. For public wikis with significant readership, this is the highest-impact performance layer available — it removes the PHP and database entirely from the critical path for anonymous page views.
Varnish only caches responses for unauthenticated users. Logged-in users always receive dynamic responses directly from MediaWiki, so this layer does not affect the editing experience.
Install Varnish:
sudo apt install varnish
Tell MediaWiki that a reverse proxy is in use and configure it to send cache purge requests when pages are edited. In LocalSettings.php:
$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1' ];
$wgCdnMaxAge = 3600;
The $wgCdnServers setting also tells MediaWiki to read the real visitor IP from the X-Forwarded-For header rather than treating every request as coming from the proxy's IP address — which is important for accurate IP logging in Special:RecentChanges.[5]
Full Varnish VCL configuration is specific to the Varnish version and the wiki's URL structure and is beyond the scope of this article. MediaWiki's official Varnish caching manual page provides complete VCL examples for current Varnish versions.
Important: If the wiki uses HTTPS (which it should for any production installation), set $wgInternalServer to the HTTP equivalent of $wgServer so that MediaWiki sends purge requests over plain HTTP to Varnish, which does not handle HTTPS internally:
$wgInternalServer = 'http://yourdomain.com';
Step 7: Optimise Image Handling
Image processing — generating thumbnails on upload — can be CPU-intensive. MediaWiki supports two image processing libraries: GD (a PHP extension, available by default) and ImageMagick (an external program). ImageMagick is generally more capable and produces better-quality thumbnails than GD.
Install ImageMagick:
sudo apt install imagemagick
Configure MediaWiki to use it in LocalSettings.php:
$wgEnableUploads = true;
$wgUseImageMagick = true;
$wgImageMagickConvertCommand = "/usr/bin/convert";
Confirm the path to the convert binary:
which convert
For wikis that serve a large number of image thumbnails, enabling lazy thumbnail generation — so thumbnails are generated on first request rather than immediately on upload — reduces the load spike associated with bulk uploads.
Step 8: Enable ResourceLoader Caching for Static Assets
ResourceLoader is MediaWiki's system for delivering JavaScript, CSS, and other static assets to the browser. It supports browser-side caching through HTTP headers and can be configured to allow longer cache lifetimes for assets that change infrequently.
Set how long (in seconds) clients and proxies should cache ResourceLoader responses. The default is 30 days; for a production wiki where assets don't change between MediaWiki upgrades, this is a reasonable value:
$wgResourceLoaderMaxage = [ 'versioned' => 2592000, 'unversioned' => 300 ];
Versioned assets (which include a hash in the URL) can be cached for longer since a new URL is generated automatically when the content changes. Unversioned assets should use a shorter lifetime.
Performance Comparison by Configuration
| Configuration | Relative Page Load Impact | Appropriate For |
|---|---|---|
| No caching (default) | Highest server load per request | Development and testing environments only |
| OPcache only | Significant improvement on PHP execution time | Very small wikis with minimal traffic |
| OPcache and APCu | Substantial improvement; parser output cached in memory | Small to medium internal wikis |
| OPcache, APCu, and Memcached | High performance for authenticated and anonymous users | Medium to large wikis with active editing |
| Above plus Varnish reverse proxy | Anonymous page views served without touching PHP | Public wikis with significant anonymous readership |
| Above plus database buffer pool tuning | Reduced disk I/O for database-heavy pages and searches | Any wiki where database queries are a measurable bottleneck |
Diagnosing a Slow Wiki
Before making configuration changes, it is worth identifying where the slowness actually originates. The most common causes of MediaWiki performance problems are:
Caching not configured. Check Special:Version for the cache type in use. If it shows none or DB, the object cache has not been configured. Setting up OPcache and APCu typically produces an immediate and noticeable improvement.
Job queue backlog. A large number of pending jobs (visible at Special:Statistics under "Queued jobs") can cause slow page responses if $wgJobRunRate is still set to 1. Offloading jobs to a cron-based runner as described in Step 5 resolves this.
Underpowered database buffer pool. If the database buffer pool is smaller than the active working set of the wiki's data, every query that misses the pool results in a disk read. Check the pool size currently in use:
sudo mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
Heavyweight extensions. Some extensions add expensive operations to every page render. CirrusSearch with Elasticsearch is resource-intensive and should run on a separate server rather than on the same VPS as the wiki application. Extensions like Semantic MediaWiki add significant parser overhead. Identifying which extensions are contributing most to slow page loads requires profiling at the application level.
Insufficient server RAM. If the server is regularly swapping memory to disk, no amount of caching configuration will compensate. Monitor RAM usage under load:
free -h
Best Practices
Apply OPcache and APCu configuration immediately after the initial installation rather than waiting for performance problems to become noticeable — it is simpler to configure before users begin relying on the wiki than after. Set $wgJobRunRate = 0 and run jobs via cron on any wiki that has more than a handful of active editors, since template changes affecting many pages can otherwise flood the job queue and add significant latency to subsequent page requests. Tune the MariaDB buffer pool size based on the actual size of the wiki's database, not the server's total RAM — allocating 4 GB to the buffer pool when the database is 500 MB provides no benefit and wastes RAM that could be used elsewhere. Verify caching is working by checking Special:Version for the reported cache type after configuration changes. Revisit performance configuration when adding resource-intensive extensions like CirrusSearch or Semantic MediaWiki, since they change the resource profile of the installation materially.
Common Mistakes
Installing MediaWiki, running it under default settings, and diagnosing poor performance as a hardware problem is the most common sequence of mistakes — in the majority of cases, adding APCu and correctly sizing the database buffer pool resolves performance complaints without any change to the underlying infrastructure. Configuring APCu as both the main cache and the parser cache on a server with limited RAM is a specific documented pitfall: the parser output cache can fill available APCu memory, causing important objects to be evicted. The fix is to set $wgParserCacheType = CACHE_DB so parser output is stored in the database rather than competing for the same memory as other cached objects. Pointing $wgCdnServers to a reverse proxy without setting $wgInternalServer to the HTTP server address will cause MediaWiki to send HTTPS purge requests to Varnish, which cannot process them. Leaving $wgJobRunRate at its default value of 1 on a wiki that has accumulated a large job backlog will cause every page request to run a background job synchronously, adding consistent latency for all users.
Frequently Asked Questions
How do I check whether caching is currently working?
Visit Special:Version on the wiki. The "Cache type" row shows what object cache MediaWiki is currently using. If it shows none or DB, no object cache has been configured. If it shows APCu or Memcached, the cache is active.
Is Varnish required for a MediaWiki installation?
No. Varnish provides the highest impact for public wikis with significant anonymous readership by eliminating PHP from the critical path for unauthenticated page views. For internal wikis where all users are logged in, Varnish provides little benefit, since it only caches responses for unauthenticated visitors. OPcache and APCu provide meaningful improvement for any wiki regardless of whether readers are logged in.
Should I use Memcached or Redis?
Both are valid choices. Memcached is simpler to configure and is what the Wikimedia Foundation uses for Wikipedia. Redis supports persistent storage, larger objects, and can also act as a job queue driver, which can be useful for wikis using extensions like Semantic MediaWiki that benefit from Redis's larger object capacity. For most straightforward MediaWiki deployments, Memcached is sufficient.
Will these optimisations affect how editors experience the wiki?
Caching layers like Varnish only serve content to unauthenticated visitors. Editors who are logged in always receive dynamically generated pages directly from MediaWiki. Caching changes at the PHP or object cache level improve performance for both editors and readers by reducing the time MediaWiki spends on each request.
How do I monitor whether the job queue is building up?
Visit Special:Statistics and look at the "Queued jobs" count. A consistently growing number, particularly following template edits, suggests the job runner is not keeping up. Setting $wgJobRunRate = 0 and running runJobs.php via cron at a more frequent interval resolves this.
Do I need to reconfigure performance settings after a MediaWiki upgrade?
Generally no — the performance settings in LocalSettings.php and the database configuration persist across upgrades. However, new releases occasionally introduce changes to how caching is configured or new recommended settings. Reviewing the release notes for any performance-related changes is good practice during major version upgrades.
Conclusion
MediaWiki's performance under load is primarily a caching configuration problem, not a hardware problem. A correctly configured installation — OPcache active at the PHP level, APCu or Memcached as the object cache, the database buffer pool sized to the actual data footprint, and the job queue running via cron rather than inline with page requests — handles significantly more traffic than the default configuration on the same hardware.
The optimisation steps in this guide are ordered by impact: OPcache and APCu should be in place before anything else, since they provide the most benefit with the least configuration effort. Database tuning and job queue management address the next most common bottlenecks. Varnish and CDN configuration are valuable for public wikis with substantial anonymous readership and add meaningful complexity, so they make more sense once the foundational caching layers are confirmed to be working correctly.
For help applying this configuration to an existing installation, or as part of a new deployment, see SolidWiki's MediaWiki Development Services page.
See Also
- How to Install MediaWiki on Ubuntu Server
- MediaWiki Hosting Guide: Choosing the Right Server for Your Wiki
- MediaWiki Security Hardening Guide
- MediaWiki SEO Best Practices
- Top 10 MediaWiki Extensions for Business Wikis
References
- ↑ MediaWiki.org, "Manual: Performance tuning", https://www.mediawiki.org/wiki/Manual:Performance_tuning
- ↑ MediaWiki.org, "Manual: Performance tuning", https://www.mediawiki.org/wiki/Manual:Performance_tuning
- ↑ MediaWiki.org, "Manual: Performance tuning", https://www.mediawiki.org/wiki/Manual:Performance_tuning
- ↑ MediaWiki.org, "Manual: Job queue", https://www.mediawiki.org/wiki/Manual:Job_queue
- ↑ MediaWiki.org, "Manual: $wgCdnServers", https://www.mediawiki.org/wiki/Manual:$wgCdnServers