Skip to main content

Hands-on with Claude Code's /loop Feature

TL;DR


Background

Claude Code’s /loop feature is rolling out gradually. It became available on my account, so I gave it a spin.


1. /loop basics

Syntax

/loop [interval] <prompt>

If you omit the interval, the default is 10 minutes.

Three ways to specify the interval

# Pattern 1: interval at the start
/loop 5m check git status

# Pattern 2: trailing "every" at the end
/loop check the deploy status every 20m

# Pattern 3: no interval (defaults to 10 minutes)
/loop check the test results

Allowed units are s (seconds), m (minutes), h (hours), and d (days). Cron’s minimum granularity is one minute, though, so seconds get rounded up.

What happens under the hood

When you run /loop, three tools fire behind the scenes:

ToolRole
CronCreateCreate a job
CronListList jobs
CronDeleteDelete a job

You don’t actually need to know these tool names — natural language is enough.

"Any jobs running right now?"  → calls CronList
"Stop the loop."               → calls CronDelete

This part of the experience is genuinely good. The fact that you can manage jobs in natural language alone makes it worth trying.


2. Practical use cases

Use case 1: Periodic API endpoint checks

Periodically poll an external API and have Claude report any changes from the previous run.

/loop 5m check https://api.example.com/v1/status and report any change since last time

Good fit for status monitoring or detecting changes in response payloads — anything along the lines of a simple API check.

Use case 2: GitHub issue monitoring

/loop 5m run `gh issue list --label "bug"` to check for new issues,
and if any show up, analyze them and propose a response plan

This pairs well with issue-driven dev flows. You could imagine, for example, automatically analyzing a new issue and spinning up a branch for it.


3. Auto-compact and interval design

Things to be aware of

When you run information-gathering jobs through /loop, results pile up in context with each iteration. Claude Code runs auto-compact when the conversation history gets long, summarizing and compressing older content (you can also trigger it manually with /compact).

Auto-compact happens during normal Claude Code use too, but combining it with /loop introduces a few quirks:

Information-gathering jobs in particular consume a lot of context, so running them at short intervals tends to trigger auto-compact frequently. I don’t think /loop is meant for super-precise timing anyway, but it’s worth knowing when you design intervals.

Interval guidelines

Use caseSuggested intervalReason
Lightweight checks (e.g. git fetch)3–5 minLow context consumption
API response monitoring5–10 minDepends on response size
Test runs10–30 minLong execution time and large output

When tuning intervals, think not just about “how often do I want to check,” but also “how much context does each check consume.”

You can also tell the prompt to “if there’s no change, just say ‘no change’” to keep context consumption down.

/loop 5m check the site, and if nothing changed just say "no change"

4. Combining with Hooks

Problem: cron triggers and manual input look identical

Wanting to combine Hooks with /loop so that “only cron-triggered runs trigger a specific action” is a natural thought. But right now, the UserPromptSubmit event payload has no field indicating the trigger source.

{
  "session_id": "abc123",
  "hook_event_name": "UserPromptSubmit",
  "prompt": "the submitted text"
  // no field like trigger_source
}

The Hook can’t tell whether cron fired automatically or whether the user typed something in by hand.

Workaround: prefix convention

You can probably distinguish them by prefixing the prompt.

/loop 5m [CRON] run git fetch and analyze any new issues

The Hook then branches on the presence of [CRON].

# check_cron.py
import json, sys

data = json.load(sys.stdin)
prompt = data.get("prompt", "")

if "[CRON]" in prompt:
    # handle cron-triggered case
    print("Cron-triggered prompt detected", file=sys.stderr)
else:
    # handle manual input case
    pass

Until an official trigger-source field shows up, this kind of workaround seems to be how you handle it.


5. Constraints and where it fits

/loop constraints

ConstraintDetail
Session-boundClosing the session (terminal) stops every job
3-day expiryJobs are auto-deleted 3 days after creation
Approval promptsDestructive operations like git push still surface a confirmation dialog
Interval precisionCron-based, minimum 1-minute granularity, plus runtime delay
Concurrent limitUp to 50 jobs per session

How it compares to GitHub Actions and friends

Given those constraints, /loop feels best suited to lightweight, ephemeral automation.

Use case/loopGitHub Actions / traditional cron
Watch a situation for a few hoursGood fitOverkill
Monitor a PR through to mergeGood fitSetup overhead
Continuous production monitoringBad fitThe right tool
Automation shared across the teamBad fitThe right tool

For one-off automation needs inside my personal dev flow, the appeal is being able to wrap things up without standing up an external CI/CD pipeline.


Summary

What I like about /loop

Even just messing around for a bit, the convenience of “spinning up a quick automation in seconds” was real. Designing intervals together with context consumption seems to be the right mindset.


References

ZSL
ZSL

AI Engineer

Researching and practicing development workflows powered by Generative AI.