# What is a "cron job expression"?

A cron expression is a compact way to describe how often a scheduled task should run. On Linux, cron expressions live in a crontab file; on Windows, Task Scheduler hides them behind a graphical interface. Same concept.

You'll encounter cron expressions whenever you [configure cron job monitoring](/docs/features/cron-job-monitoring) in Oh Dear, so let's break down how to read them.

## Finding your existing cron jobs

To see cron jobs on your Linux server, connect via SSH and run:

```bash
$ crontab -l
* * * * * php /var/www/artisan schedule:run
```

Each line represents one scheduled job. A couple of caveats:

- Every user on the server has their own crontab. `crontab -l` shows only the one for the user you're currently logged in as. For example, jobs running as `www-data` won't appear if you SSH in as `ubuntu`.
- System-wide cron jobs can also live in `/etc/cron.d/`, `/etc/cron.hourly/`, `/etc/cron.daily/`, `/etc/cron.weekly/`, and `/etc/cron.monthly/`.

## Reading the syntax

A cron expression has five fields that describe when to run, followed by the command to execute:

```
┌───────────── minute       (0 - 59)
│ ┌───────────── hour       (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month     (1 - 12)
│ │ │ │ ┌───────────── day of week  (0 - 6, Sunday to Saturday,
│ │ │ │ │                             7 is also Sunday on some systems)
│ │ │ │ │
* * * * * <command>
```

### Worked example

```
0 */4 * * * logrotate
```

Reading each field:

- **minute**: `0` — at minute 0
- **hour**: `*/4` — every hour that's divisible by 4 (00, 04, 08, 12, 16, 20)
- **day of month**: `*` — every day
- **month**: `*` — every month
- **day of week**: `*` — every day of the week

So `logrotate` runs every 4 hours, at the start of the hour (00:00, 04:00, 08:00, ...).

### The most common pattern

```
* * * * * <command>
```

Five asterisks means "every minute, every hour, every day". You'll see this a lot on Laravel apps that run `php artisan schedule:run` every minute.

## What about sub-minute schedules?

By default, crontab only supports running once per minute at most. There's no "every 30 seconds" in the spec.

The usual workarounds are:

- **Wrapper scripts** that run a command, `sleep` a few seconds, and run it again
- **Long-lived workers** (daemons, queue workers) that handle work as it arrives instead of being invoked on a schedule

For Oh Dear's cron monitoring, once per minute is the highest frequency we track.

## Using cron expressions in Oh Dear

When you monitor a scheduled task in Oh Dear, you can specify the frequency in two ways:

- **As minutes** (for simple intervals like "every 5 minutes")
- **As a cron expression** (for anything more complex)

Copy the five fields from your crontab, **without the command at the end**. So for this line:

```
30 */2 1 1 */2 /usr/local/bin/myscript.sh
```

...the cron expression is `30 */2 1 1 */2`.

That's it. Everything before the command gets pasted into Oh Dear, and we'll alert you whenever the expected execution doesn't come through.
