DEV Community

Cover image for I built a paced Claude API queue in a single HTML file — 29 tests, 10 bugs found and fixed
Sean
Sean

Posted on

I built a paced Claude API queue in a single HTML file — 29 tests, 10 bugs found and fixed

The problem

Rate limits on bulk API work are painful. You
start processing a spreadsheet row by row, hit
a 429 after a few requests, wait, continue,
hit it again. You end up babysitting an API
for hours.

What I built

Claude Batch is a paced request queue in a
single HTML file. No build step, no npm install,
no server. Open it in a browser and it works.

Two input modes:

  • Type prompts (one line = one request)
  • Upload CSV/Excel and write a {ColumnName} template — one request per row, only the columns you reference get sent (typically 70–80% fewer tokens)

Set an interval (1–180s), press Start, walk
away. Exports as JSON, CSV, or plain text.

Engineering details

  • Retry with exponential backoff (2s, 4s, 8s, cap 20s)
  • Respects retry-after header — server guidance overrides calculated backoff
  • AbortController on every fetch — cancels the actual HTTP connection on Stop
  • 504 in the retryable set (gateway timeouts are transient)
  • sleepAbortable() polls isRunning every 100ms during backoff — Stop resolves immediately
  • 29 tests across 95 assertions in a jsdom harness that loads the actual index.html and drives real UI events

10 real bugs found and fixed

Every bug has a regression test:

  1. No retry on 429s — fixed with backoff logic
  2. Timer leak on repeated start/stop — fixed with tracked setInterval
  3. Stuck processing row after Stop — fixed with status reset sweep in stopRun()
  4. Clear All orphaning in-flight rows — fixed by disabling during run
  5. retry-after header ignored — now read and respected
  6. No AbortController on fetch — added
  7. 504 missing from retryable set — added
  8. Draggable state not synced with isRunning
  9. stopRun() only re-rendered conditionally
  10. Dead code currentRowTimer — removed

Links

Live: virerra.github.io/Claude-Batch
Source: github.com/Virerra/Claude-Batch
License: MIT

Top comments (0)