Rate Limits
Request rate limits and compute units per plan.
Plans
Monthly quotas are measured in Compute Units (CU), not raw requests. Simple calls like eth_blockNumber cost 1 CU; heavier calls like eth_getLogs cost more.
| Plan | CU/month | Rate limit |
|---|---|---|
| Public (no key) | — | 1 request / 10 s per IP · basic methods only |
| Free | 3,000,000 | 10 req/sec |
| Hacker | 22,500,000 | 50 req/sec |
| Starter | 90,000,000 | 150 req/sec |
| Pro | 450,000,000 | 500 req/sec |
| Scale | 1,500,000,000 | 1500 req/sec |
| Enterprise | Unlimited | Custom |
Automated clients (monitors, directories, benchmarks)
Two things about the keyless endpoint that are easy to trip over, and both are one line to fix on your side.
Send a User-Agent that names your tool. A small set of default agents is
blocked at the edge, because they are the signature of unattended traffic that
rotates across free providers: an empty User-Agent, node, and anything
containing Go-http-client, erpc, go-rpc-proxy or rpc-proxy-gui. Those get
403 before the request reaches us. Any other value passes — acme-monitor/1.0
is enough. This is not a block on Go or Node; it is a block on anonymous
clients, and naming yourself is the whole of the fix.
Space requests at least ten seconds apart. The keyless endpoint allows one
request per ten seconds per IP. That is enough to check liveness or sample
latency periodically; it is not enough to benchmark throughput, and a burst will
return 429 with Retry-After: 10.
If you need real throughput — continuous monitoring, load testing, or an integration — take a free key instead: 10 req/sec and 3,000,000 CU a month, no card. Keyed requests are exempt from both rules above.
curl https://rpc.nodeflare.app/eth/v1/YOUR_KEY \
-X POST -H 'content-type: application/json' \
-H 'user-agent: acme-monitor/1.0' \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'Compute Units
Each JSON-RPC method has a CU weight. One standard call = 1–2 CU; heavy data queries cost more. Heavy methods (eth_getLogs, trace_*, debug_*) require an API key — they're available on every plan including Free, and are simply weighted higher so the monthly quota throttles heavy usage.
| Method | CU |
|---|---|
eth_blockNumber, eth_chainId, net_version | 1 |
eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory | 1 |
eth_getBalance, eth_getTransactionCount, eth_getCode | 2 |
eth_getBlockByNumber, eth_getBlockByHash | 2 |
eth_getTransactionByHash, eth_getTransactionReceipt | 2 |
eth_call, eth_estimateGas, eth_createAccessList | 5 |
eth_newBlockFilter | 10 |
eth_newFilter, eth_getFilterChanges, eth_getProof | 20 |
eth_getLogs, eth_getFilterLogs | 25 |
trace_*, debug_* | 100 |
txpool_* | 10 |
| Any other method | 2 |
Batch requests (JSON array) sum the CU of each call in the batch. A single request may contain up to 100 calls and a body of 256 KB.
eth_getLogs block ranges
On Robinhood Chain (4663) the span of a single eth_getLogs is capped, and the cap depends on whether your filter names an address or a topics entry:
| Filter | Max blocks per call |
|---|---|
Names an address or a topic | 5,000 |
| Names neither | 10 |
The gap is not arbitrary. A filtered query is answered from the node's log index. An unfiltered one has to decode every receipt in the range: measured on our Frankfurt node, 50 blocks took 22.2 s without a filter and 0.96 s with an address filter. Robinhood produces ~10 blocks per second, so ranges accumulate fast — 5,000 blocks is roughly eight minutes of chain.
If you hit the cap you get HTTP 400 immediately, not a hanging connection:
{ "error": "block_range_too_large",
"message": "Unfiltered eth_getLogs is limited to 10 blocks per call on this chain; this request spans 50. Add an `address` or `topics` filter to query up to 5000 blocks per call, or split this into 10-block ranges." }Unfiltered calls also run in a smaller concurrency pool. When it is full you get HTTP 503 with Retry-After: 1 — again immediately, so you can retry or narrow the query rather than wait on a socket. Adding a filter moves the call into the much larger pool.
Other chains have no per-call block-range cap.
Error responses
When you exceed the per-second rate limit:
{ "error": "rate_limit_exceeded", "message": "Rate limit of 10 req/s exceeded" }When you exhaust your monthly CU quota:
{ "error": "monthly_limit_reached", "message": "Monthly quota exhausted. Resets ... or purchase extra CU at nodeflare.app/app/billing." }Both return HTTP 429. Retry after 1 second for rate limit errors.
Extra CU top-up
If you hit your monthly quota before the reset date, you can purchase a one-time top-up of 1,000,000 extra CU for $6 from your billing page. Extra CU:
- Stack on top of your plan's monthly quota
- Are consumed at the same CU rate as your plan (an
eth_getLogscall costs 25 extra CU, not 1) - Never expire — unused extra CU carry over month to month
- Can be purchased multiple times
Upgrade your plan or buy extra CU from your billing page.
Pay-per-request (x402)
Don't want an account at all? Every chain is also available over x402: pay per request in USDC on Base, no account or API key required — designed for AI agents and automated clients. Prices follow the compute-unit weights above at 1 CU = $0.00001 with a $0.001 minimum per request, and heavy methods are included. See the x402 docs.