Cron Jobs & Webhooks
Cron jobs schedule recurring agent runs on LangGraph Platform — the critical design choice is thread-bound (state accumulates across runs) vs stateless (fresh each time, requires cleanup). Webhooks notify your systems when runs complete. This article covers correct API usage, timezone handling, failure modes, and monitoring — the production gaps that documentation does not warn you about.
Quick Reference
- →Thread-bound crons use client.crons.create_for_thread(thread_id, assistant_id, ...) — a separate method from create()
- →Stateless crons use client.crons.create(assistant_id, schedule=..., on_run_completed='delete')
- →on_run_completed accepts 'delete' (not 'delete_thread') and 'keep'
- →All cron schedules default to UTC — set the timezone parameter explicitly
- →Webhooks fire on run completion (success or error) — there is no separate stream or cron webhook type
- →Webhook config in langgraph.json uses webhooks.headers and webhooks.url (not custom_headers / url_restrictions)
- →The most common production failure: cron interval shorter than agent run time — runs queue up indefinitely
When (and When Not) to Schedule Agent Runs
If a run is triggered by an external event (new file uploaded, Slack message received, database row inserted), use a webhook trigger or API call instead. Crons are for time-based schedules. Using a cron to poll for events adds latency and wastes runs when nothing has changed.
| Trigger pattern | Use | Example |
|---|---|---|
| Fixed schedule | Cron job | Daily report at 9 AM, hourly health check |
| External event | Webhook trigger → API call | Process file on S3 upload, react to Stripe webhook |
| User-initiated | Direct API call | "Run analysis" button in your UI |
| After another run completes | Webhook on run → trigger next run | Post-processing pipeline |
Once you know a cron is right, the next choice is thread-bound vs stateless. This shapes your data model, your token costs, and your cleanup strategy.
Thread-bound reuses one thread (state accumulates); stateless creates and deletes a thread per run
Start with stateless crons. Only switch to thread-bound when you genuinely need the agent to reference previous runs. Thread-bound crons accumulate state indefinitely — after 90 daily runs, you have 90 days of conversation history being passed on every execution, which means growing input token costs and eventual context window overflow.