# Cron and heartbeat monitor

A heartbeat monitor helps you track periodic tasks by expecting regular requests to a unique URL. 

If the expected heartbeat is not received within the specified frequency and grace period, it triggers an incident and alerts the configured on-call team. 

[info]
#### Getting started with heartbeats?  
Start with our [Introduction to cron job monitoring](https://betterstack.com/community/guides/monitoring/what-is-cron-monitoring/ ";_blank") or [Getting started with cron jobs guide](https://betterstack.com/community/guides/linux/cron-jobs-getting-started/ ";_blank").
[/info]

## Step-by-step setup

1. Go to **[Heartbeats](https://uptime.betterstack.com/team/0/heartbeats)** → **Create heartbeat**.
2. Name your heartbeat — e.g. "Daily database backup".
3. Set the **Expect a heartbeat every** field to match the frequency of your task.
4. Configure the **grace period**, which is the extra time allowed before an incident is raised if the heartbeat is missed.
5. Configure the **On-call escalation settings**.
6. Click **Save heartbeat**.
7. Copy the secret URL on the heartbeat detail page; you’ll need it in your script.

[note]
#### Heartbeat remains pending until the first request
The heartbeat remains in a "Pending" state until the first request is received. The monitoring period begins from the first heartbeat received, and incidents are only raised after the **expected frequency** and **grace period** have elapsed.
[/note]

## Setting up a CRON and a background job

In this example, we’re using the cron-job style syntax to schedule a periodic task. Cron allows you to define tasks based on time intervals such as minutes, hours, days, etc.

To monitor a daily database backup, set up a CRON task to execute your job every day at midnight:

```bash
[label CRON setup for daily database backup]
0 0 * * * ruby /home/deploy/backup_database.sh >/dev/null 2>&1
```

The CRON expression `0 0 * * *` means the job will run at midnight every day.

Then, include a `curl` request to the heartbeat URL in your backup script:

```bash
[label Example of a backup script with heartbeat notification]
#!/usr/bin/env bash
set -o errexit
set -o xtrace

date=`date "+%Y-%m-%d_%H:%M:%S"`
file="/dumps/uptime.betterstack.$date.dump"

time dokku postgres:export uptime > "$file"
aws s3 cp "$file" s3://uptime-dbbackups/
rm "$file"

# Notify the heartbeat URL
curl "https://uptime.betterstack.com/api/v1/heartbeat/<HEARTBEAT_TOKEN>"
```

## Reporting failures

You can explicitly report a failure by appending `/fail` to the heartbeat URL:

```bash
[label Reporting failure to heartbeat URL]
curl "https://uptime.betterstack.com/api/v1/heartbeat/<HEARTBEAT_TOKEN>/fail"
```

Additionally, you can include an exit code or output when reporting a failure. For example:

```bash
[label Reporting failure with output and exit code]
backup_output=$(./run-backups.sh 2>&1)
curl -d "$backup_output" \
  "https://uptime.betterstack.com/api/v1/heartbeat/<HEARTBEAT_TOKEN>/$?"
```

This sends both the exit code and the script output to help diagnose the failure.