Rolling windows and concurrency
Rolling windows
Section titled “Rolling windows”A minute, hour or day limit resets at the UTC boundary by default —
so 100 calls at 23:59 and 100 more at 00:01 are both allowed. Set
rolling: true and the limit counts the last 60 seconds, 60 minutes or
24 hours at the moment of each check instead: no burst at the boundary.
curl -X POST https://api.limitry.com/v1/limits \ -H "Authorization: Bearer $LIMITRY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Calls in any 24 hours","subjectKind":"user","action":"call", "amount":100,"window":"day","rolling":true}'Use is counted in 60 slices of the window (a second for a minute, a
minute for an hour, 24 minutes for a day), and the oldest slice counts
whole — so a rolling limit never allows more than its amount, and may
refuse at most one slice early. In a check’s answer, resetsAt (and
retryAfterSeconds on a denial) is when enough use leaves the window.
month, total and concurrent limits cannot be rolling. In the app:
Window → In any 60 seconds / 60 minutes / 24 hours.
Concurrency
Section titled “Concurrency”A limit with window concurrent caps work in flight: amount is how
many at once. Each reservation takes one slot —
whatever its cost, which still counts against the subject’s other
limits — and gives it back when it is committed, released or expires.
# At most 3 exports at once per usercurl -X POST https://api.limitry.com/v1/limits ... \ -d '{"name":"Exports at once","subjectKind":"user","action":"export", "amount":3,"window":"concurrent"}'
# Start one: a reservation holds the slotcurl -X POST https://api.limitry.com/v1/checks ... \ -d '{"subject":{"kind":"user","id":"u_42"},"action":"export","mode":"reserve"}'
# Finished (or failed): give it backcurl -X POST https://api.limitry.com/v1/reservations/$ID/release ...- A
consumeorpreviewcheck against a concurrent limit is allowed while a slot is free but takes none — instant work holds nothing. - When every slot is held,
retryAfterSecondsis when the earliest hold expires (a release can free one sooner). - Always settle in a
finally: an unsettled hold keeps its slot until it expires.
Long-running work
Section titled “Long-running work”A hold lasts ttlSeconds (default 300, at most 3,600). For work that runs
longer, extend it as a heartbeat:
curl -X POST https://api.limitry.com/v1/reservations/$ID/extend ... \ -d '{"ttlSeconds":600}'If your worker dies, it stops extending and the slot frees itself.
A limit cannot change to or from concurrent (one counts use, the
other open holds) — create a new limit instead.
In reports
Section titled “In reports”Rolling limits report like others; the Usage page’s “Right now” shows the
last window, to the hour. For a concurrent limit the chart shows the work
it let start each day, and “Right now” the slots each subject holds —
among subjects checked in the last hour. limit.exceeded fires at most
once an hour per subject for both.