Skip to content

Scheduler

The RouterOS Scheduler allows you to automate tasks by running scripts or commands at specific times, after a set interval, or immediately on router startup. Common uses include automated backups, log rotation, periodic reboots, interface monitoring, and any other maintenance work that benefits from hands-free execution.

The scheduler integrates with the /system script subsystem. Each scheduler entry specifies:

  • When to run — a specific date/time, an interval, or at startup
  • What to run — a named script from /system script, or an inline command
  • With what permissions — the policy flags the task executes under

Accurate system time is required for time-based triggers. See Clock and NTP for time configuration.

/system scheduler
PropertyType / ValuesDescription
namestringUnique name for the scheduler entry
start-datedate (mmm/DD/YYYY)The first date the task is eligible to run. Defaults to the current date
start-timetime (HH:MM:SS) or startupTime of day to first run, or startup to trigger approximately 3 seconds after the router boots
intervalduration (w/d/h/m/s)How often to repeat. Setting interval=0 runs the task exactly once
on-eventstringA /system script name, or an inline RouterOS command to execute
policyflag listPermissions granted to the task. Possible flags: read, write, policy, test, password, sniff, sensitive, romon, dude, api
commentstringAdministrative note — visible in the scheduler list
disabledyes / noWhen yes, the entry is skipped entirely
PropertyDescription
run-countNumber of times this task has executed since the last reboot
next-runDate and time of the next scheduled execution

Durations combine weeks (w), days (d), hours (h), minutes (m), and seconds (s):

ExampleMeaning
interval=1dEvery 24 hours
interval=12hEvery 12 hours
interval=1wEvery 7 days
interval=30mEvery 30 minutes
interval=1d12hEvery 36 hours
interval=0Run once, do not repeat

When start-time=startup is set, the task fires approximately 3 seconds after the router console starts. This is useful for initialization tasks that must run on every boot regardless of the time of day.

If interval is also set alongside startup, the task fires at startup and then continues repeating on that interval.

/system scheduler print

Example output:

Flags: X - disabled
# NAME START-DATE START-TIME INTERVAL ON-EVENT
0 nightly-backup jan/01/1970 03:00:00 1d run-backup
1 startup-check jan/01/1970 startup 0 check-interfaces
/system scheduler add \
name=nightly-backup \
start-date=jan/01/1970 \
start-time=03:00:00 \
interval=1d \
on-event=run-backup \
policy=read,write,policy,test,password,sensitive \
comment="Daily backup at 3 AM"
/system scheduler set nightly-backup start-time=02:00:00
# Disable
/system scheduler disable nightly-backup
# Enable
/system scheduler enable nightly-backup
/system scheduler remove nightly-backup

RouterOS has no run command under /system scheduler. To trigger a task immediately, run the underlying script directly:

/system script run nightly-backup

Creates a script that exports the configuration to a file, then schedules it to run every day at 02:00:

# Create the backup script
/system script add name=run-backup policy=read,write,policy,test,password,sensitive \
source="/export file=backup-[/system identity get name]"
# Schedule it to run daily at 02:00
/system scheduler add \
name=nightly-backup \
start-time=02:00:00 \
interval=1d \
on-event=run-backup \
policy=read,write,policy,test,password,sensitive \
comment="Daily config backup"

Run a script once every time the router boots to restore dynamic state or send a notification:

/system script add name=on-boot \
policy=read,write,test \
source="/log info \"Router has started\""
/system scheduler add \
name=boot-init \
start-time=startup \
interval=0 \
on-event=on-boot \
policy=read,write,test \
comment="Run once at every boot"

Schedule a weekly reboot during a maintenance window:

/system scheduler add \
name=weekly-reboot \
start-date=jan/01/1970 \
start-time=04:00:00 \
interval=1w \
on-event="/system reboot" \
policy=read,write,policy,reboot \
comment="Weekly maintenance reboot Sunday 4 AM"

Run a command exactly once at a future time (useful for planned changes):

/system scheduler add \
name=one-time-change \
start-date=mar/25/2026 \
start-time=22:00:00 \
interval=0 \
on-event="/interface disable ether2" \
policy=read,write \
comment="Disable ether2 at 10 PM March 25"

This entry runs once and does not repeat. After execution, run-count shows 1 and next-run becomes empty.

on-event accepts either a /system script name or an inline command:

# Using a named script (preferred for multi-line logic)
/system scheduler add name=use-script on-event=my-script-name \
start-time=06:00:00 interval=1d policy=read,write
# Using inline command (fine for simple one-liners)
/system scheduler add name=log-heartbeat \
on-event="/log info \"heartbeat\"" \
start-time=startup interval=5m policy=read

For anything beyond a single command, define the logic in /system script and reference it by name.

The scheduler has no native argument-passing field. The two common patterns are:

Pattern 1 — Global variable set inline

Set a global before calling the named script. The script reads the global at runtime:

