Optimizing MediaWiki Performance for Large-Scale Community Sites
What actually matters for high-traffic MediaWiki: job queue management, layering caches correctly, PHP-FPM tuning, and read-replica architecture.
Large community wikis — tens of thousands of daily edits, heavy template use, live activity feeds — hit MediaWiki's scaling limits in a predictable order: job queue backlog, caching misconfiguration, PHP worker starvation, then database read load. This article covers each stage with the settings that actually exist in current MediaWiki (older advice about wgJobRunRate micro-management and Redis constants no longer applies).
1. The job queue: measure before tuning
Special:Statistics shows the jobs backlog; watching it over a week tells you what your wiki actually produces (template updates after transclusion changes, Echo notifications, SearchUpdate jobs). The $wgJobRunRate era of percentage-based throttling is gone; since MediaWiki 1.36 jobs run via runJobs.php or a job runner, and the recommended production setup is dedicated job runners off the request path:
# cron: process jobs continuously, in the background
php maintenance/runJobs.php --maxtime=55
Backlog policy: a few thousand jobs is normal after large template edits; a permanently growing backlog means jobs fail (check runJobs.log for errors) or the wiki is under-powered. Job queue tuning is observability work, not a magic constant.
2. Layered caching done right
- PHP opcache — 256 MB + 20000 files; non-negotiable
- APCu + parser cache — on single web servers:
$wgMainCacheType = CACHE_ACCELand$wgParserCacheType = CACHE_ACCEL - Redis for multi-server — there is no
CACHE_REDISconstant; you register the backend via$wgObjectCaches(RedisBagOStuff) and reference it by name, as shown in the caching guides on this blog - HTTP cache — the layer that actually carries a community wiki's anonymous read load:
$wgUseCdnwith nginx/Varnish in front, so the PHP process almost never sees repeat anonymous views
After any cache configuration change or extension upgrade, purge selectively (action=purge per page, or maintenance/rebuild...* tools) rather than flushing everything — a full cache flush on a big wiki causes a stampede that recreates the slowness you just fixed.
3. Web server and PHP-FPM
Apache's prefork + mod_php becomes the ceiling quickly. The standard high-traffic shape:
- php-fpm — dedicated pool per site,
pm.max_childrensized to RAM (each MediaWiki PHP worker can use 100–200 MB on template-heavy pages); start atpm.max_children = 20on 4 GB and measure - nginx in front — static files, gzip/brotli, HTTP caching (or Varnish for more control); Apache behind if your setup requires it
- Slow request logging —
request_slowlog_timeoutshows which requests eat workers
4. Database: replicas after the cheap wins
Indexes and buffer pool first (see the 'why slow' guide), then replication:
$wgDBservers = [
[
'host' => 'db-primary.internal',
'dbname' => 'wiki',
'type' => 'mysql',
'load' => 0, // no reads
],
[
'host' => 'db-replica-1.internal',
'dbname' => 'wiki',
'type' => 'mysql',
'load' => 1,
],
];
With $wgDBservers, queries route: reads to replicas (with a replica lag limit), writes to the primary. This is where community-wiki scale is genuinely won — everything before it delays the day, replication removes the ceiling. MariaDB and MySQL both do this; keep an eye on replica lag via SHOW SLAVE STATUS and the wiki's instrumentation.
5. The order that works
- opcache + APCu parser cache (day 1, free)
- Job runner + backlog monitoring (day 2)
- php-fpm + nginx with HTTP cache (week 1)
- DB buffer pool sizing + slow-query fixes (week 2)
- Read replicas when step 4 stops being enough
Public community wikis rarely need exotic tuning — they need the five layers above present and measured. The performance manual and Wikimedia's own wikitech operation docs describe the end-state architecture if the wiki keeps growing.