Skip to main content
MindStudio
Pricing
Blog About
My Workspace

How to Use Claude Code Cron Jobs to Run Agents on a Schedule

Claude Code's cron_create, cron_list, and cron_delete tools let you schedule recurring agent tasks. Learn how loops, jitter, and session scoping work.

MindStudio Team RSS
How to Use Claude Code Cron Jobs to Run Agents on a Schedule

What Claude Code Cron Jobs Actually Do

Scheduling agents to run on a recurring basis used to require standing up infrastructure — cron daemons, Lambda functions with EventBridge triggers, or a task queue with a scheduler bolted on. Claude Code changes that by baking scheduling directly into the agent runtime itself.

Claude Code cron jobs let you tell an agent to run a task every hour, every morning, or on any custom schedule — without external infrastructure. The three tools that make this work are cron_create, cron_list, and cron_delete. Understanding how they interact, how session scoping affects state, and how jitter prevents thundering-herd problems will save you a lot of debugging time when you start building scheduled agent workflows.

This guide covers all of it in practical detail.


The Three Core Cron Tools

Claude Code exposes scheduling through three purpose-built tools. Each one is narrow in scope, which makes them easy to reason about.

cron_create

cron_create registers a new scheduled task. You give it a schedule expression, a description of what the agent should do when triggered, and optionally some configuration for how the run should behave.

A basic call looks like this:

cron_create({
  schedule: "0 9 * * 1-5",
  task: "Check the GitHub repo for new issues opened since yesterday and post a summary to the #dev Slack channel",
  label: "daily-issue-digest"
})

One coffee. One working app.

You bring the idea. Remy manages the project.

WHILE YOU WERE AWAY
Designed the data model
Picked an auth scheme — sessions + RBAC
Wired up Stripe checkout
Deployed to production
Live at yourapp.msagent.ai

The schedule field follows standard cron syntax: five space-separated fields for minute, hour, day-of-month, month, and day-of-week. If you’re not fluent in cron expressions, tools like crontab.guru make it easy to verify a schedule before committing.

The task field is a natural-language description of what the agent should do. Claude Code interprets this at runtime — it’s not a script or a function reference. That means the same scheduling mechanism works for any task you’d normally describe to the agent in an interactive session.

The label field is optional but worth including. It gives the scheduled job a human-readable identifier that makes it easier to manage later.

cron_list

cron_list returns all active scheduled jobs in the current session scope. The output includes each job’s label, schedule expression, task description, and a system-assigned ID.

cron_list()

The response is a JSON array of job objects. This is most useful for:

  • Auditing what’s scheduled before adding a new job
  • Retrieving IDs you need to pass to cron_delete
  • Debugging unexpected behavior by confirming the schedule expression is what you intended

There’s no filtering built into cron_list — it returns everything. If you have dozens of jobs, you’ll need to filter the output yourself.

cron_delete

cron_delete removes a scheduled job by its ID. Pass the ID returned by cron_list or stored from a cron_create call.

cron_delete({ id: "job_abc123" })

The deletion is immediate. If a job is mid-execution when you delete it, the current run completes but no future runs are scheduled.

There’s no soft-delete or pause mechanism — if you want to temporarily disable a job, you delete it and re-create it later. Keep your cron_create calls somewhere reproducible (a setup script, a Markdown doc, a workflow config) so you’re not reconstructing schedules from memory.


Understanding Cron Syntax for Agent Schedules

Standard cron expressions work well for most scheduling needs. Here’s a quick reference for common patterns:

ScheduleExpression
Every minute* * * * *
Every 15 minutes*/15 * * * *
Every hour0 * * * *
Daily at 9 AM0 9 * * *
Weekdays at 8 AM0 8 * * 1-5
Weekly on Monday0 0 * * 1
First day of month0 0 1 * *

A few things worth knowing about how Claude Code interprets these:

Time zone matters. Claude Code evaluates schedules in UTC by default unless the runtime environment is configured otherwise. If you’re scheduling a morning digest for a US-based team, 0 9 * * 1-5 will fire at 9 AM UTC — which is 4 AM or 5 AM in US Eastern time. Adjust your expression to the UTC equivalent of your intended local time.

Seconds are not part of the expression. Standard cron doesn’t support sub-minute granularity. If you need something to run every 30 seconds, you’ll need a loop inside the agent rather than a cron expression (more on that below).

Non-standard extensions may not be supported. Some cron implementations support @hourly, @daily, @weekly shortcuts or step values like */5. Stick to standard five-field expressions for maximum compatibility.


How Loops Work Inside Scheduled Agents

Hire a contractor. Not another power tool.

Cursor, Bolt, Lovable, v0 are tools. You still run the project.
With Remy, the project runs itself.

When a scheduled job fires, Claude Code starts a new agent run and executes the task. That run is self-contained — but sometimes you want the agent to do something repeatedly within a single run, not just once per trigger.

This is where loops come in.

Polling Loops

