Schedule the next Ideogram 4.5 batch wave from ratelimit-reset

Size each wave from ratelimit-remaining and wave_size_hint, and when the write bucket is empty sleep ratelimit-reset seconds. A pure function you can test.

4 min readSume
All posts

A batch of Ideogram 4.5 images runs into two ceilings. The request budget says how many POSTs fit in this minute; generation admission says how many jobs Sume will accept right now. The admission docs expose generation_limits.wave_size_hint, defined as max(1, floor(queue_capacity_remaining x 0.75)), and the rate limit headers expose ratelimit-remaining and ratelimit-reset.

Take the smallest of the two, submit that many, and when the answer is zero, sleep until the window resets.

The wave function

Read the headers from your last submit, since the headers describe the budget that request spent from, and a submit spends the write bucket.

def next_wave(headers: dict, wave_size_hint: int, pending: int):
    """Return (how many to submit now, seconds to wait before the next try)."""
    remaining = int(headers["ratelimit-remaining"])
    reset = int(headers["ratelimit-reset"])
    size = min(remaining, wave_size_hint, pending)
    return (size, 0) if size > 0 else (0, reset + 1)

print(next_wave({"ratelimit-remaining": "118", "ratelimit-reset": "41"}, 4, 40))  # (4, 0)
print(next_wave({"ratelimit-remaining": "0", "ratelimit-reset": "41"}, 4, 40))    # (0, 42)
print(next_wave({"ratelimit-remaining": "9", "ratelimit-reset": "41"}, 4, 2))     # (2, 0)

Headers used

Rate limit headers from the Sume authentication docs, read 2026-10-06
HeaderMeaningUsed for
ratelimit-remainingRequests left in the windowCap on this wave
ratelimit-resetSeconds until the window resetsSleep when remaining is 0
retry-afterSeconds to wait, sent on 429Overrides your schedule

Rules for the loop

  • A 429 names the exhausted budget in error.details.scope (read or write); only pause submits for a write scope.
  • 429 queue_full is a capacity answer, not a rate limit. The refused job releases its idempotency key, so replay the same key later.
  • Add one second past the reset so you do not land on the boundary.
  • Keep reading ratelimit-limit from responses instead of hard-coding a plan table.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume