Advanced MediaWiki Configuration for Power Users

Why “Advanced” Matters

Why “Advanced” Matters

Most MediaWiki installations live happily on the default $wgSitename, $wgScriptPath and a few shared extensions. Power users, however, soon discover that those defaults are a double‑edged sword: they get you up and running, but they also hide a treasure chest of knobs you can turn for speed, security and flexibility. Below is a dense, hands‑on walk‑through of the settings you’ll actually tweak once you’ve outgrown the “just works” stage.

1. Getting the Foundations Right

Before you massage $wgCacheDirectory or tango with $wgObjectCache, make sure the basic environment variables are rock‑solid.

  • $IP – the absolute path to the MediaWiki root. Hard‑code it if you ever plan to move the codebase across servers.
  • $wgScriptPath – the public URL segment (e.g. /w). A typo here makes every link break.
  • $wgArticlePath – the “pretty URL” pattern, like /wiki/$1. Remember: you need matching rewrite rules in .htaccess or nginx.conf.

These three form the spine; any later tweak feels like moving your ribs without adjusting the spine – it hurts.

2. Database Deep‑Dive

Most newbies stop at $wgDBservers. For serious traffic, you’ll want a read/write split, connection pooling and even a fallback cluster.

// Example: master‑slave setup with LoadBalancer
$wgDBservers = [
    [
        'host' => 'db-master.example.org',
        'dbname' => 'wiki',
        'user' => 'wikiuser',
        'password' => '••••••••',
        'type' => 'mysql',
        'load' => 0,
        'flags' => DBO_DEFAULT,
    ],
    [
        'host' => 'db-replica1.example.org',
        'dbname' => 'wiki',
        'user' => 'wikiuser',
        'password' => '••••••••',
        'type' => 'mysql',
        'load' => 100, // higher load means more reads here
        'flags' => DBO_DEFAULT,
    ],
];

Two tips:

  1. Replication lag can cause stale reads; set $wgReadOnly during massive imports.
  2. If you’re on PostgreSQL, look at $wgDBtype = "postgres"; and enable $wgSearchType = "CirrusSearch"; for better full‑text support.

3. Caching – The Real Speed‑Booster

MediaWiki ships with a simple file cache, but power users treat it like a lazy‑dog: feed it, then let it run. The hierarchy is:

  • File cache ($wgCacheDirectory) – great for static HTML fragments.
  • MessageCache ($wgMessageCacheType) – switch to APCu or Redis for instant translation lookups.
  • Parser cache ($wgParserCacheType) – set to CACHE_ACCEL if you have an opcode cache.
  • Object cache ( $wgObjectCache ) – the heavyweight champion; most sites use Memcached or Redis.
// Using Redis as the object cache
$wgObjectCache = [
    'class' => 'RedisBagOStuff',
    'servers' => [
        [ '127.0.0.1', 6379 ],
    ],
    'persist' => true,
];

Don’t forget $wgUseSquid when you have a reverse‑proxy CDN. It tells MediaWiki to send Cache‑Control: private only when necessary, letting the CDN cache everything else.

4. Uploads, MIME Types & Antivirus

If your wiki is a collaborative knowledge‑base for design assets, you’ll be handling hundreds of megabytes daily. Fine‑tune the upload pipeline:

  • $wgFileExtensions – whitelist the exact types you need; every extra entry is a possible attack surface.
  • $wgVerifyMimeType – always enabled; it checks the real file signature.
  • $wgCheckFileExtensions – keep it true; the UI will politely refuse unknown formats.
  • $wgAntivirus – set to ClamAV or internal for on‑the‑fly scanning.
// Example: shared uploads across a farm
$wgEnableUploads = true;
$wgUploadPath = "$wgScriptPath/images";
$wgUploadDirectory = "$IP/images";
$wgHashedUploadDirectory = true; // spreads files into subfolders

When you turn on $wgHashedUploadDirectory, the filesystem stays tidy even after a few hundred thousand pictures. It’s a tiny tweak with a massive payoff.

5. ResourceLoader – Modern JS & CSS

Gone are the days of loading common.js on every request. $wgResourceModules lets you bundle assets per skin or per feature. Here’s a snippet that pulls in a custom script only for logged‑in users.

$wgResourceModules['ext.myExtension.user'] = [
    'scripts' => [ 'modules/ext.myExtension.user.js' ],
    'styles' => [ 'modules/ext.myExtension.user.css' ],
    'targets' => [ 'desktop', 'mobile' ],
    'dependencies' => [ 'mediawiki.util' ],
    'position' => 'top',
    'localBasePath' => __DIR__,
    'remoteBasePath' => "$wgScriptPath/extensions/MyExtension",
    'skipFunction' => function ( $resourceLoader, $skin ) {
        return !$skin->getUser()->isLoggedIn();
    },
];

