Standalone cron jobs run any shell command on a schedule — without a managed process. Unlike --cron restart schedules (which recycle a running app), cron jobs are first-class citizens of the daemon: they are persisted in ~/.pboss/cron.json, survive daemon restarts and reboots, and log every run to ~/.pboss/logs/cron/<name>.log.
pboss cron run#
Schedule a command using human-friendly syntax:
pboss cron run everyday@9:11 "bun /srv/backup.ts"
pboss cron run every-sunday@10:10 "sh /srv/cleanup.sh" --name cleanup
pboss cron run on-date@24-10-2026-23:10 "node migrate.js"
The schedule grammar#
Times use the 24-hour clock; dates are day-month-year (24-10-2026 = October 24, 2026).
| Schedule | Meaning |
|---|---|
everyday | every day at 00:00 |
everyday@10 | every day at 10:00 |
everyday@9:11 | every day at 09:11 |
everyday@24:30 | every day at 00:30 (24:xx = the next day) |
everysecond | every second |
every-15-seconds | every 15 seconds (1–59) |
everyhour / everyhour@30 | every hour at :00 / :30 |
everyminute | every minute |
everyweek / everyweek@10:10 | every Sunday |
every-sunday / everyMonday@10:10 / onSunday@23:10 | weekly on a weekday (full or 3-letter names) |
everymonth / everymonth@10:10 | every 1st |
every-15th / every-15@10:10 | every 15th of the month |
every-6-hours / every-6-hours@30 | every 6 hours |
every-30-minutes | every 30 minutes |
every-2-days / every-2-days@8 | every 2nd day |
today@23:10 | once, today (must be in the future) |
tomorrow@8:00 | once, tomorrow |
on-date@24-10-2026 | once, 24 Oct 2026 at 00:00 |
on-date@24-10-2026-23:10 | once, 24 Oct 2026 at 23:10 |
"*/5 * * * *" | raw 5-field cron expression (escape hatch) |
"*/10 * * * * *" | raw 6-field cron — first field is seconds |
Notes:
- Hour 24 means the following day:
24:30is00:30the next day. - Dates are calendar-validated (leap years included) —
on-date@31-02-2026is rejected with a clear error. - Keywords tolerate hyphens, underscores and camelCase:
on-date@,onDate@,on_date@are the same word. - Next-run times come from the cron-parser library, which also validates raw expressions — 6-field ones get a seconds field.
- Jobs missed while the machine or daemon was down are skipped (like classic cron); recurring jobs reschedule to their next future occurrence.
- A past time for
today@…/on-date@…is rejected with a suggestion, not scheduled to never fire.
Options for cron run:
--name, -n <name>— job name (default: derived from the command)--cwd <path>— working directory for the command (default: current directory)
pboss cron list#
List all scheduled jobs with their next run, run counts, and last exit status:
pboss cron list
┌────┬─────────┬─────────────┬──────────────────┬───────────────────────────┬──────┬──────┬──────────┐
│ id │ name │ schedule │ command │ next run │ runs │ last │ status │
├────┼─────────┼─────────────┼──────────────────┼───────────────────────────┼──────┼──────┼──────────┤
│ 1 │ backup │ everyday@9 │ bun backup.ts │ 2026-09-07 09:00 Mon │ 14 │ ✓ │ ● online │
│ 2 │ cleanup │ every-sunday│ sh cleanup.sh │ 2026-09-13 00:00 Sun │ 3 │ ✓ │ ● online │
│ 3 │ migrate │ on-date@24-10-2026-23:10 │ node migrate.js │ 2026-10-24 23:10 │ 0 │ - │ ● done │
└────┴─────────┴─────────────┴──────────────────┴───────────────────────────┴──────┴──────┴──────────┘
One-shot jobs stay in the list with a done status after firing so you can inspect their exit code; remove them when you no longer need the record.
pboss cron next#
Preview upcoming runs without waiting for them:
pboss cron next backup --count 5
pboss cron trigger#
Run a job immediately, without waiting for its schedule (the schedule itself is unaffected):
pboss cron trigger backup
pboss cron remove#
Remove a job by id or name:
pboss cron remove backup
pboss cron remove 3
Cron jobs in ecosystem files#
Declare cron jobs alongside your apps in pboss.config.ts / ecosystem.config.{ts,json}. Starting the file registers the jobs; re-running it updates changed schedules in place (jobs are matched by name):
export default {
crons: [
{
name: "backup",
schedule: "everyday@2:00",
command: "bun /srv/backup.ts",
},
{
name: "report",
schedule: "every-15th@10:10",
command: "sh /srv/report.sh",
},
{
// paused until you enable it later
name: "maintenance",
schedule: "every-sunday@5:00",
command: "sh /srv/maintenance.sh",
enabled: false,
},
],
apps: [
/* … */
],
};
| Field | Type | Description |
|---|---|---|
name | string? | Job name — defaults to a slug of the command. Used to match/update jobs on re-start. |
schedule | string | Friendly schedule or raw cron expression (same grammar as pboss cron run). |
command | string | Shell command to run. |
cwd | string? | Working directory — defaults to the ecosystem file’s directory. |
enabled | boolean? | Set false to keep the job defined but paused (default true). |
Programmatic API#
import { pboss } from "pboss";
const job = await pboss.cronAdd("everyday@9:11", "bun backup.ts", { name: "backup" });
for (const j of await pboss.cronJobs()) {
console.log(`${j.name} — ${j.description} (runs: ${j.runCount})`);
}
await pboss.cronTrigger("backup"); // run now
await pboss.cronRemove("backup"); // remove
How execution works#
Jobs run through the system shell (/bin/sh -c on Unix, cmd /c on Windows), so pipes, redirects, and compound commands work:
pboss cron run everyday@3 "bun report.ts | mail -s 'daily report' ops@example.com"
Every run appends a header (job name, schedule, working directory), the command’s combined output, and a footer with the exit code and duration to ~/.pboss/logs/cron/<name>.log. The daemon’s scheduler sleeps until the earliest next run with a periodic watchdog rescan, so firing is precise to the second and robust against clock adjustments.