Dev Encyclopedia
ArticlesToolsContactAbout

Get notified when new content drops

No spam. Just new articles, tools, and updates straight to your inbox.

Dev Encyclopedia

A reference for builders

Content

  • Articles
  • Tools
  • About
  • Contact

Connect

  • support@devencyclopedia.com
  • RSS Feed

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

© 2026 Dev Encyclopedia

Back to top ↑
  1. Home
  2. /
  3. Tools
  4. /
  5. Cron to systemd Timer Converter
Free · Private · No server

Turn a cron line into a systemd timer, instantly.

Paste your crontab entry. Get a ready-to-save .timer and .service file, a plain-English schedule, and the next five run times. All in your browser.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

How Cron to systemd Timer Converter works

  1. 1

    Paste a crontab line

    Paste a standard 5-field cron line with its command, or a macro like @daily, @hourly, or @reboot followed by the command to run.

  2. 2

    The schedule is parsed entirely in your browser

    Nothing is sent to a server. The five cron fields (or the expanded macro) are validated and translated field by field into systemd's OnCalendar= syntax.

  3. 3

    The day-of-month / day-of-week OR trap is detected

    If your schedule restricts both fields at once, a warning explains the difference between cron's OR behavior and systemd's AND behavior, and the tool emits two OnCalendar= lines to reproduce cron's semantics exactly.

  4. 4

    A .service and .timer file are generated

    The .service file wraps your command with Type=oneshot. The .timer file gets the OnCalendar= line(s), an optional Persistent=true, and WantedBy=timers.target.

  5. 5

    Toggle User or System mode

    Switching the mode updates the save-and-enable commands to match: user units go in ~/.config/systemd/user/ with systemctl --user, system units go in /etc/systemd/system/ with plain systemctl.

  6. 6

    Copy the files and the enable commands

    Save the two files with the suggested name, run the daemon-reload and enable command shown, and (for user mode) enable lingering so the timer survives logout.

What each generated file does

Every cron job becomes exactly two systemd unit files.

.service

Defines what actually runs. Type=oneshot tells systemd this unit runs once and exits, rather than staying resident, which matches how a cron job behaves.

[Unit]
Description=my-job

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
.timer

Defines when the .service runs. OnCalendar= is the schedule itself, Persistent=true (optional) catches up on a missed run after downtime, and WantedBy=timers.target makes the timer start automatically.

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target
OR trap warning

Shown only when both day-of-month and day-of-week are restricted in your cron line. Two OnCalendar= lines are generated instead of one, since systemd unions them, to correctly reproduce cron's OR semantics.

OnCalendar=*-*-01 00:00:00
OnCalendar=Sun *-*-* 00:00:00
Save and enable commands

The exact commands to copy the two files into place, reload systemd, and enable the timer, adjusted automatically for User vs System mode.

systemctl --user daemon-reload
systemctl --user enable --now my-job.timer

Cron and OnCalendar syntax reference

What's supported on input, and what it maps to on output.

Field-by-field mapping
# Cron:    minute hour day-of-month month day-of-week
# Fields:    0-59  0-23     1-31        1-12    0-7 (0 and 7 both = Sunday)

*              -> *                (any value, in either syntax)
*/15           -> 0/15             (step values)
1-5            -> 1..5             (ranges use .. in OnCalendar)
1,15           -> 1,15             (comma lists, unchanged)
dow: 1-5       -> Mon..Fri         (weekday numbers become names)
dow: 0 or 7    -> Sun

# Macros expand before conversion:
@yearly / @annually -> 0 0 1 1 *
@monthly             -> 0 0 1 * *
@weekly              -> 0 0 * * 0
@daily / @midnight   -> 0 0 * * *
@hourly              -> 0 * * * *
@reboot              -> OnBootSec=0 (no OnCalendar= at all)

Already comfortable with cron and just need to build or double-check an expression first? Our Cron Expression Builder handles that half separately, with a visual field editor and its own next-run preview.

When to use Cron to systemd Timer Converter