Don’t forget to purge the ResourceLoader cache after changes: php maintenance/rebuildLocalisationCache.php --force or simply php maintenance/update.php. It feels like a chore, but it saves you from mysterious UI glitches that pop up months later.

6. Jobs Queue – Offloading Work

Whenever you edit a page, MediaWiki fires a slew of background jobs: index updates, link tables, thumbnail generation. Tuning the queue prevents those jobs from choking the webworkers.

  • $wgJobRunRate – default 1 (run a job on every page view). In high‑traffic environments, bring it down to 0.1 and run a dedicated runJobs.php daemon.
  • $wgJobTypeConf – assign heavy jobs (e.g. image scaling) to a separate queue handled by a beefier server.
// Separate queue for thumbnail generation
$wgJobTypeConf['imageResize'] = [
    'class' => 'JobQueueRedis',
    'servers' => [ [ '127.0.0.1', 6379 ] ],
    'dbId' => 1,
];

If you’re using Redis, you can even monitor queue lengths via redis-cli LLEN jobqueue:default. A sudden spike usually means a rogue extension is queuing too many jobs.

7. Security Hardening

Power users treat security like a checklist, not an afterthought.

  • $wgSecretKey – generate a unique, 64‑character random string. Never commit it to a public repo.
  • $wgSessionsInObjectCache – store sessions in Redis; this prevents session fixation attacks.
  • $wgEnableEmail – keep it true only if you need password resets; otherwise set it false to eliminate email‑spoof vectors.
  • $wgPasswordPolicy – enforce a minimum length, mixed case and disallow common passwords.
// Example: tight password policy
$wgPasswordPolicy = [
    'policy' => [
        'MinimalLength' => [ 'min' => 12 ],
        'ContainsUppercaseLetter' => true,
        'ContainsDigit' => true,
        'RejectCommonPasswords' => true,
    ],
    'forceReset' => false,
];

Also, enable $wgContentHandlerUseDB for content‑type safety, and consider turning on $wgEnableWriteAPI only for trusted bots.

8. Internationalisation & Localization

If your wiki speaks more than one language, you’ll want to play with $wgForceUIMsgAsContentMsg and $wgLanguageCode. A neat trick is to force the UI language based on user preference while still serving content in its original language.

// Keep user interface in user language
$wgForceUIMsgAsContentMsg = false;
$wgExposeLangLinks = true; // show interlanguage links

Remember: each language file adds a few hundred kilobytes to memory, so monitor memory_limit after you enable dozens of languages.

9. Monitoring & Debugging

Even the best‑tuned wiki needs eyes on it. MediaWiki ships with built‑in profiling; just turn it on in LocalSettings.php when you suspect a slowdown.

$wgDebugLogFile = "/var/log/mediawiki/debug.log";
$wgDebugToolbar = true;            // shows a toolbar with timing data
$wgShowExceptionDetails = true;   // useful in dev, never enable in prod

For production, pipe the log to a log‑collector (e.g. Graylog or ELK). If you see “ParserCache: miss” spikes, maybe the $wgParserCacheType fell back to CACHE_NONE after a recent extension update.

10. The “If‑This‑Then‑That” Section

At this point you might be asking: “What if I need a custom setting that isn’t listed?” The answer—use $wgHooks and $wgExtensionFunctions. Hooking early lets you inject configuration before most core code runs.

// Example: force all uploads to be private until reviewed
$wgHooks['UploadComplete'][] = function ( $file ) {
    $file->setPublic( false );
    // later a reviewer can call $file->setPublic( true );
    return true;
};

This little snippet demonstrates the power of the hook system: you can alter core behavior without touching the core itself. Just be mindful of ordering; some extensions register their own hooks that might fire before yours.

Wrapping Up

Advanced MediaWiki configuration isn’t about flipping a switch; it’s about understanding the layered architecture and tuning each layer to match your traffic patterns, security posture, and feature set. The settings above cover the most common pain points: database scaling, caching layers, upload handling, ResourceLoader, background jobs, security, i18n, and observability.

When you return to $wgSitename after a weekend of tweaking, you’ll notice the wiki feels faster, safer, and more responsive—proof that those “advanced” knobs aren’t just for show.

Subscribe to MediaWiki Tips and Tricks

Don’t miss out on the latest articles. Sign up now to get access to the library of members-only articles.
jamie@example.com
Subscribe