Heartbeat monitoring

Know when a background job stops checking in

Cron jobs, workers, and backups fail in silence while the website stays up. Give each one a URL to call when it finishes. If the call is late or never comes, Acumen Logs tells you which.

No agent to install. Anything that can make an HTTP request can send a heartbeat.

Heartbeats
1 late · 1 missed
Nightly database backup
Every day at 02:00
On time
6h ago
Invoice run
Every hour
Late
+6 min
Order export
Every 15 minutes
Missed
32 min
Queue worker
Every 5 minutes
On time
1m ago
Each job pings its own URL when it finishes.
Setup

A URL, a ping, and a window

Nothing to install on the server. The monitor stays healthy for as long as the job keeps checking in.

01
Create the heartbeat

Name it after the job. You get a unique URL straight away, and a successful ping returns 200.

02
Call it when the work finishes

GET, POST, or HEAD, from cron, a worker, or any script. Put the call after the work, so a crash halfway through never sends it.

03
Set the window

Say how often a ping should arrive, how much grace to allow, and who hears about a miss.

Name
Nightly database backup
Expect a ping every
5 min
1 hour
1 day
Custom
Grace period
5 min
15 min
1 hour
Alert
Slack
Email
Teams
Create heartbeat

The pulse URL is ready as soon as you save.

The ping

One request, from whatever runs the job

The same URL works from a crontab, the Laravel scheduler, a Node worker, or a shell script.

Crontab
With metadata
# Back up at 02:00, then check in
0 2 * * * /opt/backup.sh && \
curl -fsS -X POST https://app.acumenlogs.com/heartbeat/7f3c-91ad-4e20/pulse

The && means the ping only goes out if the backup succeeded.

Send context with the ping
curl -fsS -X POST \
-H 'Content-Type: application/json' \
-d '{"duration_ms":42000,"rows":1204}' \
https://app.acumenlogs.com/heartbeat/7f3c-91ad-4e20/pulse

GET, POST, or HEAD

Send a body, headers, or query string when the job has something useful to say. A good ping answers 200.

Any language

Laravel, Node.js, Python, Ruby, shell, or anything else that speaks HTTP. No SDK and no open ports.

Guides for your stack

Step-by-step for the Laravel scheduler, AdonisJS, and Node.js.

Laravel guide →
On time, late, or missed

A late job and a missing job are not the same alert

You set the expected frequency and a grace period per heartbeat. The two states page different people for different reasons.

On time

Checked in inside the window

The job ran. The next ping is already expected, and nobody is notified.

Late

Overdue, still inside grace

The ping is late but the grace period has not run out. A queue delay, not an outage.

Missed

Grace ran out with no ping

The job never checked in. The alert includes the last successful ping.

Failure insights

The miss comes with the pings before it

Every check-in is logged. Metadata you sent with the ping, a duration or a row count, is there when you open the incident.

Order export
Check-ins
09:45
Missed

No ping within 15 min + 15 min grace. Alert sent to #ops.

09:30
Missed

Expected at 09:30. Nothing received.

09:15
On time

POST · 09:15:41 · 1,204 rows · 42s

09:00
Late

POST · 09:08:12, inside the grace period

08:45
On time

POST · 08:45:38 · 1,188 rows · 39s

This heartbeat
Missed
Expected every
15 minutes
Grace period
15 minutes
Last check-in
09:15:41
Last metadata
1,204 rows · 42s
Method
POST
Alerts
Slack #ops, email
Alerts

Hear about it while the job can still be rerun

Heartbeats use the same alert channels as the rest of your monitors.

Email
Slack
Microsoft Teams
Desktop
Webhooks
  • Separate alerts for a late check-in and a missed one.
  • Wait for a run of missed check-ins before escalating, so one slow job does not page anyone.
  • A webhook can open a PagerDuty incident or a Jira ticket.
Acumen Logs · #ops
Heartbeat missed: Order export

No check-in since 09:15. Expected every 15 minutes, with 15 minutes of grace.

Last ping: POST · 09:15:41 · 1,204 rows
What to watch

The work that fails without an error page

An uptime check never sees these. A heartbeat does, because the job has to say it finished.

Cron jobs

The nightly script that exits halfway and leaves last night's file in place.

Workers and daemons

A process that froze on a memory leak or an expired token, while the site still loads.

Backups and syncs

Database backups, imports, and search indexing that the rest of the product depends on.

Billing runs

Invoices, renewals, and payouts that have to happen on a schedule.

Pricing

10 heartbeats free. 100 for $5

Heartbeats are priced like uptime checks. They share one allowance with uptime, SSL, WHOIS, and RUM, so mix them however you need. No credit card to start.

Free

$0
forever
  • 10 checks, heartbeats included
  • Checks every 10 minutes
  • Email alerts
  • 1 status page
  • 3 days of history
Start free

Running a production app? Essentials at $39.99 a month comes with a 14-day trial.

See every plan →
Same dashboard

Jobs are one layer. Watch the rest from here too

A heartbeat sits in the same project as your uptime checks and user journeys.

Uptime monitoring

Every minute, from multiple regions, with alerts in seconds.

Uptime monitoring →

API monitoring

Chain the requests behind the job and check the data they return.

API monitoring →

Synthetic monitoring

Run login and checkout in a real browser, on a schedule.

Synthetic monitoring →

Status pages

Tell customers what is happening, updated from your monitors.

Status pages →

Test your site free.Monitor what matters.

Free results in seconds. No account, and no credit card.

FAQ

Frequently Asked Questions

What is a heartbeat?

A unique URL your job calls when it finishes. If the call does not arrive in time, the monitor is marked failed and you are alerted.

Do I need to install anything?

No. There is no agent or SDK. The job makes one HTTP request.

Which requests count?

GET, POST, and HEAD. You can send headers, a query string, or a JSON body, and a successful ping returns 200.

What is a grace period?

Extra time after the expected check-in before the job counts as missed. Set it per heartbeat, for jobs that sometimes run long.

Show all questions Show fewer questions

How is a late job different from a missing one?

Late means the ping is overdue but still inside the grace period. Missed means the grace period has passed with no ping. They alert separately.

Can I send details with the ping?

Yes. Put a duration, a row count, or anything else useful in the query string or JSON body. It is stored with that check-in.

How many heartbeats do I get?

They share the uptime allowance. Free includes 10 checks across heartbeats, uptime, SSL, WHOIS, and RUM. Solo raises that to 100 for $5 a month.

Heartbeat monitoring

Give the quiet jobs a way to say they finished

One URL, one request at the end of the job, and an alert the first time it goes quiet.