new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

bun apis/cron

29 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Bun.cron() in-process scheduling basic usage

Use Bun.cron(schedule, handler) to run a callback on a cron schedule inside the current process. The schedule is a cron expression like '*/5 * * * *' or a predefined nickname like '@hourly'. The handler is called on each fire and may return a Promise. Returns a CronJob synchronously. Throws TypeError if the expression is invalid.

Bun.cron.parse() parse cron expression

Bun.cron.parse(expression, relativeDate?, options?) parses a cron expression and returns the next matching Date in the system's local time zone, or null if no match exists within 8 years. Parameters: expression (string, required) - a 5-field cron expression or predefined nickname; relativeDate (Date | number, optional, defaults to Date.now()) - starting point for search; options (object, optional) with tz field (string, optional) for IANA time-zone name.

Cron expression 5-field syntax

Standard cron format: minute hour day-of-month month day-of-week. Minute: 0–59. Hour: 0–23. Day of month: 1–31. Month: 1–12 or JAN–DEC (case-insensitive). Day of week: 0–7 or SUN–SAT (case-insensitive, both 0 and 7 mean Sunday). Special characters: * (all values), , (list), - (range), / (step).

Cron predefined nicknames

@yearly/@annually = 0 0 1 1 * (once a year, January 1st). @monthly = 0 0 1 * * (once a month, 1st day). @weekly = 0 0 * * 0 (once a week, Sunday). @daily/@midnight = 0 0 * * * (once a day, midnight). @hourly = 0 * * * * (once an hour).

Cron time zone support

Schedules are interpreted in the system's local time zone by default. Override by passing { tz: 'IANA_name' } to Bun.cron.parse() or Bun.cron(). For example, { tz: 'UTC' } or { tz: 'America/New_York' }. OS-level and in-process forms fire at the same wall-clock time.

Cron DST spring-forward behavior

When a schedule lands in the missing hour during spring-forward DST transition, it fires that day shifted forward by the gap. For example, 30 2 * * * runs at 3:30 on the spring-forward day. For multi-minute patterns inside the gap like */15 2 * * *, only the first match fires.

Cron DST fall-back behavior

During fall-back DST transition, a fixed-time schedule in the duplicated hour like 30 1 * * * fires once at the first occurrence. A schedule with * in the minute or hour field like 0 * * * * or * * * * * fires through both occurrences—once per real-time minute, matching crontab on Linux.

Cron day-of-month and day-of-week logic

When both day-of-month and day-of-week are specified (neither is *), the expression matches when either condition is true, following POSIX cron standard. For example, 0 0 15 * FRI fires on the 15th of every month OR every Friday. When only one is specified (the other is *), only that field is used.

Bun.cron() in-process no-overlap guarantee

The next fire time is computed only after the handler—including any returned Promise—settles. If the handler takes 90 seconds and the schedule is * * * * *, the second fire is the first minute boundary after the handler finishes, not 60 seconds after. Invocations never stack.

Bun.cron() in-process error handling

Errors match setTimeout semantics: synchronous throws emit process.on('uncaughtException'); rejected returned Promises emit process.on('unhandledRejection'). Without a listener, the process exits with code 1. With a listener, the job keeps running and retries on the next scheduled time.

CronJob handle properties and methods

CronJob has: job.cron (returns the cron expression string), job.stop() (cancel, handler will not fire again), job.unref() (allow process to exit while scheduled), job.ref() (keep process alive, default). stop(), ref(), and unref() return the job for chaining. CronJob is Disposable: using job = Bun.cron(...) auto-stops at scope exit.

Bun.cron() bun --hot behavior

Under bun --hot, all in-process cron jobs are stopped immediately before module graph re-evaluation. Every Bun.cron() call still in the source re-registers. Editing schedule, handler, or deleting the line entirely all take effect on save without leaking timers.

Bun.cron() fake timers support

In-process cron honors jest.useFakeTimers(). setSystemTime(), advanceTimersByTime(), and runAllTimers() control when it fires, enabling testing scheduled callbacks without waiting on the real clock.

Bun.cron(path, schedule, title) OS-level registration

Register an OS-level cron job: await Bun.cron('./worker.ts', '30 2 * * MON', 'weekly-report'). Parameters: path (string, required) - path to script resolved relative to caller; schedule (string, required) - cron expression or nickname; title (string, required) - unique job identifier using alphanumeric, hyphens, underscores. Re-registering with same title overwrites the existing job in-place.

OS-level cron job scheduled() handler

The registered script must export a default object with a scheduled(controller: Bun.CronController) method. The controller has: controller.cron (the cron expression string), controller.type ('scheduled'), controller.scheduledTime (Date.now() at invocation). The handler can be async; Bun waits for the returned promise to settle before exiting.

Bun.cron() vs in-process vs OS-level comparison

