How monitoring works
A cron monitor watches a job that is supposed to run on a schedule: a nightly billing export, an hourly sync, a queue drain, a certificate renewal. Error tracking cannot see these. A job that throws sends you an exception, but a job that silently stopped being scheduled sends nothing at all, and silence looks identical to success.
Parsemend closes that gap with check-ins. Your job tells Parsemend when it starts and when it finishes, and Parsemend, knowing the schedule, notices when a run does not show up.
The model
your job ──check-in──▶ ingest ──▶ Monitor (one per slug)
│
├── check-in history
└── next expected at
│
sweep every minute ─┘
│
failure ──▶ Issue ──▶ alert rules, the agentThree objects, and it helps to keep them apart:
- Monitor — one per
monitor_slugper project. Holds the schedule, the current status, and when the next check-in is due. - Check-in — one row per run, keyed by
check_in_id. A run that reportsin_progressand thenokupdates the same row rather than creating two. - Issue — what a failure becomes. Not a separate alert stream.
Monitors are created by the SDK, never in the panel
There is no "New monitor" form. A monitor appears the first time a check-in arrives carrying its slug, and its schedule, margin, runtime budget and timezone all come from the monitor_config the SDK sends. The Monitors page is read-only throughout: list, detail, check-in history, nothing editable.
This is deliberate. The schedule lives next to the code that runs on it, so it cannot drift from what is actually scheduled. It has one consequence worth internalizing:
A check-in without a schedule cannot be missed
If your first check-in carries no monitor_config, the monitor is created with no schedule. Next expected stays empty, and the sweep that detects missed runs skips it forever. You will see check-in history and nothing else. Sending the schedule is not optional decoration, it is the whole detection mechanism.
The three failure modes
| Failure | What it means | How it is detected |
|---|---|---|
error | The run reported that it failed | Your job sent status: "error" |
missed | No check-in arrived when one was due | Sweep, once the margin has lapsed |
timeout | A run started and never reported finishing | Sweep, once max runtime has lapsed |
Only the first is something your job can report. The other two are the point of the feature: they are the failures that never arrive as a message, because whatever was supposed to send it is not running.
A background sweep runs every minute and checks for both.
error
Your job caught its own failure and said so. This raises an issue on the transition into error, not on every subsequent post. If a run genuinely retries and posts the same check_in_id with error twice, the second post updates the row without opening a second issue.
missed
Each monitor carries a next expected at. Once that time plus the check-in margin has passed with nothing arriving, the monitor flips to missed and an issue opens.
The sweep then advances next expected at from the missed slot, not from now. A job that is down for six hours on an hourly schedule produces six issue events, one per slot it missed, rather than an event per minute of downtime.
timeout
A check-in that reported in_progress and never reported anything terminal is a run that hung. Once its start time plus the max runtime has passed, the check-in is marked timeout, the monitor is marked timeout, and an issue opens.
Timeout detection only works for jobs that send an in_progress check-in. A job that only reports once, at the end, has no start time to measure against, so a hang shows up later as a missed instead. See schedules and timing.
Recovery
A successful check-in on a monitor that was in a bad state (error, missed or timeout) resolves whichever monitor issues are open for that slug: the error issue, the missed issue and the timeout issue alike.
You do not resolve monitor issues by hand, and you should not have to. If the job runs again, the issue closes. If it breaks again afterwards, the same issue reopens as a regression rather than piling up as a new one.
What a failure gets you
A monitor failure is an ordinary issue, created through the same pipeline an SDK error goes through. That means:
- Alert rules match it, including tag filters on
monitor_slug. - Resolve and regression tracking behave exactly as they do for crashes.
- The agent scans it like any other new issue.
The last one is the weakest of the three, and worth being honest about: the agent is good at a stack trace pointing into your code, and a missed check-in carries no stack trace. It knows the monitor stopped reporting. It does not know why your crontab entry disappeared. Treat monitor issues as a paging signal rather than something to hand to the agent.
Next
- Quickstart sends a first check-in.
- Schedules and timing covers the numbers that decide when something counts as late.
