NetStacksNetStacks

Cron Expressions

Enterprise

Write cron expressions for NetStacks scheduled tasks: 5-field format, timezone support, named days/months, and ready-to-paste patterns for network ops.

Overview

Controller feature

Scheduled tasks and cron parsing are part of the NetStacks Controller (Enterprise). The Controller stores a cron_expression and a timezone on each scheduled task and validates the expression when you create or update it.

Cron expressions define when a scheduled task runs in NetStacks. The Controller uses a 5-field cron format — minute, hour, day of month, month, and day of week — to express schedules from every minute to once a year. Each task pairs its cron expression with an IANA timezone so schedules behave correctly across regions and daylight saving transitions.

cron-format.txttext
Cron Expression Format (5 fields)

  ┌───────────── minute (0-59)
  │ ┌───────────── hour (0-23)
  │ │ ┌───────────── day of month (1-31)
  │ │ │ ┌───────────── month (1-12 or JAN-DEC)
  │ │ │ │ ┌───────────── day of week (0-7 or SUN-SAT; 0 and 7 = Sunday)
  │ │ │ │ │
  * * * * *

Under the hood the Controller parses expressions with the croner engine. Each field accepts numbers, wildcards, ranges, lists, and step values — plus named days and months and a few special tokens described below. The default expression for a new task is 0 9 * * * (daily at 09:00) with a default timezone of UTC.

How It Works

Validation

When you create or update a scheduled task, the Controller validates the cron expression by parsing it. An expression that fails to parse is rejected with an HTTP 400 error before the task is saved, so an invalid schedule never reaches the scheduler. The timezone is validated the same way: it must be a parseable IANA identifier or the request is rejected.

Next-Run Calculation

After validation, the Controller calculates the next run time relative to the task's timezone and stores it in the next_run_at field as a UTC timestamp (RFC 3339). The current time is taken in the task's timezone, the next matching occurrence is found, and the result is converted back to UTC for storage. next_run_at is recalculated whenever the cron expression or timezone changes.

Timezone Handling

Every cron expression is evaluated in the context of its timezone. The timezone field accepts any valid IANA identifier (for example America/New_York, Europe/London, Asia/Tokyo, or UTC). If a task is created without a timezone, the Controller defaults to UTC. Because the next run is computed in local time, a task scheduled for 02:00 keeps firing at 02:00 local time across daylight saving transitions.

UTC storage

Timestamps such as next_run_at are stored and returned in UTC (RFC 3339). The cron expression itself is always interpreted in the task's timezone. This keeps behavior consistent regardless of the server's local clock.

Human-Readable Description

The scheduled-task UI renders a short human-readable description next to the cron field for common patterns — for example 0 2 * * * shows as "Daily at 2:00" and 0 9 * * 1-5 shows as "Weekdays at 9:00". Less common expressions fall back to showing the raw cron string. Use this description to sanity-check the field order before saving.

Writing Cron Expressions

Step 1: Understand Each Field