A polling loop is when an agent checks for a condition repeatedly until it’s met, then takes action. For example:

  • Check if a build has completed every 30 seconds, then notify Slack when it finishes
  • Monitor an API endpoint for a status change, then write results to a database

In Claude Code, you implement this in the task description itself. You can instruct the agent to check a condition, wait, and check again. The agent maintains context across these internal iterations within a single run.

The practical limit on polling loops is the maximum run duration of the session. Long-running polls (anything measured in hours) are better handled by scheduling a short-polling job with cron_create at a frequent interval rather than keeping a single run alive indefinitely.

Batching Loops

Some tasks involve processing a list — ingesting new records, reviewing files, sending notifications to multiple recipients. The agent loops through the list as part of the task execution.

The key consideration here is idempotency. If the agent is scheduled to run every hour and process “new” records, it needs a way to distinguish what’s actually new from what it already handled. This usually means writing a cursor or timestamp somewhere the agent can read it next time — a file, a database row, or an environment variable.

Design your scheduled tasks with the assumption that runs will overlap or repeat unexpectedly. Idempotent task descriptions (“process records created since the last run timestamp stored in /tmp/last-run”) are more resilient than naive ones (“process all unprocessed records”).


What Jitter Is and Why Your Schedules Need It

Jitter means adding a small, random delay before a scheduled job actually starts.

If you have 50 agents all scheduled to run at 0 * * * *, they all try to start at exactly the top of the hour. If those agents all call the same downstream API, you’ve just created a self-inflicted spike. Databases, rate-limited APIs, and external services all have capacity limits. Simultaneous scheduled runs overwhelm them in ways that staggered runs don’t.

How Jitter Works in Practice

Claude Code’s cron implementation supports a jitter parameter on cron_create. You specify a maximum jitter window in seconds:

cron_create({
  schedule: "0 * * * *",
  task: "Sync new CRM records to the data warehouse",
  label: "hourly-crm-sync",
  jitter: 300
})

With jitter: 300, the job fires at a random point within 5 minutes after the scheduled time. If you have 10 agents with this configuration, they spread across a 5-minute window instead of all firing simultaneously.

The tradeoff is timing precision. If your task is time-sensitive (it has to run at exactly 9:00 AM), jitter is a problem. If your task is just “run roughly every hour,” jitter improves reliability without meaningful cost.

When to Use Jitter

Use jitter when:

  • Multiple scheduled agents share downstream resources (APIs, databases, queues)
  • Your schedule has many agents on the same expression
  • You’re calling APIs with rate limits
  • Exact timing isn’t required by the task

Other agents start typing. Remy starts asking.

YOU SAID "Build me a sales CRM."
01 DESIGN Should it feel like Linear, or Salesforce?
02 UX How do reps move deals — drag, or dropdown?
03 ARCH Single team, or multi-org with permissions?

Scoping, trade-offs, edge cases — the real work. Before a line of code.

Skip jitter when:

  • The task must run at a precise time (end-of-day reports, scheduled meetings, time-triggered notifications)
  • You’re the only agent hitting a resource
  • Downstream systems are not capacity-constrained

Session Scoping: What Carries Over Between Runs

Session scoping is one of the more confusing parts of Claude Code cron jobs. The short version: each scheduled run starts a new session. That means in-memory context from previous runs doesn’t persist.

What Doesn’t Persist

  • Conversation history from prior runs
  • Variables or objects created during a previous run
  • File handles or open connections
  • Any state stored only in the agent’s working memory

If your agent built a list of records during the 9 AM run, that list is gone by the 10 AM run. Each run is a cold start.

What Does Persist

  • Files written to the filesystem during a previous run
  • Database records written externally
  • Outputs committed to external systems (Slack messages, emails, API calls)
  • Environment variables set at the session level before the run starts

The practical implication: any state your agent needs to carry between runs must be externalized. Write it somewhere the next run can read it.

Designing for Stateless Runs

The cleanest way to build scheduled agents is to treat each run as stateless by design:

  1. Read current state from an external source at the start of each run (a file, a database, an API)
  2. Do work based on what you find
  3. Write updated state to that same external source at the end of the run

This pattern makes runs independent and debuggable. If a run fails, the next one starts fresh from the last committed state.

A simple example: an agent that processes new support tickets could read a last_processed_id from a JSON file, query for tickets with IDs above that value, process them, and write the new last_processed_id at the end. Each run is self-contained, and a failed run doesn’t corrupt the state.


Practical Use Cases for Scheduled Claude Agents

These are the kinds of tasks that work well as Claude Code cron jobs:

Daily digest generation — Aggregate information from multiple sources (GitHub issues, Slack threads, email, analytics dashboards), summarize it, and post or send it to the right people. Set it to run at 8 AM on weekdays and it’s off your plate entirely.

Automated code review checks — Schedule the agent to run after business hours, review pull requests opened during the day, flag anything that looks like it needs attention, and comment directly in GitHub.

Data pipeline monitoring — Check whether scheduled data jobs completed successfully, compare row counts or timestamps against expectations, and alert on anomalies.

