How DokuWiki actually runs background work

DokuWiki does not ship with a queue worker or a resident daemon the way some larger platforms do. Instead, almost everything that looks like a scheduled task is triggered opportunistically during normal page requests. When a visitor loads or saves a page, DokuWiki checks whether certain maintenance work is due and runs it inline: rebuilding the full-text search index for the edited page, updating the .changes metadata, expiring stale cache entries, and regenerating the XML sitemap once its lifetime has passed. This request-driven model works well on busy sites because there is always a steady stream of requests to piggyback on.

The trouble appears on quiet wikis, internal documentation sites, or pages that are served almost entirely from cache. If nobody triggers a full request against the pages that need work, the work never happens. A sitemap can go weeks without regenerating, subscription emails may lag, and the search index can drift out of sync with the actual page content after bulk edits or imports. On shared hosting this is compounded by aggressive LiteSpeed caching, which can serve pages without ever reaching PHP, meaning the very hook DokuWiki depends on is bypassed.

There are three DokuWiki subsystems worth understanding here. First, the search indexer, exposed at lib/exe/indexer.php, which processes the index for a page and also runs the sitemap and digest routines. Second, the XML sitemap, controlled by the sitemap config option (interval in seconds) and written to your data directory. Third, subscription notifications, which send email digests to users who have subscribed to a page or namespace. All three are normally kicked off by a tiny JavaScript beacon that the browser fires after a page loads, calling indexer.php in the background. If JavaScript is blocked, the page is cached, or the site sees little traffic, that beacon never fires and the queue stalls.

Triggering the indexer reliably with cron

The dependable fix on shared hosting is to stop relying on visitor requests and instead call the indexer endpoint on a schedule. cPanel and DirectAdmin both expose a Cron Jobs area at the account level, and neither requires root. In cPanel Jupiter, open Advanced → Cron Jobs. In DirectAdmin Evolution, open Advanced Features → Cron Jobs. You do not need sudo, systemctl, or any shell privilege beyond what the panel provides.

The cleanest approach is to hit the indexer endpoint over HTTP so it runs exactly as a browser would, honoring your DokuWiki configuration and authentication context. Most managed hosts include curl or wget in the cron environment. A command that runs every ten minutes looks like this:

*/10 * * * * curl -s "https://wiki.example.com/lib/exe/indexer.php?debug=0" > /dev/null 2>&1

If curl is unavailable, use wget instead:

*/10 * * * * wget -q -O /dev/null "https://wiki.example.com/lib/exe/indexer.php?debug=0"

The endpoint expects a page ID via the id parameter when it is invoked by the browser beacon, but calling it without one still runs the periodic tasks (sitemap, digest, and cleanup) because those checks are time-based rather than page-based. If you want to force indexing of a specific page, you can add &id=start or another page name, though for routine maintenance the bare call is sufficient.

One important detail on LiteSpeed servers: a cron HTTP request may itself be served from the cache and never reach PHP, which defeats the purpose. Add a cache-busting query parameter so each call is unique, and consider excluding the indexer path from cache in your .htaccess:

# .htaccess in the DokuWiki document root
<IfModule LiteSpeed>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/lib/exe/indexer\.php
RewriteRule .* - [E=Cache-Control:no-cache]
</IfModule>

Then append a timestamp to the cron URL, for example ?debug=0&t=$(date +\%s), escaping the percent sign because cron treats % as a newline. If your host restricts outbound HTTP from cron, you can instead invoke the CLI indexer that ships with modern DokuWiki releases at bin/indexer.php, using the PHP binary provided by CloudLinux PHP Selector. Find the exact path under Select PHP Version or use the alias your host documents, then schedule:

*/15 * * * * /usr/local/bin/ea-php82 /home/USERNAME/wiki.example.com/bin/indexer.php -q > /dev/null 2>&1

Replace the PHP path and account path with the values shown in your panel. The -q flag suppresses output so cron does not email you on every run.

Sitemaps, subscription emails, and where to change settings

Both the sitemap and notification digests hang off the same indexer trigger, so once cron is calling the endpoint they will run on schedule. What you control separately is timing and content, and all of it lives in DokuWiki's admin area rather than any server config. Log in as a superuser and open Admin → Configuration Settings.

For the sitemap, set Advanced → sitemap to the number of days between regenerations (a value of 1 means daily; 0 disables it). The generated file is written to your data directory and served through doku.php, so you can verify it by requesting https://wiki.example.com/doku.php?do=sitemap. If the file is stale, confirm the data directory is writable by the PHP user; you can check permissions in the cPanel or DirectAdmin File Manager and set the folder to 0755 if needed. Do not place the wiki's data/ directory inside your web root without the shipped .htaccess deny rules, since it holds page sources and metadata.

For notifications, DokuWiki sends mail through PHP's mail function by default, which on shared hosting routes through the local Exim or the host's outbound relay. Set your sender address under Subscribers-related options and confirm mailfrom uses a domain hosted on the account so SPF and DKIM align. If digests arrive late or not at all, the cause is almost always that the indexer is not being triggered, or the mail is failing silently. Check data/cache and the DokuWiki log, and inspect the account's mail delivery reports in cPanel's Email → Track Delivery or DirectAdmin's E-Mail Manager to see whether messages are leaving the server.

Troubleshooting stalled tasks with account tools

When background work is not happening, work through the layers you can actually see from an unprivileged account. Start with the local error_log: DokuWiki writes PHP notices and fatal errors to a file in the document root or to the path your PHP handler defines. In File Manager, look for error_log beside doku.php. A recurring "failed to open stream" or "Permission denied" against a path under data/ points to ownership or permission drift, common after restoring a backup.

If cron runs but nothing changes, add temporary logging by removing > /dev/null from the cron line so the panel emails you the raw output; an HTTP redirect or a WAF challenge page in that output tells you the request never reached PHP. A 403 usually means a security rule is blocking lib/exe/ access, which you can relax with a scoped allow rule in .htaccess. If you see PHP memory or timeout errors during large index rebuilds after an import, raise limits through a .user.ini in the document root rather than touching any server file:

; .user.ini in the DokuWiki root
memory_limit = 256M
max_execution_time = 120

Changes to .user.ini take effect after the PHP FPM user cache TTL expires, typically a few minutes, or immediately if you toggle the PHP version in the Selector. For a one-off full reindex after importing many pages, use the CLI command bin/indexer.php -c to clear and rebuild, which is far more efficient than waiting for the incremental per-page beacon. If your wiki is heavily cached and you also run other wiki software, the same caching discipline applies broadly; our companion guide on caching and LiteSpeed tuning for MediaWiki covers the cache-exclusion patterns in more depth. With cron reliably firing the indexer and the data directory writable, DokuWiki's sitemap, search index, and subscription digests stay current regardless of how much or how little traffic the site receives.