FieldPositionAllowed ValuesDescription
Minute1st0-59Minute of the hour
Hour2nd0-23Hour of the day (24-hour clock)
Day of Month3rd1-31 (also L)Day of the month
Month4th1-12 or JAN-DECMonth of the year
Day of Week5th0-7 or SUN-SAT (also #)Day of the week; both 0 and 7 mean Sunday

Step 2: Use Special Characters

CharacterMeaningExample
*Every value in the field* * * * * = every minute
,List of specific values0,30 * * * * = at minute 0 and 30
-Range of values0 9-17 * * * = every hour from 9 AM to 5 PM
/Step value (every Nth)*/15 * * * * = every 15 minutes
LLast day (in day-of-month field)0 23 L * * = 11 PM on the last day of the month
#Nth weekday of the month (in day-of-week field)0 9 * * 1#1 = first Monday at 9 AM
Named days and months

The cron engine accepts case-insensitive names as well as numbers. You can write 0 9 * * MON-FRI instead of 0 9 * * 1-5, or 0 0 1 JAN * instead of 0 0 1 1 *. Names and numbers can be mixed across fields.

Step 3: Set the Timezone

Pair every cron expression with a timezone. Use IANA names such as America/New_York, America/Chicago, America/Los_Angeles, or UTC. The schedule dialog offers a curated list of common zones, and the API accepts any valid IANA identifier. The timezone determines when the expression fires relative to local time.

Step 4: Check the Description

After typing an expression in the schedule dialog, read the human-readable description shown beneath the field. If it does not match what you intended (or it falls back to showing the raw string for an uncommon pattern), re-check the field order — minute first, day-of-week last.

Start from a known pattern

If you are unsure about an expression, copy a known pattern from the Code Examples section below and adjust it to fit your needs.

Code Examples

Common Cron Patterns for Network Operations

ExpressionScheduleNetwork Use Case
*/15 * * * *Every 15 minutesHealth check on edge switches
0 2 * * *Daily at 2:00 AMNightly config backup for core routers
0 18 * * 1-5Weekdays at 6:00 PMEnd-of-day config diff report
0 */6 * * *Every 6 hoursInterface utilization snapshot
0 0 * * 0Sunday at midnightWeekly VLAN audit on access switches
0 9 * * 1#1First Monday of the monthMonthly firmware compliance review
0 23 L * *Last day of the month at 11 PMMonth-end inventory snapshot
0 7 * * MON-FRIWeekdays at 7:00 AMMorning health summary (named days)

Health Check Every 15 Minutes

health-check-schedule.txttext
# Cron: */15 * * * *
# Timezone: UTC
# Runs at :00, :15, :30, :45 every hour
# Use case: Monitor reachability of branch edge switches

Minute:       */15   (every 15th minute)
Hour:         *      (every hour)
Day of Month: *      (every day)
Month:        *      (every month)
Day of Week:  *      (every day of the week)

Nightly Backup at 2 AM Eastern

backup-schedule.txttext
# Cron: 0 2 * * *
# Timezone: America/New_York
# Runs at 2:00 AM ET (07:00 UTC on EST, 06:00 UTC on EDT)
# Use case: Capture running-config from core and distribution devices

Minute:       0      (at the top of the hour)
Hour:         2      (2 AM local time)
Day of Month: *      (every day)
Month:        *      (every month)
Day of Week:  *      (every day of the week)

Weekday Business Hours Only

business-hours-schedule.txttext
# Cron: 0 9-17 * * 1-5     (or: 0 9-17 * * MON-FRI)
# Timezone: America/Chicago
# Runs every hour from 9 AM to 5 PM, Monday through Friday
# Use case: Hourly interface error-counter check during business hours

Minute:       0      (at the top of each hour)
Hour:         9-17   (9 AM through 5 PM)
Day of Month: *      (every day)
Month:        *      (every month)
Day of Week:  1-5    (Monday through Friday)

Creating a Scheduled Task via the API

The Controller validates the cron expression and timezone on create. A request with an unparseable expression returns HTTP 400 and is not saved.

create-task.httphttp
POST /api/tasks/agent-schedules
Content-Type: application/json

{
  "name": "Nightly core config backup",
  "prompt": "Back up the running-config of all core routers and report diffs.",
  "cron_expression": "0 2 * * *",
  "timezone": "America/New_York"
}

On success the response echoes the stored task, including the computed next_run_at as a UTC RFC 3339 timestamp:

task-response.jsonjson
{
  "name": "Nightly core config backup",
  "cron_expression": "0 2 * * *",
  "timezone": "America/New_York",
  "next_run_at": "2026-06-17T06:00:00+00:00"
}
Minimum interval

Cron syntax supports running as often as every minute (* * * * *), but frequent runs add load to target devices and the Controller. For production health checks, prefer intervals of 5 minutes or longer.

Questions & Answers

Q: What cron format does NetStacks use?
A: The Controller uses the standard 5-field cron format — minute, hour, day of month, month, day of week. Each field supports wildcards (*), ranges (1-5), lists (0,30), and step values (*/15). Parsing is handled by the croner engine, which is compatible with common Unix crontab syntax.
Q: Can I use day names or month names in cron expressions?
A: Yes. The cron engine accepts case-insensitive names in addition to numbers. Use SUN-SAT for days of the week and JAN-DEC for months — for example 0 9 * * MON-FRI or 0 0 1 JAN *. In the day-of-week field both 0 and 7 mean Sunday. The schedule dialog itself is a plain text field, so you can type either form.
Q: How do I schedule a task for the last day of the month?
A: Use the L token in the day-of-month field. For example, 0 23 L * * runs at 11 PM on the last day of every month, whether that is the 28th, 30th, or 31st. (Classic Unix crontab has no last-day keyword and would require a workaround like 28-31, but the NetStacks engine supports L directly.)
Q: Can I schedule the first/second/Nth weekday of the month?
A: Yes, using the # token in the day-of-week field. 0 9 * * 1#1 runs at 9 AM on the first Monday of the month, and 0 9 * * 5#3 runs on the third Friday. This is handy for monthly maintenance windows and compliance reviews.
Q: How do I handle timezones in cron expressions?
A: Each scheduled task has a timezone field that accepts IANA identifiers like America/New_York or Europe/London. The expression is evaluated in that timezone, the next run is computed in local time, and the result is stored as a UTC next_run_at timestamp. Schedules keep firing at the same local time across daylight saving changes. If no timezone is supplied, the default is UTC.
Q: How do I confirm my cron expression is correct?
A: The schedule dialog shows a short human-readable description next to the cron field for common patterns (for example "Daily at 2:00" or "Weekdays at 9:00"). Uncommon expressions fall back to displaying the raw string. After saving, the task's next_run_at timestamp tells you exactly when it will fire next. Invalid expressions are rejected with an error before the task is saved.
Q: What is the minimum interval for scheduled tasks?
A: The shortest cron interval is every minute (* * * * *), but that is not recommended for production. Health checks and monitoring typically use 5- or 15-minute intervals; backups and deployments use daily or weekly schedules. Running tasks too frequently can overload target devices and consume Controller resources.

Troubleshooting

Invalid cron expression error on save

The Controller validates the expression by parsing it and rejects anything that fails with an HTTP 400. Check the field count (exactly five space-separated fields), confirm ranges are within bounds, and make sure any names (MON, JAN) and tokens (L, #) are placed in the correct field. The timezone is validated the same way — an unrecognized IANA name is also rejected.

Task running at the wrong time

This is almost always a timezone mismatch. Verify the timezone field matches your intended local time, then check next_run_at (a UTC timestamp) and convert it to local time to confirm it aligns with the expression. Remember that daylight saving transitions shift the UTC offset by one hour, so the UTC time of a local 02:00 task changes seasonally.

Expression not matching expected schedule

The most common mistake is confusing field order. The fields are minute, hour, day-of-month, month, day-of-week. For example, 30 2 * * * means "at 2:30 AM" (minute 30, hour 2), not "every 30 minutes at 2 AM." The human-readable description in the schedule dialog helps catch this before you save.

Overlapping executions

If a previous run has not finished by the next scheduled trigger, you can end up with overlapping work and a growing backlog. If a task consistently takes longer than its interval, widen the cron interval or reduce the task's scope so it finishes well within its window.

Tip

Use the Task Monitoring dashboard to track execution duration over time. If a task's average duration approaches its cron interval, widen the interval to prevent queue buildup.

Learn more about scheduling and automation in NetStacks:

  • Scheduled Tasks — Create and manage cron-scheduled tasks for backups, health checks, and automated reviews
  • Task Monitoring — Track execution status, view logs, and watch run history
  • Method of Procedures (MOPs) — Multi-step procedures with approval workflows for complex changes
  • MOP Approvals — Require sign-off before a procedure executes
  • NOC Agents — AI agents that run the prompt attached to a scheduled task