Content scheduling — Draft posts, descriptions, or copy on a schedule, then queue them for human review or publish directly if auto-approval is configured.

Infrastructure hygiene — List unused resources, check for expiring certificates or credentials, audit access logs for anomalies. These are tasks people intend to do manually but rarely get to.

Everyone else built a construction worker.
We built the contractor.

🦺
CODING AGENT
Types the code you tell it to.
One file at a time.
🧠
CONTRACTOR · REMY
Runs the entire build.
UI, API, database, deploy.

Recurring report generation — Pull data, format it, and send it to stakeholders without anyone having to trigger it manually.

The common thread across all of these is that they’re repetitive, time-based, and well-defined enough for an agent to handle without supervision.


Running Scheduled Agents Without Writing Code: Where MindStudio Fits

Claude Code cron jobs are powerful, but they assume you’re working in a developer environment — you have Claude Code installed, you’re comfortable writing task descriptions in a terminal, and you’re managing session configuration directly.

For teams that want scheduled agent workflows without the infrastructure overhead, MindStudio takes a different approach.

MindStudio is a no-code platform for building and deploying AI agents. It includes native support for autonomous background agents that run on a schedule — built through a visual workflow editor, not a command line. You define what the agent should do using a drag-and-drop interface, configure a schedule, and MindStudio handles execution, retries, and logging.

What makes this relevant to the Claude Code cron job conversation is that the problems are the same: you want something to happen repeatedly, on time, without human intervention. MindStudio solves that problem with over 1,000 pre-built integrations (Slack, HubSpot, Google Workspace, Airtight, Salesforce, and more), so your scheduled agent can read from and write to the systems you already use without any API plumbing.

For developers who use Claude Code for agentic tasks but want to expose certain recurring workflows to non-technical teammates, MindStudio’s visual interface makes that handoff clean. The developer defines the workflow; the non-technical user runs or adjusts it without touching code.

You can try MindStudio free at mindstudio.ai.


Frequently Asked Questions

How do I delete all cron jobs at once in Claude Code?

There’s no bulk-delete command. You need to call cron_list to retrieve all active job IDs, then call cron_delete for each one. If you’re managing many jobs, it’s worth scripting this: capture the IDs from cron_list and iterate through them with cron_delete.

What happens if a scheduled Claude Code job is still running when the next one triggers?

By default, a new run starts even if the previous one hasn’t finished. This means two instances of the same job can run concurrently. If your task isn’t safe to run in parallel (for example, it writes to a shared file), you need to implement your own locking mechanism — typically by writing a lock file at the start and removing it at the end, with the task checking for the lock before proceeding.

Can Claude Code cron jobs persist across machine restarts?

No. Scheduled jobs are scoped to the session and the running Claude Code process. If the process stops — machine restart, terminal close, process kill — the scheduled jobs are gone. They don’t auto-recover. This is an important limitation for production-grade scheduling. For persistent, always-on scheduling, you need either a long-running server process managing the agent, or a platform that handles execution guarantees for you.

How granular can Claude Code cron schedules be?

Cursor
ChatGPT
Figma
Linear
GitHub
Vercel
Supabase
remy.msagent.ai

Seven tools to build an app. Or just Remy.

Editor, preview, AI agents, deploy — all in one tab. Nothing to install.

The minimum interval is one minute, since standard cron expressions don’t support sub-minute scheduling. If you need something to run every 10 seconds, you’ll need to implement a loop inside a single agent run rather than scheduling multiple runs at sub-minute intervals.

What’s the difference between jitter and simply staggering schedules manually?

Manual staggering means you explicitly schedule different agents at 0 9 * * *, 5 9 * * *, 10 9 * * *, and so on. Jitter lets you use the same schedule expression for all agents and let the runtime randomize the offsets. Jitter is better when you’re managing many agents or when the number of agents changes over time — you don’t have to manually reassign schedule expressions every time you add or remove an agent.

Do Claude Code cron jobs support environment variables or secrets?

Yes. Secrets and environment variables configured in the session environment are accessible to scheduled runs. The key point is that these need to be set at the session or process level before the cron jobs run — you can’t pass per-run environment configuration through cron_create directly.


Key Takeaways

  • Claude Code’s cron_create, cron_list, and cron_delete tools give agents native scheduling without external infrastructure.
  • cron_create takes a standard five-field cron expression, a natural-language task description, and an optional label and jitter window.
  • Each scheduled run is a new session — state doesn’t persist in memory. Externalize anything you need to carry between runs.
  • Jitter adds a random delay before a run starts, which prevents resource spikes when multiple agents share the same schedule.
  • Loops inside agent runs handle sub-minute polling or batch processing; recurring schedules handle everything else.
  • For teams that want scheduled agent workflows without a developer environment, MindStudio offers a no-code alternative with native scheduling, 1,000+ integrations, and visual workflow building.

Presented by MindStudio

No spam. Unsubscribe anytime.