# Script that reads a global argument
/system script add name=rotate-backup \
policy=read,write,policy,test,sensitive \
source={
:global keepDays
:if ([:len $keepDays] = 0) do={ :set keepDays 7 }
:log info ("Rotating backups, keeping $keepDays days")
# ... rotation logic using $keepDays ...
}
# Scheduler entry sets the global, then calls the script
/system scheduler add \
name=rotate-backup-14d \
start-time=04:00:00 \
interval=1d \
on-event=":global keepDays 14; /system script run rotate-backup" \
policy=read,write,policy,test,sensitive \
comment="Rotate backups, keep 14 days"

Pattern 2 — Fully inline logic

For simple one-off parameterisation, embed the logic directly in on-event:

/system scheduler add \
name=disable-ether2 \
start-date=mar/25/2026 \
start-time=22:00:00 \
interval=0 \
on-event="/interface disable ether2" \
policy=read,write \
comment="One-time: disable ether2 at 22:00 on Mar 25"

Creates a timestamped binary backup and exports the configuration, then uploads both to a remote server. The script requires ftp, sensitive, and password policies in addition to read and write.

# Create the upload script
/system script add name=backup-upload \
policy=read,write,policy,test,password,sensitive,ftp \
source={
:local id [/system identity get name]
:local d [/system clock get date]
:local base ($id . "-" . [:pick $d 7 11] . [:pick $d 4 6] . [:pick $d 0 3])
:local backupFile ($base . ".backup")
:local exportFile ($base . ".rsc")
# Create local backup files
:do {
/system backup save name=$base encryption=aes-sha256
/export file=$base
} on-error={
:log error "BACKUP: failed to create local files"
:error "backup-failed"
}
# Wait for files to be written
:delay 3s
# Upload binary backup
:do {
/tool fetch mode=sftp address=203.0.113.10 port=22 \
src-path=$backupFile upload=yes \
user=backupuser password="StrongPassword" \
dst-path=("/backups/" . $backupFile)
:log info ("BACKUP: uploaded " . $backupFile)
} on-error={
:log error ("BACKUP: upload failed for " . $backupFile)
}
# Upload text export
:do {
/tool fetch mode=sftp address=203.0.113.10 port=22 \
src-path=$exportFile upload=yes \
user=backupuser password="StrongPassword" \
dst-path=("/backups/" . $exportFile)
:log info ("BACKUP: uploaded " . $exportFile)
} on-error={
:log error ("BACKUP: upload failed for " . $exportFile)
}
}
# Schedule daily at 02:30
/system scheduler add \
name=daily-backup-upload \
start-time=02:30:00 \
interval=1d \
on-event=backup-upload \
policy=read,write,policy,test,password,sensitive,ftp \
comment="Daily backup + SFTP upload"

For FTP instead of SFTP, change mode=sftp port=22 to mode=ftp port=21.

Disable and re-enable an interface — useful for resetting a link without a full reboot:

/system script add name=bounce-wan \
policy=read,write \
source={
:local iface "ether1"
:log info ("Bouncing " . $iface)
/interface disable $iface
:delay 10s
/interface enable $iface
:log info ($iface . " re-enabled")
}
# Schedule a weekly bounce during maintenance window
/system scheduler add \
name=weekly-wan-bounce \
start-date=jan/01/1970 \
start-time=04:00:00 \
interval=1w \
on-event=bounce-wan \
policy=read,write \
comment="Weekly WAN interface bounce"

To trigger the bounce immediately for testing:

/system script run bounce-wan

Each scheduler entry has its own policy flag set. When a scheduled task calls a named script, RouterOS checks that the intersection of the scheduler policy and the script policy is sufficient to perform the operations in the script.

If a script requires write permission but the scheduler entry’s policy does not include write, the task will fail with a permissions error.

For scripts that need to run from the scheduler without strict policy matching, set dont-require-permissions=yes on the script:

/system script set my-script dont-require-permissions=yes

Use this only for trusted, internally maintained scripts. It bypasses all permission checks for that script regardless of which facility calls it.

  1. Check the task is enabled:

    /system scheduler print

    Disabled entries are flagged with X.

  2. Verify next-run is populated and in the future:

    /system scheduler print detail
  3. Confirm system time is correct — tasks will not trigger if the clock is wrong:

    /system clock print
  1. Check the system log for script errors:

    /log print where topics~"script"
  2. Confirm the scheduler policy includes the permissions the script needs (e.g., write for configuration changes, test for ping/traceroute).

  3. Try running the underlying script manually to reproduce the error interactively:

    /system script run task-name

If a task takes longer than its interval, RouterOS will not start a second instance — the current run continues and the next trigger is skipped. To avoid missed runs, set interval to be safely longer than the maximum expected execution time.

If the log shows permission denied for a scheduled script:

  1. Check the policy flags on both the scheduler entry and the script.
  2. Ensure required flags (e.g., write, policy, sensitive) are present on the scheduler entry.
  3. Consider dont-require-permissions=yes on the script if the execution context cannot hold the required flags.
  • Clock - System time configuration
  • Scripting - Script syntax, variables, loops, and functions
  • Logging - Viewing script execution logs
  • NTP - Time synchronization for accurate scheduling
  • Fetch - Upload/download files from scripts