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 typeRequest ratePublish throughputScope
Live (rnv_live_)1000 req / min60 MiB / minPer project
Test (rnv_test_)120 req / min6 MiB / minPer project
Public demo key60 req / minsubscribe onlyPer 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:

response headers
x-ratelimit-limit: 1000
x-ratelimit-remaining: 998
x-ratelimit-reset: 1785931200

x-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:

429 Too Many Requests
retry-after: 2
x-ratelimit-limit: 1000
x-ratelimit-remaining: 0
x-ratelimit-reset: 1785931200

How 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:

backoff 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.