Skip to content

MediaWiki Performance Tuning — Caching (FileCache, Redis), JobQueue, and Profiling

DodaTech Updated 2026-06-26 9 min read

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.php every 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

  1. What are the three caching layers in MediaWiki and how do they work together?
  2. How does Redis improve performance compared to FileCache alone?
  3. What is the JobQueue and what types of tasks does it handle?
  4. 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

How much RAM does Redis need for a wiki cache?

Start with 256 MB for a small wiki (under 10,000 pages). For larger wikis, 1-4 GB is typical. Monitor Redis memory usage with redis-cli info memory and adjust as needed.

Can I use both FileCache and Redis together?

Yes. They serve different purposes. FileCache caches full HTML pages for anonymous users. Redis caches database query results and parsed content for all users. They work well together.

How do I know if caching is working?

Check response headers: X-Cache header indicates cache hits. Monitor database query counts before and after enabling cache. Use profiling to measure page generation time.

What happens when cache memory is full?

Redis starts evicting the least recently used keys. Configure maxmemory and maxmemory-policy in redis.conf. The default policy (noeviction) returns errors when memory is full.

Does VisualEditor work with caching?

Yes, but VE requires real-time Parsoid conversion which bypasses the page cache. VE requests are not cached. The wikitext editor uses cached pages for read-only access.

Mini Project

Goal: Measure, optimize, and document performance improvements.

  1. Baseline measurement: Measure page load time for the Main Page (anonymous and logged-in)
  2. Enable FileCache and re-measure anonymous page load time
  3. Install Redis and configure for object cache
  4. Re-measure both anonymous and logged-in page load times
  5. Set up JobQueue and verify it processes jobs
  6. Configure cron for runJobs.php
  7. Enable profiling and identify the top 3 slowest operations
  8. Create a "Performance Report" page documenting:
    • Before/after measurements
    • Configuration changes made
    • Bottlenecks identified
    • Recommendations for future optimization
  9. 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