Recurring: cron(...)
Declare a cron in your manifest. It fires a function every time the schedule matches (the scheduler checks once a minute).
app.ts
functions/: a normal query, mutation, or action:
functions/hourlyRollup.ts
Make cron functions
internal: true. A cron function is also a regular function, so without internal: true, it is reachable at /api/fn/<name>. Marking it internal means only the scheduler (and ctx.runMutation) can invoke it.ctx.db.* calls run server-side and are not subject to entity policies (those gate client sync, not trusted server code), so a maintenance cron reads and writes its entities directly.
Elevate only in two cases, and always with an audit reason:
reason is mandatory. Every elevation is logged, so an operator can audit who elevated and why. Pylon never grants admin to a cron implicitly.
Schedule format. Standard 5-field cron: minute hour day-of-month month day-of-week. A schedule that does not parse, or a function name that is not registered, is logged loudly at boot and skipped. A typo fails visibly in pylon dev instead of silently never running.
Durability. Cron jobs are backed by a persistent job store. A fire that is in flight survives a restart, and the schedule resumes after a redeploy. Postgres stores the queue in the application database. SQLite stores it in a local sidecar database.
On Postgres, all replicas use one shared queue. Workers use row locks and short leases to claim jobs. Another replica can recover a job after its lease expires. One elected cron scheduler adds each matching cron to the shared queue once per tick. During a rolling release, each replica claims only functions that exist in that release.
SQLite jobs stay on one machine. Do not run one SQLite database on multiple replicas.
One-shot: ctx.scheduler
To run something later (not on a repeating schedule), schedule it from inside a mutation or action:
args you pass are delivered verbatim. Like crons, these scheduled calls are durable across restarts.
When a Postgres mutation calls runAfter or runAt, Pylon commits the scheduled job in the same database transaction as the mutation writes. A rollback removes both the writes and the job. Scheduling from an action cannot share a transaction with its external work.