Back to Article List

Nextcloud cron and background jobs done right

Nextcloud cron and background jobs done right - Nextcloud cron and background jobs done right

Last background job execution ran 4 hours ago. Something seems wrong. If your admin overview shows that line, background jobs on your instance are stalled, and this is a five minute fix, not a fifteen minute one. The fix is almost always the same: stop relying on AJAX mode and give the system a real cron job. I'll cover the crontab line, the one PHP gotcha that makes it fail silently and the Docker variants.

What are Nextcloud background jobs

A surprising amount of Nextcloud runs outside the request cycle. Background jobs expire the trash bin and old file versions, scan for changed files, send activity and share notification mails and run whatever the installed apps queue up (the mail app fetches on a job, preview pre-generation runs on a job, calendar reminders go out on a job). None of it is optional in practice. When jobs stop, the instance keeps working in the sense that files sync, while everything time-based quietly stops happening underneath.

The heavier housekeeping jobs also respect a maintenance window, so they can be herded into the small hours instead of competing with your users at 14:00. Setting the window's start hour is one command:

sudo -u www-data php /var/www/nextcloud/occ config:system:set maintenance_window_start --type=integer --value=1

The value is an hour in UTC, so 1 means the expensive jobs begin at 01:00 UTC. On my instance the difference is visible in the morning load graphs, a fat spike at night and a flat line during the day, exactly where I want it. The window only gates jobs flagged as time-insensitive; anything user-facing, reminders and notifications included, still runs on the normal five minute cycle.

AJAX, webcron and cron: Pick cron every time...

Nextcloud offers three execution modes, described in the background jobs configuration docs. AJAX is the default and it's a trap on small instances: it piggybacks one job onto page visits, so jobs only run while somebody has the web UI open in a browser. A family instance where everyone uses the mobile and desktop clients can go days without a single UI visit. Days without jobs. Webcron has an external service hit cron.php over HTTP on a schedule, which works and has one legitimate niche: shared hosting where you can't touch the crontab. On a server you administer, it's an outside dependency doing badly what one crontab line does well. System cron is what I run everywhere and what the docs themselves call the preferred method, since it executes on schedule regardless of who's logged in and runs with CLI limits instead of web request timeouts, so a long file scan can actually finish.

The mode switch lives in Administration settings under Basic settings, or from the shell:

sudo -u www-data php /var/www/nextcloud/occ background:cron

There are matching background:ajax and background:webcron commands, and the general shape of running these is in the occ command documentation.

The crontab line for www-data

The job has to run as the same user that owns the files, which on the stack from my Nextcloud install guide for Ubuntu is www-data. Edit that user's crontab, not root's:

sudo crontab -u www-data -e

One line does it:

*/5 * * * * php -f /var/www/nextcloud/cron.php

Adjust the path if your installation lives elsewhere. Every five minutes is the standard interval; the runner picks jobs off a queue, so a tighter schedule buys nothing. Confirm the line took with sudo crontab -l -u www-data, then wait five minutes.

Two small refinements from experience. Cron runs with a minimal PATH, so if your PHP lives somewhere unusual, write /usr/bin/php in full (on Ubuntu the plain php resolves fine). And while debugging, temporarily redirect the output so failures stop being invisible:

*/5 * * * * php -f /var/www/nextcloud/cron.php >> /var/log/nextcloud-cron.log 2>&1

A healthy run writes nothing, which makes the log file a cheap dead-man's switch: if it starts growing, something inside cron.php is complaining. I drop the redirect again once things are stable, otherwise logrotate gains one more file to babysit.

apc.enable_cli, the silent killer

Here's the part that generates most of the "nextcloud cron jobs not running" search traffic. If config.php sets 'memcache.local' to APCu (and it should), cron.php will fail from the command line while the website works perfectly. PHP disables APCu for CLI by default, so the cron run aborts with an error about \OC\Memcache\APCu not being available for local caching, and since cron output goes nowhere by default, nothing tells you. The admin page just keeps counting hours since the last run.

The fix is one line for the CLI configuration. On PHP 8.5:

echo 'apc.enable_cli=1' | sudo tee -a /etc/php/8.5/mods-available/apcu.ini

Then run the job once by hand and check the exit code:

sudo -u www-data php -f /var/www/nextcloud/cron.php; echo $?

Silence followed by 0 means it worked. I've hit this on two separate servers over the years, and both times the instance had been coasting without jobs for weeks before the admin page tipped me off. A quick manual run after any PHP upgrade is cheap insurance, since a new PHP version brings a new apcu.ini that may not carry the flag.

Cron in Docker and AIO

Containers don't ship a crond next to Apache, so compose users pick one of two patterns. Either a host crontab entry that execs into the container:

*/5 * * * * docker exec -u www-data nextcloud-app-1 php cron.php

or, cleaner, a dedicated cron container running the same image with its entrypoint set to /cron.sh, sharing the app volume. The host crontab version depends on a container name that changes if you rename the project directory, and nothing warns you when it does; the cron container restarts with the stack, survives renames and shows up in docker compose ps where you'll actually notice it dying. I use the second, and the compose file in my Nextcloud Docker Compose guide includes it as a fourth service. The apc.enable_cli problem doesn't exist here, the official image ships with the flag handled. AIO users can skip this article's setup entirely, the master container schedules jobs itself, which is one of the honest arguments for AIO on a dedicated box.

