MediaWiki Performance Tuning — Caching (FileCache, Redis), JobQueue, and Profiling
In this tutorial, you will learn about MediaWiki Performance Tuning. We cover key concepts, practical examples, and best practices to help you master this topic.
Performance tuning in MediaWiki involves configuring caching layers (FileCache, Redis, Memcached), managing the JobQueue for deferred processing, enabling profiling to identify bottlenecks, and optimizing database queries — the same techniques Wikipedia uses to serve pages to hundreds of millions of users with sub-second response times.
What You'll Learn
- Understanding MediaWiki caching layers
- Configuring FileCache for anonymous users
- Setting up Redis or Memcached for object cache
- Managing the JobQueue
- Enabling profiling and identifying bottlenecks
- Optimizing database queries
Why It Matters
A slow wiki frustrates users and reduces productivity. Every page load triggers database queries, template Parsing, and cache checks. Without optimization, a page that takes 3 seconds to load feels sluggish. With proper caching, the same page loads in under 200 milliseconds. Performance tuning is not optional for wikis with more than a few hundred pages or more than a handful of concurrent users.
Real-World Use
A DodaTech wiki with 5,000 pages and 50 concurrent users was experiencing 4-second page loads. The administrator enabled FileCache for anonymous users (reducing load time to 0.5 seconds), configured Redis for object caching (reducing database queries by 80%), and tuned the JobQueue (eliminating a 10-minute backlog). Page load times dropped below 200 milliseconds for most requests.
Learning Path
flowchart LR A["36: Logging & Monitoring"] --> B["37: Backup & Restore"] B --> C["38: Performance Tuning"] C:::current D["39: Upgrading MediaWiki"] E["40: Security"] C --> D --> E classDef current fill#38bdf8,color#0f172a,stroke-width:2px
Caching Layers
MediaWiki has three caching layers:
Browser Cache (client-side)
↓
CDN / Reverse Proxy (Varnish, Cloudflare)
↓
FileCache (disk-based, for anonymous users)
↓
Object Cache (Redis, Memcached — for logged-in users)
↓
Database (final source of truth)
Each layer reduces load on the next. A well-configured wiki serves most requests from cache without touching the database.
FileCache
FileCache stores rendered HTML pages as static files on disk. It only serves anonymous (not logged-in) users.
Enabling FileCache
// In LocalSettings.php
$wgUseFileCache = true;
$wgFileCacheDirectory = "$IP/cache/filecache";
Configuration
// Cache expiry (seconds)
$wgCacheEpoch = '20260601000000'; // Cache valid until this date
// Exclude special pages from cache
$wgFileCacheExcludeRegexp = '/^(Special|API):/';
Verification
Check that cached files are being created:
ls -la /opt/lampp/htdocs/mediawiki/cache/filecache/
Each cached page is stored as a separate HTML file. Anonymous visitors are served these files without any PHP or database processing.
Drawbacks
- Only works for anonymous users
- Does not invalidate automatically when templates change
- Can use significant disk space on large wikis
- Not suitable for wikis requiring real-time content updates
Object Cache (Redis)
Object cache stores database query results, parsed templates, and user session data in memory.
Installing Redis
# Install Redis server
apt install redis-server
# Start Redis
systemctl enable redis-server
systemctl start redis-server
Installing php-redis
apt install php-redis
Configuring MediaWiki for Redis
// In LocalSettings.php
// Use Redis for object cache
$wgMainCacheType = CACHE_REDIS;
$wgRedisServers = [
'127.0.0.1:6379' => [
'password' => null,
'serializer' => 'php',
],
];
// Use Redis for sessions (if using multiple web servers)
$wgSessionCacheType = CACHE_REDIS;
// Use Redis for parser cache (parsed page output)
$wgParserCacheType = CACHE_REDIS;
// Use Redis for message cache
$wgMessageCacheType = CACHE_REDIS;
Verifying Redis
# Check Redis is running
redis-cli ping
# Should return: PONG
# Monitor cache usage
redis-cli info | grep keys
Redis Performance Impact
With Redis, typical improvements:
- Database queries: 80-90% reduction
- Page load time: 60-80% reduction
- Template parsing: 90% reduction
Alternative: Memcached
Memcached is an alternative to Redis with similar performance.
apt install memcached php-memcached
$wgMainCacheType = CACHE_MEMCACHED;
$wgMemCachedServers = [
'127.0.0.1:11211'
];
Redis is generally preferred over Memcached because it offers persistence, more data types, and better monitoring capabilities.
JobQueue
The JobQueue handles deferred tasks that do not need to run immediately.
What Jobs Do
- Refresh link tables after page edits
- Send email notifications
- Rebuild search index
- Generate image thumbnails
- Process template transclusions
Checking JobQueue Status
cd /opt/lampp/htdocs/mediawiki
php maintenance/showJobs.php
Output:
Job queue:
refreshLinks: 1,234 jobs
sendMail: 456 jobs
enotifNotify: 89 jobs
Total: 1,779 jobs
Running Jobs
# Run all pending jobs
php maintenance/runJobs.php
# Run specific type of job
php maintenance/runJobs.php --type=refreshLinks
# Run jobs in a loop (production use)
php maintenance/runJobs.php --wait
Configuring the JobQueue
// Use Redis for job queue (recommended for production)
$wgJobTypeConf['default'] = [
'class' => 'JobQueueRedis',
'order' => 'fifo',
'redisServer' => '127.0.0.1:6379',
];
// Job execution rate per page request
$wgJobRunRate = 1; // Run 1 job per page view
JobQueue Best Practices
- Run
runJobs.phpevery minute via cron - Monitor queue depth with
showJobs.php - Alert administrators when queue exceeds 1,000 jobs
- Use Redis backend for reliability
- Schedule resource-intensive jobs during low-traffic hours
Profiling
Profiling helps identify what makes pages load slowly.
Enabling Profiling
// In LocalSettings.php (debugging only, not production)
$wgProfiler = [
'class' => 'ProfilerXhprof',
'output' => 'text',
];
Reading Profile Output
Add ?forceprofile=1 to any page URL. Output example:
Profile:
Total: 1,234.5ms
Database: 456.7ms (37%)
Parser: 234.5ms (19%)
Template transforms: 123.4ms (10%)
Other: 419.9ms (34%)
Profiling Tips
- Profile before and after each optimization
- Focus on the largest percentage first
- Template processing is a common bottleneck
- Database queries should be under 50ms per page
- Total page generation time should be under 500ms
Database Query Optimization
Slow Query Log
Enable MySQL slow query logging:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- Log queries over 1 second
Check /var/log/mysql/mysql-slow.log for slow queries.
Index Optimization
-- Check which indexes are missing or unused
SELECT * FROM sys.schema_unused_indexes;
-- Run ANALYZE TABLE for query optimizer
ANALYZE TABLE page, revision, text;
Query Cache
// Enable MySQL query cache (deprecated in MySQL 8.0, use Redis instead)
$wgDBservers = [
[
'host' => 'localhost',
'load' => 1,
'flags' => DBO_DEFAULT,
],
];
CDN and Reverse Proxy
Cloudflare
// Configure for Cloudflare
$wgUseCdn = true;
$wgCdnServers = [
'173.245.48.0/20',
'103.21.244.0/22',
// Cloudflare IP ranges
];
// Trust Cloudflare headers
$wgCdnServersNoPurge = [
'173.245.48.0/20',
];
Varnish
// Configure for Varnish reverse proxy
$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1:6081' ];
$wgSquidPurgeUseHostHeader = true;
Performance Checklist
☐ Enable FileCache for anonymous users
☐ Install Redis and configure object cache
☐ Set up JobQueue with Redis backend
☐ Configure cron for runJobs.php
☐ Enable profiling and identify bottlenecks
☐ Optimize slow database queries
☐ Set up CDN (Cloudflare or Varnish)
☐ Monitor page load times
☐ Tune PHP-FPM and MySQL for your server
☐ Enable OPcache for PHP bytecode caching
What You Learned
- FileCache serves static HTML to anonymous users
- Redis provides fast in-memory caching for all users
- Object cache reduces database queries by 80-90%
- JobQueue handles deferred tasks asynchronously
- Profiling identifies performance bottlenecks
- Database optimization includes slow query logging and indexing
- CDN and reverse proxy cache pages at the network edge
In the next lesson, you'll learn about upgrading MediaWiki.
Common Mistakes
| Mistake | Why It Happens | How to Fix |
|---|---|---|
| FileCache not working | Cache directory not writable | Create the file cache directory and set proper permissions: mkdir -p cache/filecache && chmod 755 cache/filecache. |
| Redis connection refused | Redis not running or wrong port | Check Redis status: systemctl status redis-server. Verify the port in LocalSettings.php matches the Redis configuration. |
| JobQueue growing without bound | No cron job processing jobs | Set up a cron job to run runJobs.php every minute. Monitor queue depth with showJobs.php and alert on high counts. |
| Page load slower after caching | Cache invalidation not working | Check cache configuration. If templates change, cached pages may not reflect changes. Use ?action=purge to test manual invalidation. |
| Profiling enabled in production | Debug configuration exposed | Disable profiling in production. Use it only on a staging environment. Profiling adds overhead to every page load. |
Practice Questions
- What are the three caching layers in MediaWiki and how do they work together?
- How does Redis improve performance compared to FileCache alone?
- What is the JobQueue and what types of tasks does it handle?
- Challenge: Tune your wiki for performance. Enable FileCache and verify it works by checking the cache directory. Install Redis and configure it for object, parser, and session cache. Measure page load time before and after (use browser developer tools or curl). Set up the JobQueue with Redis backend and configure cron to run jobs every minute. Check the queue depth before and after optimization. Enable profiling temporarily and identify the top 3 bottlenecks. Document each optimization with before/after measurements.
FAQ
Mini Project
Goal: Measure, optimize, and document performance improvements.
- Baseline measurement: Measure page load time for the Main Page (anonymous and logged-in)
- Enable FileCache and re-measure anonymous page load time
- Install Redis and configure for object cache
- Re-measure both anonymous and logged-in page load times
- Set up JobQueue and verify it processes jobs
- Configure cron for runJobs.php
- Enable profiling and identify the top 3 slowest operations
- Create a "Performance Report" page documenting:
- Before/after measurements
- Configuration changes made
- Bottlenecks identified
- Recommendations for future optimization
- Set up monitoring for cache hit rates and queue depth
What's Next
A fast wiki is a usable wiki. Now let's make sure you can safely upgrade when new versions are released.
Continue to Lesson 39: Upgrading MediaWiki — learn about version compatibility, upgrade procedures, testing, and rollback strategies.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro