CtrlOps
|Docs
Product Modules

Cron Jobs: Schedule Server Tasks Without Editing Crontab

The Cron Jobs tab schedules work on your server without cron syntax. Pick a frequency from a dropdown, point the job at a shell command, a saved script, or a URL, and get a Slack, Telegram, or webhook alert the moment a run fails. Every run is logged with its full output.

Cron is how work gets scheduled on a server. Nightly backups, log cleanups, certificate renewals, the small jobs nobody thinks about until one stops. Setting one up means crontab -e, five numbers you decode from memory, and then hoping. And when a job stops running, nothing tells you. You find out days later, when the backup you needed is not there. The real problem with cron was never the syntax. It is the silence.

The Cron Jobs tab replaces both halves of that. Connect to a server and every scheduled job is listed for you, including the ones CtrlOps did not create. Pick a frequency from a dropdown instead of writing an expression, point the job at a shell command, a script you already saved, or a URL, and choose who hears about it when a run fails. Every run is kept with its full output. Scripts you save in the Script Directory can be scheduled here directly, and backup jobs keep their own schedule in the Backup tab.

What you can do in the Cron Jobs tab

  • See every scheduled job on the server, with its schedule, next run, last run status, and alerts.
  • Find cron jobs that were already on the server and adopt them into the dashboard in one click.
  • Build a schedule from a dropdown, and read the next few run times before you save.
  • Run a shell command, a saved script from your Script Directory, or an HTTP request.
  • Set a timeout, decide how many run logs to keep, and choose what happens when runs overlap.
  • Get alerted when a job fails, times out, succeeds, or prints something matching a pattern.
  • Send those alerts to Slack, Telegram, or a webhook, using a channel you set up once.
  • Run any job right now, off-schedule, without touching its timing.
  • Pause, edit, duplicate, or delete a job from the card.
  • Select several jobs and pause, resume, or delete them together.
  • Open the full history of any job and search, tail, or download the output of a single run.

Why a Cron Jobs tab instead of editing crontab

Doing it by handDoing it in CtrlOps
ssh user@host, then crontab -e in an editor you may not have pickedClick the server, click the Cron Jobs tab
Decode 0 2 * * * and hope you counted the fields rightPick Daily, set the hour and minute
Work out when it will actually fire nextRead the next run times, previewed as you choose
Jobs somebody else added are invisible until you go lookingNative jobs are listed for you with an Adopt button
Redirect output yourself, then remember where you sent itEvery run is logged with its full output
Find out it failed when something downstream breaksA Slack message the moment the run fails
Wrap the command in flock so two runs cannot collideSet Overlapping runs
Prefix the command with timeout 300Set Timeout (seconds)
Comment the line out to pause it, and remember to put it backClick Pause, then Resume
Copy a similar line and hand-edit the copyClick Duplicate

Before you start

You need very little, and CtrlOps tells you when something is missing.

RequirementWhy you need itWhat to do if it is missing
An active server connectionJobs are scheduled on the server you are connected toOpen the server from the Home page first
Cron on the serverIt is what actually fires the jobsNearly every Linux distribution ships it. If it is not running, start the cron service
An alert channelOnly if you want to be told when a run failsSet one up once on the Alert Channels tab of the Home screen

You do not need an alert channel to schedule a job. Without one the job still runs and still records its history, it just runs silently. You can add a channel later and save the job again.

Open the Cron Jobs tab

Connect to your server

Open CtrlOps and click the server you want to schedule work on. Wait for the header to show Connected.

Click the Cron Jobs tab

In the left sidebar, click Cron Jobs. It sits at the bottom of the list, below Audit Report.

Cron Jobs sits at the bottom of the left sidebar and opens on the job list.

See what is already scheduled

If you have no jobs yet you get an empty screen inviting you to create your first one. If the server already has crontab entries, they are listed here with a NATIVE badge, ready to adopt.

Two controls sit in the panel header. The timezone chip next to the title, usually Etc/UTC, tells you which clock every schedule on this page is measured against. Sync crontab re-reads the server's crontab and writes CtrlOps entries back out, which is what you click if the crontab was edited outside the app.

Adopt cron jobs that are already on the server

