BETA
Skip to content

Scheduling Guide ​

Krafter Cron Jobs supports two scheduling modes: cron expressions for precise control and interval presets for common cadences. This guide covers both modes, timezone handling, and retry logic.

Cron Expressions ​

Set schedule_type to "cron" and provide a standard 5-field cron expression in the schedule field.

Cron Syntax ​

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *

Each field supports:

  • Specific values -- 5 (only at 5)
  • Ranges -- 1-5 (1 through 5)
  • Lists -- 1,3,5 (1, 3, and 5)
  • Steps -- */15 (every 15 units)
  • Wildcards -- * (every unit)

Common Cron Patterns ​

PatternExpressionDescription
Every minute* * * * *Runs once per minute
Every 5 minutes*/5 * * * *Runs at :00, :05, :10, ...
Every hour0 * * * *Runs at the top of every hour
Every 6 hours0 */6 * * *Runs at 00:00, 06:00, 12:00, 18:00
Daily at midnight0 0 * * *Runs once per day at 00:00
Daily at 9 AM0 9 * * *Runs once per day at 09:00
Weekly on Monday0 0 * * 1Runs every Monday at 00:00
Monthly on the 1st0 0 1 * *Runs on the 1st of every month at 00:00
Weekdays at noon0 12 * * 1-5Runs Monday--Friday at 12:00

Example: Create a Cron Job ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly Report",
    "schedule_type": "cron",
    "schedule": "0 0 * * *",
    "timezone": "Europe/Berlin",
    "url": "https://example.com/api/reports/generate",
    "method": "POST"
  }'

This job runs daily at midnight in the Europe/Berlin timezone.

Interval Presets ​

Set schedule_type to "interval" for simple recurring schedules without writing cron expressions.

Available Intervals ​

PresetDescription
every_30sEvery 30 seconds
every_1mEvery 1 minute
every_5mEvery 5 minutes
every_15mEvery 15 minutes
every_30mEvery 30 minutes
every_1hEvery 1 hour
every_6hEvery 6 hours
every_12hEvery 12 hours
every_1dEvery 24 hours

Example: Create an Interval Job ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cache Warm",
    "schedule_type": "interval",
    "schedule": "every_15m",
    "url": "https://example.com/api/cache/warm",
    "method": "POST"
  }'

TIP

Interval presets are ideal for high-frequency jobs (sub-minute to hourly). For jobs that need to run at specific times of day, use cron expressions instead.

One-Time Schedules ​

Set schedule_type to "once" and provide an ISO-8601 datetime in the schedule field. The job fires exactly once at that moment, then auto-disables (enabled becomes false, next_run_at becomes null).

A one-shot job gets the same retries as any other: next_run_at is cleared as soon as the first attempt starts, so the scheduler will not fire it a second time, but enabled stays true until the run settles — a failing one-shot job exhausts max_retries before it is marked spent.

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Migration Trigger",
    "schedule_type": "once",
    "schedule": "2026-05-15T18:00:00Z",
    "url": "https://example.com/api/run-migration",
    "method": "POST"
  }'

INFO

The timezone field is ignored for once schedules — the schedule string must include its own UTC offset (or trailing Z).

Timezone Handling ​

By default, all jobs run in UTC. You can set the timezone field to any IANA timezone identifier when creating or updating a job.

json
{
  "schedule_type": "cron",
  "schedule": "0 9 * * 1-5",
  "timezone": "America/New_York"
}

This job runs every weekday at 9:00 AM Eastern Time. Krafter automatically adjusts for daylight saving time transitions.

Common Timezones ​

TimezoneUTC Offset (standard)
UTC+00:00
America/New_York-05:00
America/Chicago-06:00
America/Los_Angeles-08:00
Europe/London+00:00
Europe/Berlin+01:00
Asia/Tokyo+09:00
Australia/Sydney+11:00

INFO

The timezone field only affects cron schedules. An interval job's next run is simply "now plus the interval", and a once schedule carries its own offset — in both cases the timezone is ignored.

How next_run_at Is Calculated ​

When a job is created or finishes executing, Krafter calculates the next run time:

  • Cron jobs -- The next matching time according to the cron expression and timezone.
  • Interval jobs -- The current time plus the interval duration.

The next_run_at field is always returned in UTC, regardless of the job's timezone setting. Pausing leaves it alone, but resuming recalculates it from the schedule — a job paused on Monday and resumed on Friday still carried Monday's next_run_at, which is in the past, and would have fired within the minute. Resuming a job never causes an immediate catch-up run.

Retry Logic ​

When a job execution fails (non-2xx status, timeout, or connection error), Krafter retries it with linear backoff: 15 seconds, 30 seconds, 45 seconds, and so on at 15 seconds per attempt. Each attempt is recorded as a separate entry in the execution history with an incrementing attempt number.

How many times it retries is up to max_retries: a job gets max_retries + 1 attempts in total, so the default of 3 means four attempts and 0 means one attempt and no retry.

FieldDefaultDescription
timeout_ms30000Receive timeout: maximum time waiting for the target endpoint to respond (in milliseconds). Valid range is 1 to 300000 (5 minutes hard cap).
max_retries3Retries after a failed attempt, 0--10. Total attempts are max_retries + 1.

INFO

The TCP connect timeout is fixed at 5 seconds and is not configurable. timeout_ms only governs how long Krafter waits for a response after the connection is established.

Example: Configure Timeout ​

bash
curl -X POST https://app.krafter.dev/api/v1/cron/jobs \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Payment Sync",
    "schedule_type": "cron",
    "schedule": "*/30 * * * *",
    "url": "https://example.com/api/payments/sync",
    "method": "POST",
    "timeout_ms": 60000
  }'

This job runs every 30 minutes and waits up to 60 seconds for a response. On failure it is retried according to its own max_retries (here the default: four attempts, with 15s/30s/45s backoff).

Redirects ​

Krafter does not follow redirects. A 3xx answer is recorded as a failed execution with the returned status in http_status.

This is deliberate. Krafter resolves your job's hostname and pins the request to the address it validated, so the call cannot be diverted to a private or internal address after the fact. Following a Location: header would hand that decision back to the endpoint and undo the check. If your URL redirects, point the job at the final URL instead.

Failure Notifications ​

Set failure_notify to true and Krafter emails the team owner when a job fails. The mail names the job, its URL and schedule, the number of attempts and the last error.

It is deliberately quiet:

  • Once per run, not once per attempt. The mail is sent only after the retries are spent, so a job with max_retries: 3 produces one mail, not four.
  • Once per outage, not once per occurrence. It is sent on the transition into failure, so a job scheduled every minute that stays broken mails once — not once a minute. When the job succeeds again and later fails again, that is a new transition and you are told again.

The job stays scheduled either way; the mail is a heads-up, not a pause. You can also query the Executions API for entries with status: "failed".

Next Steps ​

Built by Krafter Studio