Rate limits
Runnev enforces two independent limits: a request rate and a publish throughput. Both are reported on every response so you can pace yourself before you are throttled.
The limits
| Key type | Request rate | Publish throughput | Scope |
|---|---|---|---|
Live (rnv_live_) | 1000 req / min | 60 MiB / min | Per project |
Test (rnv_test_) | 120 req / min | 6 MiB / min | Per project |
| Public demo key | 60 req / min | subscribe only | Per IP |
Both limits are token buckets that refill continuously, so a short burst above the per-minute figure is fine as long as the average stays under it.
The headers
Every response reports the request-rate bucket:
x-ratelimit-limit: 1000
x-ratelimit-remaining: 998
x-ratelimit-reset: 1785931200x-ratelimit-reset is the Unix time at which the bucket is expected to be
full again. When you are throttled, a 429 adds retry-after:
retry-after: 2
x-ratelimit-limit: 1000
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785931200How the bucket refills
A live key gets 1000 tokens and refills at 1000 / 60 ≈ 16.7 tokens per second.
Each request costs one token. If you spend all 1000 in the first second, you then get
one request roughly every 60 ms until you stop hammering it. Worked example: send
1000 requests instantly, and the 1001st is rejected with
retry-after: 1; wait one second and about 16 tokens are available again.
Subscriptions and the request budget
A subscription costs one request at connect time and nothing
thereafter. Holding it open, however long, does not drain the bucket. This is a
deliberate design choice: the product is built for connections that live for hours, so
charging them per-second against a rate limit would make no sense. Only the initial
GET counts.
Recommended client backoff
On 429, honour retry-after if present. Otherwise, and on
5xx, back off exponentially with full jitter:
base, cap = 0.2, 20.0 # seconds
delay = min(cap, base * (2 ** attempt))
sleep = random.uniform(0, delay) # full jitter: pick anywhere in [0, delay]Full jitter (a uniform pick in [0, delay]) spreads a thundering herd far
better than a fixed exponential schedule, where every client retries at the same
instant. All three SDKs implement this.
Staying under the limit
The request-rate limit counts requests, not events, so batching is how you move more data without hitting it. At the 1000 req/min live limit, one event per request caps you near 16 events/s; a hundred events per request lifts that to about 1,600 events/s under the very same limit. The binding constraint then becomes the 60 MiB/min throughput limit, which counts publish bytes. See Batching for throughput for the sizing trade-off.