ScenarioWhat to pasteWhat you get
Migrating a server off cron onto systemdEach line from crontab -l, one at a timeA .timer/.service pair per job, ready to enable
You inherited a crontab from a previous adminThe exact line you don't fully understand yetA plain-English schedule description and next run times
Want missed-run recovery on a laptop or workstationYour existing cron jobA timer with Persistent=true, so it catches up after the machine wakes
Setting up a rootless container hostThe job you'd normally cron as your own userUser-mode unit files plus the enable-linger reminder
Double-checking a day-of-month + day-of-week scheduleA line like 0 0 1 * 0The OR-trap warning and the two OnCalendar= lines it requires
Converting a @reboot cron entry@reboot /path/to/script.shA timer using OnBootSec=0 instead of OnCalendar=

Frequently Asked Questions

What is systemd OnCalendar syntax?

OnCalendar= is the directive systemd timers use to define a recurring schedule. It follows the format weekday year-month-day hour:minute:second, where each component supports lists (,), ranges (..), wildcards (*), and step values (/).

text
*-*-* 02:00:00        # every day at 2:00 AM
Mon..Fri *-*-* 09:00:00  # weekdays at 9:00 AM
*-*-* *:0/15:00        # every 15 minutes
*-01-01 00:00:00       # New Year's Day at midnight

Check what a timer will actually do before deploying it with systemd-analyze calendar "Mon..Fri *-*-* 09:00:00", which prints the next several trigger times.

Does this replace cron entirely?

Not necessarily, but systemd timers cover everything cron does and add a few things cron can't: Persistent=true catches up on a missed run after the machine was off, output goes to journalctl alongside every other service's logs, and Requires=/After= let a timer's job depend on another service being up first.

Plain cron is still perfectly fine for simple, low-stakes personal scripts. Systemd timers are the better choice for anything running on a server you actually monitor.

What's the difference between the User and System toggle?
User (rootless)System (rootful)
Unit file location~/.config/systemd/user//etc/systemd/system/
Managed withsystemctl --user ...systemctl ... (no --user)
Runs asYour userroot
Survives logout by defaultNo, needs enable-lingerYes, always

Default to User mode unless the job genuinely needs root privileges. If you pick User mode, remember to run loginctl enable-linger $USER once, or the timer stops the moment you log out.

Does this tool send my crontab or server details to a server?

No. Parsing the cron line, computing the next run times, and generating the unit files all happen in JavaScript inside your browser. Nothing, including your commands, paths, or job names, is sent anywhere.

💡 Tip

This makes it safe to paste real production crontab lines, including internal paths and script names, without any of that leaving your machine.

How do I convert a real crontab line, step by step?

Paste the exact line from crontab -l, including the command, then copy the two generated files to the location shown in the "Save and enable" block:

bash
# 1. See your existing crontab
crontab -l

# 2. Paste a line like this into the tool above:
#    0 2 * * * /usr/local/bin/backup.sh

# 3. Save the generated files, then reload and enable (user mode shown):
mkdir -p ~/.config/systemd/user
cp my-job.service my-job.timer ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now my-job.timer

# 4. Remove the old cron entry once you've confirmed the timer works
crontab -e

For a full worked example converting a multi-service Docker Compose stack (not just a scheduled job) to systemd, see our Docker Compose to Podman Quadlet migration guide.

Why did I get two OnCalendar= lines instead of one?

This happens when your cron line restricts both the day-of-month and the day-of-week fields at the same time, for example 0 0 1 * 0 (the 1st of the month, or every Sunday).

Cron treats that combination as an OR: the job runs if either condition matches. A single systemd OnCalendar= expression with both a weekday and a day-of-month set is an AND instead, which would silently narrow your schedule. Since systemd unions multiple OnCalendar= directives in the same [Timer] section, the tool generates one line per condition to reproduce cron's OR behavior correctly.

Related reading

Guide

Docker Compose to Podman Quadlet

See a full systemd unit conversion example: a multi-service Docker Compose stack converted to Quadlet .container, .volume, and .network units.

Guide

Cloud & DevOps Interview Questions

Covers the broader Linux, container, and infrastructure concepts that come up alongside scheduling and service management.

Zeeshan Tofiq

Zeeshan Tofiq

Full Stack Developer

Full stack developer with over 6 years of experience building production applications. Writes practical guides on JavaScript, TypeScript, React, Node.js, and cloud infrastructure. Focused on helping developers solve real problems with clean, maintainable code.

Enjoyed this article?

Get practical dev guides, tool updates, and new articles delivered straight to your inbox. No spam, unsubscribe anytime.

Try:

Paste a crontab line above, or click one of the examples.