Most servers already have cron jobs on them, written months ago by somebody who has since moved on. CtrlOps reads the crontab and shows you those jobs instead of pretending they do not exist.

Spot the NATIVE badge

Jobs CtrlOps found rather than created carry a NATIVE badge. They read NOT TRACKED under LAST RUN, because CtrlOps has no history for them yet.

Click Adopt

Click Adopt on the job card

CtrlOps takes the entry over and starts recording every run.

Adopt sits on the card itself, next to the NATIVE badge.

Confirm the job is tracked

The NATIVE badge and the NOT TRACKED label disappear. The card now shows next run, last run status, and alerts like any other job.

Adopting does not change when a job runs. The schedule stays exactly as it was. What changes is that the job now has run history, full output logs, and somewhere to send an alert.

Create a cron job

Click New cron job

Click New cron job (top right of the Cron Jobs tab)

A panel opens on the right with a four-step flow. The left rail tracks where you are and shows a live RESULTING CRONTAB preview as you go.

New cron job sits at the top right, beside Sync crontab.

Name the job and set its schedule

FieldWhat to enter
Job nameSomething you will recognise in an alert at 3am, like nightly-cleanup.
Execute userThe Linux user the job runs as. Defaults to the user you connected with.
How oftenThe frequency. See the schedule options below.
Step 1 previews both the expression it will write and the next few times the job will fire.

Pick what the job runs

Choose one of three task types: a shell command, a saved script, or an HTTP request. Each one is covered in the three task types below.

Step 2 is where the job gets its command, its saved script, or its URL.

Choose your alerts

Tick the conditions that should reach you and pick a channel to send them to. The job fails and The job times out are already ticked. See adding alerts.

Review and create

Click Create cron job

The review screen restates everything in one place: the name, what it runs, the schedule, the guard rails, which conditions alert, and where they go. Leave Enable immediately on and the entry goes into the crontab as soon as you save.

Review restates every choice in one screen before anything is written to the server.

Pick a schedule without writing cron syntax

Pick how often the job should run and CtrlOps writes the expression for you.

How oftenWhat it means
Every N minutesRuns on a fixed minute interval, for example every 15 minutes.
HourlyRuns once an hour, on the minute you choose.
Every N hoursRuns on a fixed hour interval, for example every 6 hours.
DailyRuns once a day, at the hour and minute you choose.
Every N daysRuns on a fixed day interval.
WeeklyRuns on the weekday and time you choose.
MonthlyRuns on the day of the month and time you choose.
Custom expressionWrite the five cron fields yourself, if you already know them.

Whatever you pick, two things update live. The EXPRESSION box shows the cron expression with a plain-English reading underneath, and NEXT RUNS lists the next few times the job will fire so you can sanity-check the schedule before saving it.

Down the left rail, RESULTING CRONTAB shows the actual line CtrlOps will write:

0 2 * * * ~/.local/share/ctrlops/cron/jobs/<new>.sh

Schedules use the server's timezone, shown in the panel header, not your laptop's. If a job needs to run at 2am your time, check the server clock first.

If you would rather understand the syntax itself, our free cron expression generator builds and explains an expression field by field.

Set guard rails on a job

Three settings sit below the schedule. The defaults are sensible, so change them only when you have a reason.

SettingWhat it doesWhen to change it
Timeout (seconds)Stops a run that has gone on too longLower it for a job that should be quick, so a hung run is caught rather than left running
Logs retention (last runs)How many runs are kept in the historyRaise it for a job you audit, lower it for a noisy job that runs every few minutes
Overlapping runsWhat happens when a run is still going and the next one is dueSet it for any job that can occasionally take longer than the gap between runs

A job scheduled every five minutes that occasionally takes six is the classic way to pile up processes until a server falls over. Overlapping runs is the setting that prevents it, and it costs nothing to set now.

The three task types

Task typeUse it when
Shell commandThe job is a one-off specific to this server
Script directoryYou want the same job on several servers
HTTP requestThe job is really just pinging a URL

Shell command

A POSIX shell script, written once for this job and stored with it. This is the right choice for something specific to one server, like clearing a cache directory that only exists there.

Script directory

Runs a script you already saved in the Script Directory, with its runtime variables. Because the script library travels with you rather than living on one box, this is what you want when the same job belongs on several servers: write it once, schedule it everywhere.

