Skip to content

getting started

Quickstart

Monitor your first cron job in five minutes. You’ll create a monitor, add one line to your job, and watch the first ping arrive.

  1. From the dashboard, click New monitor. Set the period to how often your job runs and add a grace window for normal jitter — a job scheduled every hour that usually takes two minutes wants a period of 1h and a grace of a few minutes, not zero.

    Each monitor gets its own ping URL. The token in it is the monitor’s identity, so treat it like a credential:

    # your monitor's unique ping URL
    https://ping.deadpost.dev/00000000-0000-7000-8000-000000000001
  2. Append a request to the end of your job. If the job succeeds, the ping is sent; if it fails, the shell short-circuits and no ping goes out — which is exactly the signal deadpost is watching for.

    0 9 * * * pg_dump prod | gzip > backup.sql.gz && curl -fsS https://ping.deadpost.dev/00000000-0000-7000-8000-000000000001
  3. The monitor flips from pending to healthy the moment the first ping lands. From then on the clock is running: if a ping doesn’t arrive within the period plus its grace window, the monitor goes late, and then down.

You are not alerted when something breaks loudly. You are alerted when something stops happening quietly.

curl can say “I finished”. It can’t say how long the job took, that it failed and why, or how many rows it processed — and it can’t buffer a ping through a network blip. That is what the SDKs add:

import deadpost
# The simple case: "my job ran and succeeded".
rotate_logs()
deadpost.ping()
# Bracket the work instead, and you also get its duration — plus the
# difference between "not started yet" and "started an hour ago and
# never came back".
with deadpost.run() as run:
rows, size = dump_database()
# Tag the numbers that describe the work, not just that it happened:
# a backup that exits 0 having written 2 MB is green everywhere else.
run.tag(rows=rows, bytes=size)
# An exception reports /fail — forcing the monitor down immediately
# rather than waiting out its grace period — and is re-raised unchanged.
with deadpost.run("nightly-etl", env="prod") as run:
run.tag(rows=export_to_warehouse())