Parameter format, interval units, budget ceilings, default values, and cancellation methods for /loop loop execution.
/loop Enables Qoder CLI to repeatedly execute a prompt or slash command, either at a fixed interval (powered under the hood by the scheduled task system) or at a pace Qoder chooses for itself. This page explains its parameter format, interval conversion, budget ceilings, and cancellation methods. For a usage guide on loop execution, see Loop Tasks.
Usage
[interval](optional): Execution interval. Providing one selects fixed-interval mode; omitting one selects dynamic-pacing mode.[flags](optional): Persistence and budget ceilings, listed below.<prompt>(required): The prompt text or slash command to be executed repeatedly. Slash commands are passed through unchanged.
Modes
| Mode | Selected when | Mechanism |
|---|---|---|
| Fixed-interval | The input contains an interval | The interval is converted to a cron expression and registered as a scheduled task. |
| Dynamic-pacing | The input contains no interval | After each run Qoder schedules the next wake-up itself, with a delay clamped to [60, 3600] seconds. Not scheduling one ends the loop. |
/loopwith no arguments: if.qoder/loop.mdexists, Qoder loops over that task list in dynamic-pacing mode; otherwise the usage message is shown./loop 5m(interval but no prompt): the usage message is shown.- Flags only, with no prompt (e.g.
/loop --max-turns 3): Qoder runs a general project health check on each iteration, in dynamic-pacing mode.
Flags
| Flag | Value | Description |
|---|---|---|
--durable | — | Persist the task to disk so it survives restarts, with no automatic expiry. |
--durable <N>d | Days | Persist the task and expire it N days from now. |
--permanent, -p | — | Equivalent to --durable with no expiry. |
--max-turns <N> | Whole number | Stop the loop after N runs. |
--max-credits <N> | Number | Stop the loop once N credits have been spent in total. Decimals are allowed. |
- Both the space form (
--max-turns 6) and the=form (--max-turns=6) are accepted for the ceilings. - Flags may appear anywhere in the input. They are stripped before the interval is parsed, so
/loop --max-turns 5 10m check the deploystill reads10mas the interval instead of5. - If a flag is repeated, the first value wins and every copy is removed from the prompt.
--durableand--permanentapply to fixed-interval loops. A dynamic-pacing loop always lives in the current session.
Interval Units
An interval consists of a number and a unit suffix:
| Suffix | Unit | Description |
|---|---|---|
s | Seconds | Rounded up to the nearest minute (minimum granularity of 1 minute). |
m | Minutes | Every N minutes. |
h | Hours | Every N hours. |
d | Days | Every N days (triggers at midnight local time). |
The minimum granularity is 1 minute. Intervals in seconds are rounded up to ceil(N/60) minutes, and you will be notified of the rounding.
Parsing Rules
After the flags are removed, /loop parses the remaining input with the following priority:
- Leading token: If the first word matches
^\d+[smhd]$(e.g.,5m,2h), it is treated as the interval, and the rest as the prompt → fixed-interval mode. - Trailing every clause: Otherwise, if the input ends with
every <N><unit>orevery <N> <unit>(e.g.,every 20m,every 5 minutes), it is extracted as the interval and removed from the prompt → fixed-interval mode. This only matches wheneveryis followed by a time expression—check every PRdoes not contain an interval. - Otherwise: No interval is present, and the whole input is the prompt → dynamic-pacing mode.
Examples
Interval to cron Conversion
| Interval Pattern | cron Expression | Description |
|---|---|---|
Nm (N ≤ 59) | */N * * * * | Every N minutes |
Nm (N ≥ 60) | 0 */H * * * | Converted to hours (H = N/60, must be divisible by 24) |
Nh (N ≤ 23) | 0 */N * * * | Every N hours |
Nd | 0 0 */N * * | Every N days at midnight |
Ns | Treated as ceil(N/60)m | Minimum cron granularity is 1 minute |
7m would produce uneven intervals, 90m cannot be expressed in cron), the closest clean interval is selected, and you will be informed of the rounding result before the task is created.
Budget Ceilings
A ceiling is a limit to arrive at, not one to exceed: the loop stops as soon as usage reaches it. When both ceilings are set, whichever is reached first stops the loop; if both are reached at the same moment, the message reports the run ceiling.
| Ceiling | Counter | Checked | Accuracy |
|---|---|---|---|
--max-turns | Number of runs over the whole life of the task | Before each run | Exact—--max-turns 2 fires exactly twice. |
--max-credits | Credits spent in total | After a run has been metered | The final run may end slightly above the ceiling; a run in progress is never cut off. |
- Only positive values are accepted. The scheduling tools reject
0or a negative number instead of silently dropping it, and a non-positive value found in an existing task file is discarded, leaving the task with no ceiling. - Run counts are lifetime counts. Restarting Qoder CLI does not reset them.
- Reaching a ceiling is not the same as expiring. The task is removed and cannot be resumed; start a new loop to continue.
- When a ceiling is reached, both you and Qoder are notified—you see
Scheduled task <id> stopped: it used 2 of 2 turns.(orLoop stopped: it used 3 of 3 turns.in dynamic-pacing mode), and Qoder is told to report the stop rather than recreate the task.
Persisted fields
For a durable task, the ceilings and the usage are stored alongside the other fields in .qoder/scheduled_tasks.json:
| Field | Description |
|---|---|
fireCount | Lifetime number of runs, compared against maxTurns. |
creditsUsed | Credits spent in total. A missing value means the spend was never metered, which is not the same as zero. |
maxTurns | Run ceiling. Absent means no ceiling. |
maxCredits | Credit ceiling. Absent means no ceiling. |
Dynamic-pacing ceilings
In dynamic-pacing mode the ceiling and the usage are held in memory for the duration of the loop:
- Sticky: pass the flag on the
/loopthat starts the loop and it applies to every later wake-up. Later wake-ups that do not repeat it cannot remove the ceiling. - Reset on stop: stopping the loop clears both the ceiling and the usage, so the next
/loopstarts from zero rather than inheriting the previous loop's spend. - Reaching the ceiling cancels the pending wake-up, so the loop does not wake again.
Tool parameters
The same ceilings are available to Qoder when it schedules work itself, so you can also ask for them in natural language ("check it five times, then stop"):
| Tool | Parameters |
|---|---|
| Scheduled task creation | maxTurns, maxCredits — reported back in the confirmation as Stops after N turns or M credits. |
| Dynamic-pacing wake-up | maxTurns, maxCredits — sticky for the whole loop. |
Panel controls
In the /crontab panel:
- The
USAGEcolumn shows3/10 turns · 12.5/50 creditswhen ceilings are set,2 turns · 8.25 creditswhen they are not, and a dash in place of the amount spent when the spend was never metered (—/50 credits). A task that has never run and has no ceiling leaves the column empty. - The task detail page shows
Turns 3 / 10 (stops at the limit)andCredits 12.5 / 50 (stops at the limit). - Press
tto edit the run ceiling andbto edit the credit ceiling. An empty value clears the ceiling; a non-positive value is not accepted, andEsccancels.
Cancellation and Expiration
- Session-only recurring tasks are the default: they stop when the process exits.
- Recurring tasks automatically expire 7 days after creation, unless created with
--durable(no expiry) or--durable <N>d(custom expiry). - You can manually delete the corresponding scheduled task before expiration (request the Agent to delete it using natural language and provide the task ID, or delete it from the
/crontabpanel). - In dynamic-pacing mode, asking Qoder to stop ends the loop and cancels the pending wake-up.
- After creating a recurring task, the current prompt is executed immediately once, without waiting for the first cron trigger.
Next Steps
- /loop usage guide: Loop Tasks.
- Underlying mechanisms of scheduled tasks: Scheduled Task Reference.