Configuration & operations
Koha cron jobs: which ones matter, and what breaks silently without each
A package install schedules about fifteen jobs. This is what each one does, when it runs, and the exact symptom a library sees when it stops.
Updated 2026-08-09 · Tested against Koha 26.05
On a Debian/Ubuntu package install, the koha-common package installs the schedule for you in three files: /etc/cron.d/koha-common, /etc/cron.hourly/koha-common and /etc/cron.daily/koha-common. Nothing needs to be added to a user crontab. Almost every "Koha stopped doing X by itself" report is one of those jobs not running.
Why this is the hardest part of Koha to notice
Step 1See what is actually scheduled
$ cat /etc/cron.d/koha-common$ cat /etc/cron.hourly/koha-common$ cat /etc/cron.daily/koha-commonEvery line is wrapped in koha-foreach, which loops the instances on the box and runs the job once per instance. The filters matter: --enabled skips disabled instances, and --email skips instances that have not had koha-email-enable run on them.
Every 15 minutes — the message queue
One job, and the one that generates the most support requests.
*/15 * * * * root koha-foreach --chdir --enabled --email \ /usr/share/koha/bin/cronjobs/process_message_queue.pl| Job | What breaks without it |
|---|---|
| <code>process_message_queue.pl</code> | Nothing is delivered. Notices, holds-ready messages and password resets are generated correctly and sit in message_queue at pending forever. See configuring SMTP in Koha. |
Hourly
| Job | What breaks without it |
|---|---|
| <code>holds/build_holds_queue.pl</code> | The holds pull list stops updating. Staff pick from a stale list, so items already collected stay on it and newly placed holds never appear. |
| <code>automatic_checkin.pl</code> | Item types configured to check themselves in automatically stay on loan, and the patron keeps accruing overdue days on an item they returned. |
Daily — the long list
These run once a night, in the order below, through /etc/cron.daily/koha-common.
| Job | What breaks without it |
|---|---|
| <code>koha-run-backups --days 2</code> | No nightly database dump in /var/spool/koha. You discover this on the day you need it. See backing up Koha. |
| <code>fines.pl</code> | Fines never accrue. Overdue items show as overdue but the patron owes nothing, and circulation rules that block on a fine threshold never trigger. The single most consequential job on the list. |
| <code>overdue_notices.pl -t</code> | No overdue notices are generated at all — nothing reaches the queue, so this is invisible from the SMTP side. |
| <code>advance_notices.pl -c</code> | No "due soon" or "item due" reminders. Patrons only hear from you once they are already late. |
| <code>automatic_renewals.pl -c</code> | Auto-renew loans are not renewed and quietly go overdue, with fines, on items the patron was told would renew themselves. |
| <code>membership_expiry.pl -c</code> | No expiry warnings. Patrons find out their card lapsed at the desk. |
| <code>holds/cancel_expired_holds.pl</code> | Expired holds stay in the queue, blocking the item for the next patron in line. |
| <code>holds/auto_unsuspend_holds.pl</code> | Holds suspended until a date stay suspended past it, so the patron never reaches the front of the queue. |
| <code>serialsUpdate.pl -c</code> | Serial issues stay "expected" after their date instead of moving to late, so claiming a missing issue never surfaces. |
| <code>recalls/expire_recalls.pl</code>, <code>recalls/overdue_recalls.pl</code> | Recalls never expire or escalate; an item stays flagged as recalled after the requester has lost interest. |
| <code>cleanup_database.pl</code> | Sessions, the zebra queue, temporary uploads and unverified self-registrations accumulate. Slow growth, then a full disk. |
| <code>merge_authorities.pl -b</code> | An edited authority record does not propagate to the bibliographic records using it, so headings disagree across the catalog. |
| <code>anonymize_last_borrowers.pl</code> | Old borrower links on items are retained past your privacy policy. A compliance problem rather than a functional one, and none the less real. |
| <code>plugins_nightly.pl</code> | Installed plugins never run their scheduled work — what that costs depends entirely on which plugins you use. |
Step 2Check they are actually running
The schedule existing is not evidence it ran. Confirm cron is alive and look for the jobs in its log:
$ systemctl is-active cron$ grep koha /var/log/syslog | tail -20A quicker functional check is to look for the thing the job produces. Fines: has accountlines gained rows since yesterday? Backups: is there a dump from last night?
$ ls -lh /var/spool/koha/library/$ sudo koha-mysql library -e "SELECT MAX(date) FROM accountlines;"Step 3Run one by hand
Any job can be run on demand, which is how you both test it and catch up after an outage. Always run it as the instance, through koha-foreach or koha-shell, so it picks up that instance's configuration:
$ sudo koha-foreach --chdir --enabled \ /usr/share/koha/bin/cronjobs/fines.pl -vCatching up is not always harmless
fines.pl is safe to re-run — it calculates from the due date rather than adding a day's worth each time. overdue_notices.pl is not the same: running it repeatedly can queue duplicate notices to the same patron. Test on a copy before catching up a long gap on a live system.Why so much of Koha lives outside the web interface
Everything on this list is work that has to happen whether or not anyone is logged in. A fine accrues because a day passed, not because a librarian opened a screen. Koha models that honestly: the web interface is for people, and time-driven work is a scheduled job.
The trade is that a large part of what a library thinks of as "Koha behaviour" has no screen to notice missing. That is why a Koha server is not finished when the install completes — it is finished when someone has confirmed the schedule runs and knows where to look when it stops.
Related: backing up Koha with koha-dump and rebuilding the Zebra index, both of which are scheduled work with the same failure mode.
Would rather not do this yourself? We do it as a service — and if you would rather it were already done, it is on Koha Cloud before you log in.
Related
More on configuration & operations
Answers to the questions that usually arrive with this one.
Koha internal server error: finding the line that caused it
A 500 page is Koha telling you nothing on purpose. The real message is in that instance's error log — here is which file to read, and the two causes that produce most of them.
Rebuilding the Zebra index when Koha search results go stale
A record you can open by its number but cannot find by searching means the index is behind, not that the record is missing. Here is how to rebuild it properly.
Backing up Koha with koha-dump — and restoring it
A package install already backs itself up nightly, keeps two days, and writes to a disk that dies with the server. Here is how to check it, and how to restore.
Using a Gmail account as Koha’s SMTP server
Gmail works as Koha’s mail server, but only with an app password and two-step verification on. Here are the exact settings, and the limits worth knowing before you rely on it.

