# The scheduler

> Manage recurring cron jobs — scheduled backups, cleanup sweeps, and your own — from the admin.

_Updated: 2026-07-15_

Recurring work in Railbase runs on **persisted cron schedules** (the `_cron`
collection). The **Settings → Scheduler** screen (`/_/settings/scheduler`) is the
admin surface for all of them — the housekeeping jobs the core ships, plus any you
add. It's the UI counterpart to the `railbase cron` CLI, and it's where scheduled
**backups** live now that they've moved off the Backups screen.

## What's on the screen

The Scheduler lists **every** cron row on your instance:

- **Your schedules** — anything you add (a nightly report, a custom cleanup, a
  scheduled backup).
- **System builtins** — the core's housekeeping jobs (`cleanup_sessions`,
  `cleanup_jobs`, `audit_seal`, `audit_archive`, and the like). These are visually
  flagged and **protected**: you can enable, disable, or run them now, but you
  can't delete them or change their `kind`.

Each row shows its name, cron expression, target job **kind**, and enabled state.

## Add or change a schedule

The **New schedule** drawer takes a **cron expression** and a job **kind**. It
defaults to `kind = scheduled_backup`, since "schedule a backup" is the primary
flow — a backup schedule also takes a small payload:

- **`retention_days`** — how many past archives to keep (older ones are swept).
- **`out_dir`** — where the archives are written (defaults to `<data-dir>/backups`).

Pick a different `kind` to schedule cleanup or another registered handler instead.
Editing an existing schedule reopens the same drawer.

## Per-row actions

- **Enable / disable** — pause a schedule without deleting it.
- **Run now** — fire the job immediately, off-schedule, to test it.
- **Delete** — remove one of your schedules (builtins can't be deleted).

## From the CLI

The same schedules are managed with `railbase cron` (which, like every command
that opens the vault, needs the server **stopped**):

```bash
railbase cron upsert nightly-report "0 3 * * *" report.generate
railbase cron list
railbase cron run-now nightly-report
railbase cron enable nightly-report
railbase cron disable nightly-report
```

> [!NOTE]
> These are the **durable**, operator-managed schedules. A cron added from a
> JavaScript hook with `$app.cronAdd(...)` is a different thing — it's in-memory
> and per-process, re-registered from your hook files on each reload, and does
> **not** appear in the `_cron` table or on this screen. See
> [Jobs & cron](jobs-and-cron).

See also [Backups & restore](backups-and-restore) for the backup side and
[Operating from the admin](operations) for the other day-two screens.
