After last week's postmortem about our cron scheduler, enough people asked where cron actually came from that it seemed worth writing down properly. Most engineers use crontab syntax weekly and know almost nothing about why it looks the way it does, which is a shame, because the history explains some genuinely odd design decisions that otherwise look arbitrary.
cron takes its name from the Greek "chronos," time, and first appeared in Version 7 Unix around 1979, credited to Brian Kernighan among others at Bell Labs, though the exact authorship of early versions is one of those pieces of Unix history that's a little murky and disputed depending on which oral history you trust. What's clear is that by the early 1980s, cron had become the standard way Unix systems ran unattended, scheduled work, and it has barely changed since.
What's remarkable isn't that cron was invented — scheduled task execution is an obvious need — it's that the interface it settled on, the five-field crontab line, has survived essentially unchanged for over four decades while nearly everything else about how we build software has been rewritten multiple times over.
Why the crontab syntax looks the way it does
The five fields — minute, hour, day of month, month, day of week — map directly onto how humans already described recurring events before computers existed ("every Monday," "the first of the month," "at 2am"). That's not an accident of implementation; it's a deliberate choice to mirror a mental model people already had, which is a big part of why it never needed replacing. Compare that to many modern scheduling configuration formats that reinvent the wheel with JSON objects or custom DSLs, and you start to appreciate how much thought went into picking an interface that matches how people actually talk about time.
# minute hour day-of-month month day-of-week command
0 3 * * * /usr/local/bin/backup.sh
*/15 * * * * /usr/local/bin/healthcheck.sh
0 9 1 * * /usr/local/bin/monthly-report.sh
The asterisk as a wildcard, the comma for lists, and the slash for step values were all added incrementally across different Unix variants during the 1980s rather than designed in one sitting, which is why the full modern syntax (ranges, steps, lists all combinable) feels like it accumulated organically — because it did.
Per-user crontabs: a later addition
Early cron implementations read a single systemwide file. The idea of individual users owning their own crontab, editable with crontab -e and stored privately rather than requiring root to edit a shared file, came later, notably through the version shipped in 4.2BSD in the early 1980s. This is the version whose behavior most modern cron implementations (including Vixie cron, which underlies most Linux distributions today) are descended from, which is why the permission model feels natural now — it's been the default for most of cron's existence, even though it wasn't there from day one.
Vixie cron and the version almost everyone actually runs
Paul Vixie rewrote cron in 1987, adding shorthand macros that most people use constantly without knowing they're a later addition rather than part of the original design:
@reboot— run once, at startup, instead of on a fixed schedule@daily/@midnight— shorthand for0 0 * * *@weekly,@monthly,@yearly— the same idea for longer intervals- A more robust handling of daylight saving time edge cases — ironic, given how often DST edge cases still trip up systems built around cron, including the one in last week's postmortem
Vixie cron, or close derivatives of it, is what ships on most Linux distributions today. The BSD family and macOS carry their own lineage, close enough in syntax that almost nobody notices the difference day to day, which is itself a testament to how thoroughly the original interface won.
The oddities that never got fixed, because nobody could agree how
Cron's design has a few well-known rough edges that have survived precisely because fixing them would break decades of existing crontabs. The most famous is the day-of-month and day-of-week fields being OR'd together rather than AND'd when both are specified as something other than a wildcard — set a job for "the 15th of the month AND every Friday" and it will actually run on both, not just when the two conditions coincide, which trips up nearly everyone the first time they read the spec closely enough to notice. There was informal discussion over the years about "fixing" this in various forks, and it never happened, because the installed base of crontabs relying on the existing OR behavior, even unknowingly, was too large to risk breaking silently.
The lack of a built-in way to express "the last day of the month" is another one — ask anyone who has written a monthly billing job why their cron expression has an ugly conditional check inside the script itself instead of in the schedule. Various non-standard extensions exist across different cron implementations to handle this, none of them universal, which is its own small lesson in how hard it is to add new syntax to a format this widely deployed without fragmenting it.
Why it's still here
Dozens of more sophisticated schedulers have been built since — Kubernetes CronJobs, Airflow, cloud provider scheduled functions, countless in-house systems like the one that bit us last week. Almost none of them have replaced cron outright; they wrap it, imitate its syntax, or coexist alongside it. The reason is less about technical superiority and more about the fact that cron does exactly one thing, does it with almost no configuration overhead, and has had forty-plus years for every weird edge case to get found and documented somewhere on the internet. That's an enormous, invisible advantage that's nearly impossible for a new tool to replicate no matter how much better its feature set looks on paper.
A small piece of software history worth knowing
Most of us interact with fifty-year-old design decisions every single day without ever thinking about where they came from. cron is a good example of a tool that got the interface right early enough that it simply never needed a second attempt — which, if you've spent any time maintaining software, you'll recognize as a remarkably rare outcome.