Scheduler vs Cron¶
Verified status as of March 28, 2026. Runtime note: FastFN auto-installs function-local dependencies from
requirements.txt/package.json; host runtimes are required infastfn dev --native, whilefastfn devdepends on a running Docker daemon. FastFN has a built-in scheduler that can auto-invoke functions inside the gateway process. “Cron” is the general concept of time-based scheduling (often implemented by an external service/process).
TL;DR¶
- FastFN Scheduler: per-function config in
fn.config.json, supports interval (every_seconds) and cron (cron+timezone), plus optional retry/backoff. - Cron systems: typically support richer timezone rules (IANA names), job history/management, and running arbitrary commands (not just HTTP/function calls).
Run “Every X Minutes”¶
Use every_seconds:
{
"schedule": {
"enabled": true,
"every_seconds": 300,
"method": "GET",
"query": { "action": "inc" }
}
}
Rule of thumb:
X minutes=every_seconds = X * 60
Run “At 9am” (Cron + Timezone)¶
FastFN supports 5-field and 6-field cron expressions, common macros, and a limited timezone:
UTC(orZ)local- fixed offsets like
-05:00,+02:00,-0500,+0200 - macros such as
@hourly,@daily,@midnight,@weekly,@monthly,@yearly,@annually
Example (daily at 09:00 UTC):
Example (daily at 09:00 with a fixed offset):
Retry/Backoff (Built-In)¶
Enable retries for transient failures (429/503/5xx):
Observability¶
- API snapshot:
GET /_fn/schedules - Console view:
/console/scheduler - Pending retries appear as
retry_dueandretry_attemptin the scheduler snapshot.
Persistence Between Restarts¶
FastFN persists scheduler state (last/next/status/errors, plus pending retries) to a local file under your functions root:
- default:
<FN_FUNCTIONS_ROOT>/.fastfn/scheduler-state.json
Controls:
FN_SCHEDULER_PERSIST_ENABLED=0disables state persistence.FN_SCHEDULER_PERSIST_INTERVALcontrols how often state is flushed (seconds).FN_SCHEDULER_STATE_PATHoverrides the state file path.
Checklist¶
- [x] “Call a function every X minutes”:
every_seconds - [x] Cron expressions + timezone:
cron+timezone - [x] Built-in retry/backoff:
schedule.retry - [x] Persist scheduler state between restarts:
.fastfn/scheduler-state.json - [x] Inspect last/next/last_status/last_error:
/_fn/schedules+ Console
Known Limits (Current)¶
- No full IANA timezone names like
America/New_York(onlyUTC,local, fixed offsets). - Not a distributed job queue (no cross-node coordination, no exactly-once guarantees).
- Cron matching uses standard day/month aliases and Vixie-style
ORsemantics for day-of-month vs day-of-week, which is worth remembering when porting schedules from other systems.
Problem¶
This answers a common operational question: should a function be triggered by FastFN itself, by a cron-like external service, or by a job runner outside the app?
Use the built-in scheduler when you want:
- the trigger definition to live next to the function in
fn.config.json - retries and last-run state to stay visible in
/_fn/schedules - the invocation to pass through the same gateway/runtime policy as normal traffic
Use an external scheduler when you need richer timezone support, fleet-wide coordination, or non-HTTP command execution.
Mental Model¶
Treat a FastFN schedule as a synthetic HTTP invocation owned by the gateway:
every_secondsis best for simple polling or heartbeat-style jobscronis best for wall-clock schedules like "every day at 09:00 UTC"method,query,headers,body, andcontextbecome the scheduled request payloadlast,next,last_status, andlast_errorare scheduler state, not function config
Design Decisions¶
- The scheduler runs inside the gateway so scheduled traffic follows the same auth, policy, timeout, and runtime path as normal requests.
- Timezone support is intentionally limited to
UTC,local,Z, and fixed offsets to keep evaluation deterministic across local dev, Docker, and CI. - Retries are built in for transient runtime failures, but this is still not a distributed job system.
- If you need IANA timezones, multi-node coordination, job history, or arbitrary shell execution, use an external scheduler.