In-process: survives process exit=No, shared state between runs=Yes, platform requirements=None, Windows expression limits=None, returns CronJob. OS-level: survives process exit=Yes, shared state=No (fresh process each time), platform requirements=crontab/launchd/Task Scheduler, Windows expression limits=48-trigger cap, returns Promise<void>.

Linux OS-level cron implementation with crontab

Bun uses crontab to register OS-level jobs. Each job is stored as a line in the user's crontab with a '# bun-cron: <title>' marker comment above it. The crontab entry format: '<schedule> '<bun-path>' run --cron-title=<title> --cron-period='<schedule>' '<script-path>'. View with 'crontab -l'. Logs go to system log: journalctl -u cron or check /var/log/syslog.

macOS OS-level cron implementation with launchd

Bun uses launchd to register OS-level jobs. Each job is installed as a plist file at ~/Library/LaunchAgents/bun.cron.<title>.plist. The plist uses StartCalendarInterval to define the schedule. Complex patterns are expanded into multiple StartCalendarInterval dicts as a Cartesian product. View with 'launchctl list | grep bun.cron'. Logs go to /tmp/bun.cron.<title>.stdout.log and /tmp/bun.cron.<title>.stderr.log.

Windows OS-level cron implementation with Task Scheduler

Bun uses Windows Task Scheduler with CalendarTrigger elements and Repetition patterns. Each job is registered as a scheduled task named 'bun-cron-<title>'. Most cron expressions are fully supported including @daily, @weekly, @monthly, @yearly, ranges, lists, named days/months, and day-of-month patterns. Windows has a 48-trigger limit per task.

Windows cron S4U logon type

Bun registers tasks with S4U (Service-for-User) logon type, which runs jobs as the registering user even when not logged in—matching Linux crontab behavior. No password is stored. TCP/IP networking works normally. The only restriction: S4U tasks cannot access Windows-authenticated network resources like SMB file shares, mapped drives, Kerberos/NTLM services.

Windows cron on headless servers and CI environments

On headless servers and CI where the current user's Security Identifier (SID) cannot be resolved—such as service accounts created by NSSM—Bun.cron() fails with an error. Workaround: run Bun as a regular user account, or create the scheduled task manually with 'schtasks /create /xml <file> /tn <name> /ru SYSTEM /f'.

Windows cron 48-trigger limit examples

Expressions that work: */5 * * * * (1 trigger with Repetition PT5M), */15 * * * * (1 trigger), 0 9 * * MON-FRI (5 triggers, one per weekday), 0,30 9-17 * * * (18 triggers), @daily/@weekly/@monthly/@yearly (1 trigger each). Expressions that fail: */7 * * * * (216 triggers), */8 * * * * (192), */9 * * * * (168), */11 * * * * (144), */13 * * * * (120), */15 * * 6 * (96), 0,30 * 15 * FRI (96).

Windows cron trigger count rules

Minute steps that evenly divide 60 (*/1, */2, */3, */4, */5, */6, */10, */12, */15, */20, */30) use Repetition and work regardless of other fields. Steps that don't divide 60 (*/7, */8, */9, */11, */13, etc.) must expand to individual CalendarTrigger elements; with 24 hours active, the count quickly exceeds 48. Workaround: restrict hour range or use a divisor of 60.

Windows Docker container cron limitation

Bun.cron() OS-level is not supported in Windows Docker containers. The Task Scheduler service is not running in servercore or nanoserver images. Use an in-process scheduler for containerized workloads.

Bun.cron.remove() remove registered cron job

Remove a previously registered OS-level cron job by its title with await Bun.cron.remove('weekly-report'). Works on all platforms. Reverses what Bun.cron() did: on Linux edits crontab, on macOS runs launchctl bootout and deletes plist, on Windows runs schtasks /delete. Removing a job that doesn't exist resolves without error.

Bun.cron.parse() chaining to get sequence of times

Call parse() repeatedly with the result to get a sequence of upcoming times. Example: let cursor = Date.now(); for (let i = 0; i < 3; i++) { cursor = Bun.cron.parse('0 * * * *', cursor)!; console.log(cursor.toLocaleString()); } gets the next three top-of-hour boundaries.

Bun.cron() in-process error handling example

Example showing error handling: process.on('unhandledRejection', err => log.error('cron failed:', err)); Bun.cron('* * * * *', async () => { await mightThrow(); }); Errors are logged and the job retries on the next minute without stopping.

Bun.cron() CronJob Disposable usage

Example using CronJob as Disposable: using job = Bun.cron('0 * * * *', () => {}); automatically stops the job at scope exit. Properties: job.cron returns '0 * * * *', job.stop() cancels it, job.unref() allows process exit, job.ref() keeps process alive.

OS-level cron scheduled() handler example

Example worker.ts: export default { scheduled(controller: Bun.CronController) { console.log(controller.cron); // '30 2 * * 1' console.log(controller.type); // 'scheduled' console.log(controller.scheduledTime); // 1737340201847 (Date.now() at invocation) } };

Give your agent this brain