The first time I put a coding agent on a schedule, I did the obvious thing. I took a prompt that worked beautifully in an interactive session — "triage the failing tests on main and fix what's cheap" — and wired it to fire at 6am. It ran. It also force-pushed a half-finished rewrite of a flaky test, because in the interactive version I was the missing piece: sitting there, reading each diff, saying "no, not like that." The cron expression was correct. Everything downstream of it was wrong.
That failure taught me the actual lesson of unattended agents: the scheduling primitive is trivial. Five fields and a prompt. The hard part is designing a job that a memoryless process, with no human in the loop, can run and still produce something worth waking up to.
Two different things both called "scheduling"
Before the design, get the mechanics straight, because "schedule my agent" maps to two very different tools.
A session loop runs on your machine, inside an open conversation. In Claude Code that's /loop: it re-runs a prompt on an interval down to one minute, and it dies when the session ends or seven days pass, whichever comes first. It's for polling — babysitting a PR, watching a deploy finish, checking a long build. It needs your terminal open and your laptop awake.
A routine is a named, scheduled invocation that runs on managed cloud infrastructure. It doesn't care whether your machine is on, your terminal is open, or you're asleep. Each run starts from a fresh clone with no memory of the last one. The minimum interval is one hour; a cron expression asking for anything more frequent is rejected. Triggers can be a clock, an API call, or a repository event like a push or a new issue.
The distinction that matters:
|
Session loop (/loop) |
Cloud routine |
| Runs on |
Your machine |
Managed cloud |
| Needs machine on / session open |
Yes / Yes |
No / No |
| Local files |
Yes |
No — fresh clone |
| Minimum interval |
1 minute |
1 hour |
| Survives a restart |
Only on --resume |
Yes |
If the answer to "should this run while I'm not here?" is yes, you want a routine. The rest of this is about making that safe.
The memoryless run is the whole design constraint
Every routine run is amnesiac by design. New clone, empty context, no "as we discussed yesterday." That sounds like a limitation until you realize it's what makes the job reproducible — but it forces a discipline interactive work lets you skip.
The prompt is the entire job description. There is no follow-up turn to clarify what you meant, and — critically — no permission prompt mid-run, because there's nobody to answer it. An agent that stops to ask "shall I proceed?" at 3am simply stalls. So the prompt has to carry everything: what to look at, what counts as done, and what to produce.
Which means you need an output contract — a concrete definition of the artifact the run leaves behind — written before you ever pick a cron time.
Here is the single rule that turns a scary automation into a boring, useful one:
A scheduled agent's output should be a reviewable artifact — a pull request, a filed task, a posted summary — never an irreversible action.
The platform gives you scaffolding for this. By default a routine can only push to branches prefixed with claude/; it can't push to main or trigger a deploy without an explicit override. Leave that on. It converts "the agent changed production" into "the agent opened a PR I'll read over coffee." That gap is the entire safety margin.
The corollary is a ramp, not a leap. Run any new routine in read-only mode for a week — let it only post its findings to a channel or file a task — and read what it would have done. If a week of its proposals are things you'd have approved, enable writes. If they aren't, you just avoided merging a week of bad diffs.
A routine that earns its slot
Here's a dependency-hygiene routine that fits the shape. It runs before the workday, proposes, and never touches main:
# Weekday 6:40am — deliberately not :00 to dodge scheduling jitter
schedule: "40 6 * * 1-5"
model: claude-opus-4-8 # code reasoning; downshift to Haiku for lint-only jobs
repository: acme/api
connectors: [github] # narrowest scope; read-only token where possible
branch_prefix: claude/ # keep the default guardrail on
prompt: |
Review the lockfile for outdated direct dependencies.
- For safe patch/minor bumps with green tests: open ONE PR titled
"chore(deps): weekly bumps", grouped, with the changelog links in the body.
- For anything with a breaking change or a failing test: do NOT attempt it.
Open a GitHub issue describing the upgrade and why it needs a human.
If nothing is outdated, post a one-line "deps clean" summary and stop.
Every clause is load-bearing. The split between "open a PR" and "open an issue" is the output contract. The "do NOT attempt" line is there because an amnesiac agent will otherwise cheerfully burn an hour fighting a breaking change with no memory that it already failed. And the fallback — "post one line and stop" — means a quiet week produces a quiet, legible signal instead of nothing.
For the local /loop case, the same discipline lives in a .claude/loop.md that scopes the agent to reviewable work:
Check the release/next PR. If CI is red, pull the failing job log, diagnose,
and push a minimal fix to the PR branch. If review comments arrived, address
each and resolve the thread. If everything is green, say so in one line.
Cadence and model are your cost dial
Two levers set what a routine costs: how often it fires and which model runs it. A cheap, frequent check — "did any error rate cross threshold?" — belongs on a small fast model. A weekly reasoning job that reads diffs wants the stronger one. Match the model to the thinking, not to habit.
And know what not to schedule. Deterministic work that needs no judgment — formatting, codegen, a fixed lint — should be a plain script in CI, not an agent paying to re-derive the same answer. Exploratory, one-off work stays interactive, where you're there to steer. Routines are for recurring judgment calls with a clear artifact at the end.
The takeaway
Before you write a single cron field, run the exact prompt once by hand — in a throwaway clone, with your hands off the keyboard — and look at what it leaves behind. If that artifact isn't something you'd merge or act on without editing, no schedule will fix it; you'll just receive the same bad output on a timer. The question that decides whether an unattended workflow is worth building was never "what time?" It's "what does this produce, and who reads it in the morning?"
Sources: Run prompts on a schedule — Claude Code Docs, Claude Code Routines: The Complete Guide to Scheduled Cloud Agents, GitHub Copilot: Meet the new coding agent