AI agent monitoring
Your agent reported success.
It produced nothing.
Scheduled agents fail quietly. A run that never fired, a loop that swallowed a tool error and exited 0, a model call that never returned. SteadyCron watches the outcome instead of the exit code, and tells you when a real result stops arriving.
No card. One agent monitor free, with every rule switched on.
What the run looked like
02:00 scheduled run started
02:04 process exited 0
02:04 ✓ marked successful
# out/digest.md → 0 bytes
# tokens spent: 84,300
# anyone alerted? no What you actually needed to know
02:00 /start run began
02:04 report: items=0
02:04 rule: empty_result → failed
→ #ops-slack nightly-digest failed
last good run: yesterday 02:03 The problem
For an unattended agent, silence looks like success
Agent frameworks are built to keep going. A tool call fails, the model apologises and moves on, the loop finishes cleanly with nothing written. The process exits 0 because the process ended — not because work happened.
Running unattended was the whole point, so nobody is reading the output. The scheduler will not report a dead schedule, the provider will not report an exhausted spend cap, and the agent will not report its own empty run.
The distinction that matters
An agent reporting all-clear with zero throughput isn't healthy — it's asymptomatic.
- Exit code 0 with no artifact — the most common agent failure, and the one every uptime check passes.
- The run never fired at all: a disabled workflow, a sleeping machine, a dropped schedule event.
- A model call without a timeout wedges the run for hours, and the next runs pile up behind it.
- Rate limits, an exhausted budget, or a rotated API key end tonight's run early — and tomorrow's too.
- A deprecated model ID or a reshaped response breaks parsing on the provider's timeline, not your deploy timeline.
Three failures worth paging for
Caught by a schedule expectation, not a stack trace
Tracing tools record what a run did. None of them can record a run that never happened — there is no trace to emit. That takes something watching from the outside, on a clock.
The run never happened
GitHub Actions disabled the workflow after 60 days of repo inactivity. Nobody noticed for three days, because a run that does not start produces no log, no error, and no trace.
Only an external schedule expectation catches an absence. This is the failure your observability stack structurally cannot see.
It ran, and produced nothing
The search tool failed, the model apologised, the loop completed. Four minutes of tokens spent and zero rows written — reported as a success, because the process ended without throwing.
Your run reports the count; the empty-result rule turns a zero into a failure and an alert. You do not have to remember to implement the check.
It hung on a model call
Many SDKs ship without a request timeout. One wedged connection and the run never finishes. The /start ping arrived; /success never did.
The start ping arrived on time, so this is not a missed schedule — it is a hung run, and we report it as one. Your trigger is fine; the agent is not.
Wire it up
Five lines, wherever your agent runs
Ping when the run starts, and ping success only after checking that the output exists. That second half is the whole trick — it is what turns an empty run into an alert.
# Anthropic runs the schedule — but a routine that gets skipped, or
# finishes with nothing, tells nobody. Connect SteadyCron's MCP server
# and the agent reports its own runs with a tool call.
MCP server: https://api.steadycron.com/mcp
Auth: Bearer <your SteadyCron API key>
# Then, in the routine's prompt:
Call report_run_start with jobKey "nightly-digest" before you begin.
This is required — report_run is refused if no run is open.
Do the work. Write the result to out/digest.md.
When you are done, count what you actually produced and call report_run
with that count. If you produced nothing, report 0 — do not omit the
field, and do not round up.
report_run { jobKey: "nightly-digest", itemsProduced: 42,
model: "claude-opus-5", tokensIn: 18400, tokensOut: 2100 }
# SteadyCron turns a 0 into a failed run and an alert. No curl to get
# wrong, and a tool call is far harder for the model to skip than a
# sentence in the prompt. Full walkthrough for each platform, plus the gotchas, in Monitoring scheduled AI agents.
The run report
One small JSON body, and what each field switches on
The recipes above post a handful of numbers when the run finishes. Every field is optional — a partly instrumented agent is still monitored — but each one turns something on, and nothing here asks you to compute a verdict yourself.
What you can send
- itemsProduced
- How many things the run actually made. Zero fails the run. This is the field the whole monitor kind exists for.
- model + tokensIn / tokensOut
- We price the run from a built-in model price table, so per-run cost arrives without you working it out.
- costUsd
- Already know the figure? Send it and we use yours instead of deriving one.
- steps / toolCalls
- Ceilings that catch a loop — the same tool called forty times while the run burns tokens without finishing.
- traceUrl
- The alert links straight to that run in Langfuse, LangSmith, or wherever you record spans.
- summary
- Attached to the alert your on-call actually reads. Send the raw error, not a paraphrase.
Spend you see before the invoice does
Every priced run rolls into a month-to-date total per monitor, and you can set a ceiling per run or across the month. A model we have no price for is recorded as unpriced rather than free: a total that quietly under-reports is worse than no total at all.
Leaving a field out is fine — a rule with nothing to read simply does not evaluate. Whatever you do send is kept verbatim alongside the parsed numbers, so when a count looks wrong you can see exactly what your agent reported.
Scope
A narrow question, answered reliably
SteadyCron is not an LLM tracing tool and does not pretend to be one. It watches the run, not the reasoning.
What this does
- Alerts when a scheduled run never happened — the one failure a trace cannot record.
- Alerts when a run finishes having produced nothing. We check the number your run reports, so this is not something you have to remember to implement.
- Alerts when a run costs more than your ceiling — per run, or across the month.
- Alerts when a run's step or tool-call count says it is looping.
- Alerts when a run starts and never finishes, against a run time you set.
- Tells a run that never started apart from one that started and hung — two clocks, two incidents, two different fixes.
- Prices each run from the tokens and model it reports, and totals the month per monitor.
- Flags a run that claimed success without sending the report it owes you, instead of taking the claim at face value.
- Keeps the exact JSON every run sent, for the moment a number looks wrong.
- Shapes the noise — grace periods, consecutive-failure thresholds, quiet hours, auto-resolve.
What it does not do
- Span-level traces of every model call and tool invocation.
- Prompt management, datasets, or LLM-as-judge evaluation.
- Scoring answer quality, or detecting hallucinations.
- Telling you why the model made a particular decision.
For those, use a tracing tool — Langfuse, LangSmith, and friends do it well. Put the trace URL in the ping payload and your alert links straight to the run. SteadyCron answers the questions they cannot: did it run, did it finish, did it produce anything, and what did it cost.
Where the data sits
Agent runs are the most sensitive logs you have
A backup script logs "complete". An agent run carries prompts, retrieved documents, tool arguments, and whatever customer data passed through the context window — and you are about to send a summary of it to a monitoring vendor.
SteadyCron runs on Hetzner servers in Germany, operated by a German legal entity, under a self-serve DPA you can read and sign without a sales call. You also choose what goes in the ping: attach a row count instead of the rows.
- Hetzner, Germany
- German legal entity
- Self-serve DPA
- Public sub-processor list
One platform, every scheduled job
HTTP Execution
Run your endpoints on schedule — retries, timeouts, and full run logs.
Heartbeat Monitoring
Watch jobs you run anywhere; get alerted the moment one goes silent.
AI Agent Monitoring
You're hereKnow when a scheduled agent skips a run — or finishes with nothing.
Cron as Code
Define every job, monitor, and alert in YAML or Terraform.
Point a monitor at tonight's run
Create an agent monitor, set the schedule your agent is meant to keep, and add the two pings. If tomorrow's result does not arrive, you will know before anyone asks.
- Free plan, no card
- 1 agent monitor free
- EU-hosted
- Paid from €10/mo