Skip to content
Back to skills

Opus Ratelimit Fanout Retry On Sonnet Throttled Waves

ASecurity

When a large Workflow/Agent fan-out (dozens of parallel subagents on Opus) mass-fails with "Server is temporarily limiting requests (not your usage limit)" / HTTP 429 — most agents dying, a few that finished before the burst surviving — recover by re-running the SAME fan-out on Sonnet and throttled into sequential waves (not one wide burst). Use when: (1) a Workflow returns far fewer results than dispatched and the failures all read "Rate limited" / 429 with "not your usage limit"; (2) you la...

  • 3 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 6, 2026
ai-agentsawsapi

Works with

  • claude code
  • api

Security analysis

A100/100

Scanned September 6, 2026

npx -y skills add wan-huiyan/agent-traffic-control --skill opus-ratelimit-fanout-retry-on-sonnet-throttled-waves --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Opus Ratelimit Fanout Retry On Sonnet Throttled Waves?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Opus Ratelimit Fanout Retry On Sonnet Throttled Waves
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wan-huiyan-opus-ratelimit-fanout-retry-on-sonnet-throttled-wa/badge)](https://www.skillsdirectory.com/skills/wan-huiyan-opus-ratelimit-fanout-retry-on-sonnet-throttled-wa)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: opus-ratelimit-fanout-retry-on-sonnet-throttled-waves
description: |
  When a large Workflow/Agent fan-out (dozens of parallel subagents on Opus) mass-fails
  with "Server is temporarily limiting requests (not your usage limit)" / HTTP 429 — most
  agents dying, a few that finished before the burst surviving — recover by re-running the
  SAME fan-out on Sonnet and throttled into sequential waves (not one wide burst). Use when:
  (1) a Workflow returns far fewer results than dispatched and the failures all read
  "Rate limited" / 429 with "not your usage limit"; (2) you launched 20+ concurrent Opus
  subagents in one shot; (3) the task is well within Sonnet's range (triage, review,
  code-tracing, classification). Sonnet is a SEPARATE capacity pool, so it sidesteps the
  Opus-specific server throttle; the orchestrator/synthesis can stay on Opus.
author: Claude Code
version: 1.0.0
date: 2026-06-08
disable-model-invocation: true
---

# Opus rate-limit on a fan-out → retry on Sonnet, throttled into waves

## Problem
A wide parallel fan-out (Workflow `parallel()`/`pipeline()` or many concurrent `Agent`
calls) launched on **Opus** mass-fails with a server-side capacity throttle, not your
account quota. The whole fan-out collapses to a handful of results — only the agents that
happened to finish *before* the burst survive.

## Context / Trigger Conditions
- Failure string (one per dead agent): **`API Error: Server is temporarily limiting
  requests (not your usage limit) · Rate limited`** → HTTP **429**.
- The "(not your usage limit)" clause is the tell: this is **Anthropic-side Opus capacity
  throttling**, NOT your per-account rate limit. Waiting and retrying on Opus alone often
  re-hits it.
- You launched many subagents at once (one `parallel()` over 20–50 items, or a single
  message with dozens of `Agent` calls). The wider the simultaneous burst, the worse.
- Distinct from the empty-`StructuredOutput` loop (that's a *schema*-payload failure under
  the same storm — see the companion skill `workflow-schema-agents-empty-loop-under-ratelimit`).
  This skill is about the **mass-429 capacity** failure mode and the cheapest recovery.

## Solution
Two independent levers; apply both on the retry:

1. **Move the fan-out agents to Sonnet.** Set `model: 'sonnet'` on the `agent()` calls
   (Workflow) or `model: "sonnet"` on the `Agent` tool. Sonnet draws from a **separate
   capacity pool**, so it does not contend for the throttled Opus capacity. Keep the
   *orchestrator* and the final *synthesis/judge* on Opus — only the fan-out workers move.
   Triage / review / code-tracing / classification fan-outs are well within Sonnet's range.
2. **Throttle the burst into sequential waves.** Instead of one N-wide `parallel()`, loop
   in chunks of ~8 (parallel *within* a wave, barrier *between* waves). This spaces the
   request bursts so you never present 50 simultaneous requests again:

   ```js
   const CHUNK = 8
   const results = []
   for (let i = 0; i < ITEMS.length; i += CHUNK) {
     const slice = ITEMS.slice(i, i + CHUNK)
     log(`wave ${i/CHUNK+1}: ${slice.join(', ')}`)
     const r = await parallel(slice.map((it) => () =>
       agent(prompt(it), { model: 'sonnet', schema: SCHEMA })))
     results.push(...r)
   }
   ```

It trades wall-clock (waves run serially) for reliability. Re-running is cheap because a
Workflow with the same script + args returns cached results for the agents that already
succeeded — but a fresh run on Sonnet+waves is usually simpler than resuming.

## Verification
- The retry completes with **0 missing** (`ITEMS.filter(n => !results.some(r => r.number===n))`
  is empty), where the Opus burst returned only a few.
- Spot-check that the Sonnet outputs meet the bar — for triage/review they typically do; if
  a few items need deeper reasoning, re-run *just those* on Opus after the storm passes.

## Example (~50-issue triage fan-out)
First run: ~50 investigator agents in one `pipeline()` burst, all Opus → **nearly all died
with "Rate limited · 429 · not your usage limit"**; only a handful (that finished before the
storm) returned. Re-ran the identical fan-out with `model: 'sonnet'` in **waves of 8** →
**all ~50 completed, 0 missing**, and the adversarial-verify pass still flipped the couple of
dismissals it should. Final synthesis/cut-line stayed on Opus. Net cost of the
diagnosis+retry: minutes.

## Notes
- Don't just "wait and retry on Opus" — the capacity window can persist and you re-burn the
  burst. The model-swap is what actually dodges it.
- `parallel()` swallows a thrown thunk to `null` (never rejects), so a partial storm shows
  up as `null` holes, not an exception — always `.filter(Boolean)` and compare count to
  dispatched to detect it.
- If the agents are forced to emit a large required `StructuredOutput` schema, the storm
  also triggers the empty-args validation loop — drop to free-text return for the heaviest
  agents (see the companion skill `workflow-schema-agents-empty-loop-under-ratelimit`).
- Pair with the journal-recovery path (extract `{"type":"result"}` lines from
  `subagents/workflows/<run>/journal.jsonl`) when you'd rather salvage the survivors than
  re-run the whole fan-out.

## References
- Workflow tool docs — per-`agent()` model override (quality-patterns).
- Companion skill `workflow-schema-agents-empty-loop-under-ratelimit` (the schema-loop
  variant of the same storm).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.