HTTP request

Pings a URL on a schedule, with no shell involved at all.

FieldWhat to enter
MethodThe HTTP method, for example GET or POST.
URLThe full URL to call, for example a health endpoint.

Add alerts to a cron job

This is the part that changes how cron feels. Pick what should reach you:

Alert me whenWhat triggers it
The job failsThe run exits with a non-zero exit code
The job times outThe run exceeds the timeout you set
The job succeedsEvery clean run, useful for a job you must prove ran
Output matches a patternThe run's output contains a pattern you give

Open the Alerts step

Either create a new job and continue to step 3, or open an existing job's More actions menu, click Edit, and go to the same step.

Pick a channel under Send to

Click Add channel and pick a saved channel

Channels are set up once on the Alert Channels tab of the Home screen and reused on every job and every server, so most of the time this is picking one off a list.

Send to starts empty. Add channel picks from the ones you saved on the Home screen.

Tick the triggers you want

The job fails and The job times out are ticked for you, so a new job already alerts on failure unless you turn it off.

Then save the job. Saving is what installs the delivery details on the server.

Failure and timeout alerts are on by default, so a new job is never silent by accident.

Because the alert is written into the job on the server rather than handled by the dashboard, it fires whether or not CtrlOps is open. Close the app, close your laptop, and a failed run still reaches you.

Pick an alert channel

Alerts go to a channel: Slack, Telegram, or a webhook. You set a channel up once and reuse it on every job, on every server.

Channels live on the Alert Channels tab of the Home screen, not inside a single job. That tab lists what you have saved, lets you edit or delete a channel, and has a Send test button so you can confirm delivery before you rely on it.

Channels are configured once on the Home screen and reused on every job and every server.

Custom webhook bodies and message templates accept tokens such as {{jobName}}, {{status}}, {{exitCode}}, {{outputTail}}, and {{duration}}. The full list is on the Alert Channels tab itself, under What CtrlOps sends.

Channel changes reach a cron job only when that job is saved. Each job bakes its channel's delivery details into its own wrapper script on the server, which is exactly why alerts work with CtrlOps closed. If you edit or replace a channel, open each job that uses it and save it again. See where CtrlOps puts your cron jobs.

Read the job list

Each job is a card, and the card is meant to answer "is this fine?" without opening anything.

On the cardWhat it tells you
ScheduleThe frequency in plain English, with the cron expression underneath
Next runA countdown and the exact date and time
Last runWhether the previous run succeeded or failed, and how long it took
AlertsWhich channel this job notifies, or a prompt to add one

Above the list, filter chips narrow things down:

ChipShows
AllEvery job on the server
ActiveJobs currently scheduled to run
PausedJobs that exist but are not firing
FailingJobs whose last run failed, the one to check first
NativeJobs found on the server that you have not adopted yet

The search box filters by name, script, or command, which is how you find a job on a server that has thirty of them. The toggle at the top right switches between card and table views.

Act on a single job

ActionWhere it isWhat it does
Run nowPlay icon on the cardRuns the job immediately, without changing its schedule
HistoryClock icon on the cardOpens every recorded run and its output
PauseMore actions menuStops the job firing, keeps its definition and history
EditMore actions menuReopens the four-step panel on an existing job
DuplicateMore actions menuCopies the job as a starting point for a similar one
DeleteMore actions menuRemoves the job

Delete removes the entry from the server's crontab, so the job stops running. If you only want it to stop for now, use Pause instead, which keeps the job and its history intact.

Act on several jobs at once

Select jobs in the list and the toolbar turns into bulk actions: Pause, Resume, Delete, and Clear to drop the selection. The honest use for this is a maintenance window: pause everything before you start, resume it when you are done, and you never have to remember which individual jobs you commented out.

Open the run history and logs

Click the history icon on the job card

The clock icon, next to run now, opens that job's run history. How many runs are kept is set by the Logs retention guard rail.

Pick a run

Runs are listed newest first with their status, size, and exit code. Click one to load its output.

Search, tail, or download the output

The full output is here, stdout and stderr together rather than in two separate files you have to correlate.

