# How I read cron schedules without pretending I remember the syntax

A beginner-friendly guide to cron expressions, the five fields, common schedule examples, and checking next run times before installing a job.

- Date: 2026-09-27
- URL: https://ilham.dev/posts/how-to-read-cron-schedules/
- Markdown: https://ilham.dev/posts/how-to-read-cron-schedules/index.md
- Tags: cron, linux, automation, tools
- Reading time: 4 min


Cron is simple once it is explained, but the syntax is not something I try to
memorise perfectly.

A cron expression often looks like this:

```text
0 2 * * *
```

If you do not read cron every day, that line is not obvious. The
[Crontab Generator](/tools/crontab-generator/) helps build the expression, and
[Cron Next Runs](/tools/cron-next-runs/) helps check when it will actually run.

## The simple idea

Cron runs commands on a schedule.

A crontab line usually looks like this:

```text
<schedule> <command>
```

Example:

```cron
0 2 * * * /usr/local/bin/backup.sh
```

Plain meaning:

> Run `/usr/local/bin/backup.sh` every day at 02:00.

## The five cron fields

The schedule has five fields:

```text
minute hour day-of-month month day-of-week
```

So this:

```text
0 2 * * *
```

means:

```text
minute:       0
hour:         2
day of month: every
month:        every
day of week:  every
```

In plain English:

> Run at 02:00 every day.

## Field 1: minute

The first field is minute, from `0` to `59`.

Example:

```text
15 * * * *
```

Plain meaning:

> Run at minute 15 of every hour.

That means 00:15, 01:15, 02:15, and so on.

## Field 2: hour

The second field is hour, from `0` to `23`.

Example:

```text
0 9 * * *
```

Plain meaning:

> Run every day at 09:00.

Cron normally uses 24-hour time.

## Field 3: day of month

The third field is the day number in the month.

Example:

```text
0 9 1 * *
```

Plain meaning:

> Run at 09:00 on the 1st day of every month.

## Field 4: month

The fourth field is the month.

Example:

```text
0 9 1 1 *
```

Plain meaning:

> Run at 09:00 on January 1st.

## Field 5: day of week

The fifth field is day of week.

Depending on the cron implementation, Sunday may be `0` or `7`. This is why I like
checking with a tool instead of relying only on memory.

Example:

```text
0 9 * * 1
```

Plain meaning:

> Run at 09:00 every Monday.

## Common symbols

Cron uses a few symbols:

| Symbol | Meaning |
| --- | --- |
| `*` | every value |
| `,` | list of values |
| `-` | range |
| `/` | step |

Examples:

```text
*/5 * * * *
```

Every 5 minutes.

```text
0 9,17 * * *
```

At 09:00 and 17:00 every day.

```text
0 9 * * 1-5
```

At 09:00 Monday through Friday.

## Step 1: describe the schedule in human words

Before writing cron, I write the sentence first.

Example:

```text
Run every day at 2 AM.
```

Then I turn it into cron:

```text
0 2 * * *
```

This prevents me from starting with symbols before I know what I want.

## Step 2: build the expression

Open [Crontab Generator](/tools/crontab-generator/) and choose the schedule parts.

For a daily 2 AM job:

- minute: `0`;
- hour: `2`;
- day of month: every;
- month: every;
- day of week: every.

The result is:

```text
0 2 * * *
```

## Step 3: check the next run times

Before installing a job, open [Cron Next Runs](/tools/cron-next-runs/) and paste the
expression.

Check the next few run times. This catches mistakes like:

- running every minute instead of every hour;
- running at midnight instead of noon;
- using the wrong weekday;
- forgetting timezone assumptions.

If the next run list looks wrong, fix the expression before it reaches the server.

## Step 4: add the command

A full crontab line includes the command:

```cron
0 2 * * * /usr/local/bin/backup.sh
```

Use absolute paths where possible. Cron does not always have the same environment as
your interactive shell.

This can fail in cron:

```cron
0 2 * * * backup.sh
```

This is clearer:

```cron
0 2 * * * /usr/local/bin/backup.sh
```

## Step 5: redirect output if needed

Cron may email output depending on the system. For scripts, I usually log output
intentionally:

```cron
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
```

Plain meaning:

- normal output goes to `/var/log/backup.log`;
- error output goes there too.

This makes failures easier to debug later.

## Step 6: remember the environment is smaller

Cron jobs often fail because environment variables are missing.

Your terminal may know:

```text
PATH
HOME
DATABASE_URL
NODE_ENV
```

Cron may not.

If a script depends on environment variables, define them in the script, load an env
file, or configure them explicitly in the crontab.

## My cron checklist

Before I save a cron job, I check:

1. Can I describe the schedule in plain English?
2. Did I build the expression from that sentence?
3. Did I check the next run times?
4. Is the command using absolute paths?
5. Does the script work when run manually?
6. Does the job need environment variables?
7. Where will output and errors go?
8. What timezone does the server use?

Cron is reliable when the schedule is clear. The hard part is making sure the five
fields say what I think they say.
