Access keys and quota
How Arkiv meters reads, what a worker and a browser actually use, and how to keep both running.
Arkiv meters arkiv_query calls. Each costs the same whatever it returns (Arkiv-Cost: 100), and the
response says how much of the budget is used (Arkiv-Quota-Used-Percent).
| Who | Budget | When it runs out |
|---|---|---|
| Without a key | An anonymous budget per IP address | 429 {"error":"ANON_COST_LIMITED"}. Resets after a while (the window is not documented) |
With a key (X-API-KEY) | A monthly quota per key | 429 {"error":"QUOTA_EXCEEDED"}, with no reset time given |
Get a key at hub.arkiv.network. A key is a secret: never ship it to a browser.
What a worker uses
A worker reloads rules at most every 30 seconds (reloadMs) and re-reads a watched entity every 10
minutes unless it is within 10 minutes of its deadline (extensions and deletes arrive as events). Measured
with about 430 rules on the chain, firing included: about 10 queries a minute, roughly 14,000 a day.
- Give each long-running worker its own key, used by nothing else.
- Check
Arkiv-Quota-Used-Percentdaily:
curl -s -D - -o /dev/null -X POST -H 'content-type: application/json' -H "X-API-KEY: $ARKIV_ACCESS_KEY" \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' \
https://rpc.tiramisu.db-chain.testnet.arkiv.network | grep -i quota- When the key runs out, worker logs say so in one line: "Arkiv quota for this access key is used up".
- To size a worker on your own rules,
node spike/count-worker.mjs 420(in the repository) counts its calls by method for 7 minutes.
What a browser uses
One dashboard page load is about a dozen calls, five of them queries. Browsers read on their own anonymous budget, so normal visitors never hit a limit, but someone testing heavily from one network can.
The dashboard and the example apps handle it two ways:
- Reads use
http(url, { retryCount: 0 }), so a 429 fails in about a second instead of silently waiting minutes; the page shows a banner and retries every 30 seconds. - An optional read relay: a server function (
/api/rpcin the dashboard,/api/arkivin the examples) that forwards read methods only to Arkiv with a key added on the server. The browser tries Arkiv directly first and uses the relay only when it is rate-limited. Set the key as a server variable (ARKIV_ACCESS_KEY), never a publicVITE_orNEXT_PUBLIC_one.
Hangs that look like freezes
Through the SDK with default retries, an anonymous 429 does not raise an error: viem waits out
Retry-After. Every query in arkiv-triggers fails after 30 seconds with QueryTimeoutError instead,
naming the access key.