Every run is kept with its full output, searchable and tailable like any log file.
ControlWhat it does
Search outputFilters the loaded lines
Line countHow many lines to load, 500 by default
FollowTails a run that is still going
RefreshRe-pulls the output
DownloadSaves the run's output to your machine
DeleteRemoves that run from the history

This is one job's output. For whole log files on disk, like an Nginx access log, use the Logs tab instead.

Where CtrlOps puts your cron jobs

Worth understanding, because it explains most of the behaviour on this page.

CtrlOps does not put your command directly in the crontab. It writes a small wrapper script under ~/.local/share/ctrlops/cron/jobs/ and points the crontab entry at that:

0 2 * * * ~/.local/share/ctrlops/cron/jobs/<new>.sh

The wrapper is what records the run, enforces the timeout, applies the overlapping-runs rule, and sends the alert. Three things follow from that. Alerts arrive even with CtrlOps closed, because the server sends them. Editing an alert channel does not reach jobs you already saved, because their delivery details were written into their own wrapper at save time. And if the crontab is edited outside CtrlOps, Sync crontab is what brings the two back into agreement.

Tips

Set the alert when you create the job, not after the first failure. The whole point is to find out from a message rather than from a customer.

On a server you inherited, adopt the native jobs before you change anything. Once they are tracked you can see what actually runs and what has been quietly failing for months.

If the same job belongs on more than one server, save it in the Script Directory first and schedule it as a Script directory task. Then you fix the script once instead of in five separate crontabs.

Troubleshooting

Frequently Asked Questions

How do I create a cron job without editing crontab?

Open CtrlOps, click your server, go to the Cron Jobs tab, and click New cron job. A four-step panel asks for a name and how often the job should run, what it should run, and which failures should alert you. CtrlOps writes the crontab entry for you and shows the resulting line in a preview as you build it.

Do I need to know cron syntax to use CtrlOps?

No. The frequency picker covers every N minutes, hourly, every N hours, daily, every N days, weekly, and monthly, and CtrlOps turns your choice into the cron expression. It also lists the next few run times, so you can confirm the schedule means what you think it means before you save. A custom expression option is there if you already know the syntax.

Can CtrlOps find cron jobs that are already on my server?

Yes. CtrlOps reads the server crontab when you open the tab and lists anything it did not create with a NATIVE badge and an Adopt button. Until you adopt one it reads NOT TRACKED under LAST RUN. Click Adopt and the job joins the dashboard with run history, logs, and alerts, without changing its schedule.

How do I get a Slack alert when a cron job fails?

In the Alerts step of the job, tick The job fails, pick a Slack channel under Send to, and save. The job fails and The job times out are ticked by default, so a new job already alerts on failure unless you turn it off. You can also alert on every successful run, or when the output matches a pattern.

Do cron job alerts still fire when CtrlOps is closed?

Yes. The channel's delivery details are written into the job's wrapper script on the server, so the server sends the alert itself. Nothing depends on the desktop app being open, which is the whole point of putting the alert in the job rather than in the dashboard.

Where can I see the output of a cron job run?

Click the history icon on the job card. Every run is listed with its status, and opening one shows the full output, stdout and stderr together. You can search it, change how many lines to load, download it, delete it, or click Follow to tail a run that is still going.

What can a CtrlOps cron job actually run?

Three things. A shell command is a POSIX shell script you write once for this job. A script directory job runs a saved script from your Script Directory with runtime variables, so the same script works on every server. An HTTP request job takes a method and a URL and pings it on a schedule.

Can I stop a cron job from running twice at the same time?

Yes. Each job carries an Overlapping runs setting alongside its timeout and log retention. Set it when a run can take longer than the gap between runs, for example a job scheduled every five minutes that occasionally takes six.

How do I pause a cron job without deleting it?

Open the More actions menu on the job card and click Pause. The job stops firing but its definition, alerts, and run history are kept, and the same menu resumes it later. You can also select several jobs in the list and pause or resume them together.

What timezone do CtrlOps cron jobs run in?

The server's timezone, which is shown in the panel header next to the Cron Jobs title, for example Etc/UTC. The next run times CtrlOps previews use that same timezone, so a job set for 2:00 runs at 2:00 on the server, not on your laptop.