Skip to main content

Cron Expression Guide

Scheduling

Master cron expressions for scheduling recurring jobs with proper timezone handling.

Cron Syntax

5-field expression format

Timezone Support

UTC or local timezone

Visual Builder

Build expressions visually

Expression Testing

Preview next run times

Cron Expression Syntax

A cron expression consists of 5 fields separated by spaces. Each field represents a unit of time and determines when the job should run.

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

Field Definitions

PropertyTypeDescription
Minute0-59Minute of the hour (0 = top of hour)
Hour0-23Hour of the day (0 = midnight, 23 = 11pm)
Day of Month1-31Day of the month (1 = first day)
Month1-12Month of the year (1 = January, 12 = December)
Day of Week0-6Day of the week (0 = Sunday, 6 = Saturday)

Special Characters

Use special characters to create flexible scheduling patterns:

PropertyTypeDescription
*wildcardMatches any value (e.g., every minute, every hour)
,listSpecifies multiple values (e.g., 1,3,5 = Mon, Wed, Fri)
-rangeSpecifies a range (e.g., 1-5 = Monday through Friday)
/stepSpecifies increments (e.g., */15 = every 15 minutes)
// Examples of special characters

// Asterisk (*) - every value
* * * * *     // Every minute

// Comma (,) - multiple specific values
0 9,12,18 * * *   // At 9am, 12pm, and 6pm

// Hyphen (-) - range of values
0 9 * * 1-5       // Weekdays at 9am (Monday through Friday)

// Slash (/) - step values
*/15 * * * *      // Every 15 minutes
0 */4 * * *       // Every 4 hours

Common Cron Patterns

Reference these commonly used patterns for typical scheduling needs:

PropertyTypeDescription
* * * * *patternEvery minute
*/5 * * * *patternEvery 5 minutes
*/15 * * * *patternEvery 15 minutes
0 * * * *patternEvery hour (at minute 0)
0 */2 * * *patternEvery 2 hours
0 0 * * *patternDaily at midnight
0 9 * * *patternDaily at 9:00 AM
0 9 * * 1-5patternWeekdays at 9:00 AM
0 0 * * 0patternWeekly on Sunday at midnight
0 6 * * 1patternWeekly on Monday at 6:00 AM
0 0 1 * *patternMonthly on the 1st at midnight
0 0 1 1 *patternYearly on January 1st at midnight

Pattern Builder

Use the CronBuilder component to visually create cron expressions without memorizing the syntax.

Timezone Handling

By default, all cron expressions are evaluated in UTC. You can specify a timezone to run jobs in local time.

UTC timezone
import { platform } from '@/lib/platform'

// Runs at 9am UTC every day
const job = await platform.jobs.schedule({
  url: 'https://myapp.com/api/jobs/daily-report',
  cron: '0 9 * * *',
  // No timezone specified = UTC
})

Daylight Saving Time

When using local timezones, be aware of DST transitions. Jobs scheduled during the "skipped" hour (when clocks spring forward) will not run. Jobs during the "repeated" hour (when clocks fall back) will run once.

Testing Cron Expressions

Preview when your cron expression will run next using the SDK or console.

Using SDK
import { platform } from '@/lib/platform'

// Get the next 5 run times for a cron expression
const nextRuns = await platform.jobs.previewCron({
  cron: '0 9 * * 1-5',
  timezone: 'America/New_York',
  count: 5,
})

console.log(nextRuns)
// [
//   '2024-01-22T14:00:00Z', // Monday 9am EST
//   '2024-01-23T14:00:00Z', // Tuesday 9am EST
//   '2024-01-24T14:00:00Z', // Wednesday 9am EST
//   '2024-01-25T14:00:00Z', // Thursday 9am EST
//   '2024-01-26T14:00:00Z', // Friday 9am EST
// ]

Scheduling via SDK

Create recurring jobs programmatically using the SDK.

lib/scheduled-jobs.ts
import { platform } from '@/lib/platform'

// Schedule a daily report
export async function scheduleDailyReport(orgId: string) {
  const job = await platform.jobs.schedule({
    url: 'https://myapp.com/api/jobs/generate-report',
    cron: '0 6 * * *', // 6am UTC daily
    body: {
      orgId,
      type: 'daily',
    },
    retries: {
      maxAttempts: 3,
      backoff: 'exponential',
    },
    metadata: {
      name: 'Daily Report',
      orgId,
    },
  })

  return job
}

// Schedule hourly cleanup
export async function scheduleCleanup() {
  return platform.jobs.schedule({
    url: 'https://myapp.com/api/jobs/cleanup',
    cron: '0 * * * *', // Every hour
    timeout: 300, // 5 minute timeout
    metadata: {
      name: 'Hourly Cleanup',
    },
  })
}

// Schedule weekly digest on Mondays
export async function scheduleWeeklyDigest(userId: string, timezone: string) {
  return platform.jobs.schedule({
    url: 'https://myapp.com/api/jobs/weekly-digest',
    cron: '0 9 * * 1', // Monday 9am
    timezone,
    body: { userId },
    metadata: {
      name: 'Weekly Digest',
      userId,
    },
  })
}

Job Metadata

Use the metadata field to store additional information about your job. This makes it easier to identify and filter jobs in the console.

Viewing Scheduled Jobs

Manage and monitor your scheduled jobs through the console or SDK.

List scheduled jobs
import { platform } from '@/lib/platform'

// List all cron jobs
const cronJobs = await platform.jobs.list({
  type: 'cron',
  status: 'active',
})

for (const job of cronJobs) {
  console.log({
    id: job.id,
    cron: job.cron,
    timezone: job.timezone,
    nextRunAt: job.nextRunAt,
    lastRunAt: job.lastRunAt,
    status: job.status,
  })
}

Console Features

The Sylphx console provides a visual interface for managing cron jobs:

Visual Schedule

See upcoming runs in a calendar view with timezone conversion

Run History

View execution history, duration, and success/failure rates

Manual Trigger

Trigger a cron job manually for testing without waiting for schedule

Quick Actions

Pause, resume, edit, or delete jobs directly from the dashboard

Best Practices

Use Descriptive Metadata

Always include meaningful metadata with your cron jobs to make them easier to identify and manage in the console.

Avoid Minute 0

Many systems schedule jobs at exactly :00 minutes. Consider using an offset (e.g., 5 * * * *) to distribute load.

Overlapping Runs

If a job takes longer than the interval between runs, the next run will be skipped. Ensure your timeout is shorter than your interval, or design jobs to handle concurrent execution.

Idempotency

Design your job handlers to be idempotent. If a job runs twice due to retries or scheduler issues, it should produce the same result.