Verifying that background jobs run

Back in Basic settings, the line under the mode selector should read "Last job ran" followed by something under five minutes, with a green check. Give it one full interval before concluding anything; I've watched people re-edit a perfectly good crontab because they checked after ninety seconds. For a deeper look, occ background-job:list prints the queue as a table (job ID, class, last checked, last run), and a job whose last run sits days behind the others is your misbehaving app. Failures land in nextcloud.log, which I've mapped out in where to find the Nextcloud logs; grep it for the job class name and you usually have the stack trace that explains everything.

What breaks when cron is dead

It's worth recognizing the symptoms, because they look unrelated until you check the overview page. The trash bin and file versions stop expiring, so disk usage climbs for no visible reason (on my instance, versions expiry reclaims a couple of gigabytes a month, and 400 GB of photos generates plenty of versions). Activity emails and share notifications arrive late or never. Apps that poll external services stop polling. New warnings pile up on the admin page. If your instance feels stale rather than broken, check the "Last job ran" line first; a dead cron also drags down the numbers I chase in the Nextcloud performance tuning guide, because cleanup that never runs turns into bloat the database carries on every query.

One more failure shape worth knowing: cron that runs but never finishes. A single enormous job, say a first file scan over hundreds of gigabytes, can hold the queue while the "Last job ran" counter stays suspiciously fresh, since the runner is technically alive. If the overview looks healthy while trash expiry clearly isn't happening, check for a php process that's been running for hours under www-data. Killing it and letting the next five minute run pick up the pieces has fixed that for me both times it happened.

Five minutes: one crontab line, one apcu.ini flag, one green check. That warning at the top of this page shouldn't survive your coffee.

Your idea deserves better hosting

24/7 support 30-day money-back guarantee Cancel anytime
Billing Cycle

VPS.S1

£4.43 Save  17 %
£3.69 Monthly
  • 2 vCPU AMD EPYC
  • 2 GB RAMMEMORY
  • 30 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

VPS.S3

£11.06 Save  33 %
£7.37 Monthly
  • 4 vCPU AMD EPYC
  • 6 GB RAMMEMORY
  • 70 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

EPYC VPS.P1

£6.63 Save  22 %
£5.16 Monthly
  • 2 vCPU AMD EPYC
  • 4 GB RAMMEMORY
  • 40 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P2

£12.53 Save  24 %
£9.58 Monthly
  • 2 vCPU AMD EPYC
  • 8 GB RAMMEMORY
  • 80 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P4

£22.12 Save  23 %
£16.96 Monthly
  • 4 vCPU AMD EPYC
  • 16 GB RAMMEMORY
  • 160 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P5

£29.54 Save  25 %
£22.16 Monthly
  • 8 vCPU AMD EPYC
  • 16 GB RAMMEMORY
  • 180 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P6

£44.24 Save  25 %
£33.18 Monthly
  • 8 vCPU AMD EPYC
  • 32 GB RAMMEMORY
  • 200 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

EPYC VPS.P7

£51.70 Save  29 %
£36.93 Monthly
  • 16 vCPU AMD EPYC
  • 32 GB RAMMEMORY
  • 240 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G2

£18.46 Save  20 %
£14.77 Monthly
  • 2 vCPUAMD EPYC Genoa 4th generation 9xx4 with 3.25 GHz or similar, on Zen 4 architecture. AMD EPYC G4
  • 4 GB DDR5MEMORY
  • 50 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G4

£33.24 Save  22 %
£25.85 Monthly
  • 4 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 8 GB DDR5MEMORY
  • 100 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G6

£66.48 Save  22 %
£51.70 Monthly
  • 8 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 16 GB DDR5MEMORY
  • 200 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

Genoa VPS.G7

£118.19 Save  22 %
£92.34 Monthly
  • 8 vCPUAMD EPYC processor with dedicated vCPU cores, on enterprise server hardware. AMD EPYC G4
  • 32 GB DDR5MEMORY
  • 250 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included
  • Free auto backupsIncludes one backup slot you can set to run daily, weekly or monthly.

AMD Ryzen VPS.R1

£12.55 Save  18 %
£10.34 Monthly
  • 1 dedicated CPU AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 4 GB DDR5MEMORY
  • 50 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

AMD Ryzen VPS.R2

£22.15 Save  17 %
£18.46 Monthly
  • 2 dedicated CPUs AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 8 GB DDR5MEMORY
  • 100 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

AMD Ryzen VPS.R4

£81.25 Save  18 %
£66.48 Monthly
  • 8 dedicated CPUs AMD Ryzen 9 7950X with 4.5 GHz or similar, on Zen 4 architecture. vCPU
  • 32 GB DDR5MEMORY
  • 400 GB NVMeSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6 included IPv6 support is currently unavailable in France, Finland or the Netherlands.
  • Auto backup included

Frequent questions

Do background jobs run while maintenance mode is on?

No. With 'maintenance' =undefinedgt; true the cron run exits early, and jobs resume on the next interval after you switch maintenance mode off. A long maintenance window followed by a burst of catch-up jobs is normal, so don't read the first slow minutes after an upgrade as a cron problem.

GPU products are in high demand at the moment. Fill the form to get notified as soon as your preferred GPU server is back in stock.