Free-tier maxxing¶
About 105 requests/second of Solana RPC, for $0/month — and more if you want it. No single free tier gets you there; the best one on its own is 25 req/s. Stacking eight endpoints behind one local address does, because no single key ever sees more than a fraction of your traffic.
This page is the arithmetic and the config.
Is there a free Solana RPC endpoint?¶
Yes, several, at three different levels of commitment.
No signup at all. Two endpoints need no account and no key:
https://api.mainnet-beta.solana.com # Solana Foundation
https://solana-rpc.publicnode.com # PublicNode, operated by Allnodes
The Solana Foundation endpoint is documented at roughly 10 req/s (100 requests per 10 seconds per IP), 4 req/s for any single method, 40 concurrent connections, and 100 MB per 30 seconds. Solana's own cluster documentation says plainly: "The public RPC endpoints are not intended for production applications."
PublicNode publishes no rate limits at all, which cuts both ways:
there is no documented cap to design against, and no commitment that today's throughput survives
tomorrow. Verified serving mainnet 2026-09-05. Treat it as free capacity of unknown size — start it
with a conservative max_rps, watch rpc_plane_rate_limited_total and the 429 rate, and raise the
cap until one of them moves.
Free tiers with an account. Six providers give you a real allowance for a signup and no card:
| Provider | Monthly allowance | Rate limit | Notes |
|---|---|---|---|
| Alchemy | 30M compute units | 25 req/s | ~3M standard reads. Largest on dedicated infrastructure |
| Chainstack | 3M request units | 25 req/s | 1 RU per call, so 3M calls. Renews monthly |
| dRPC | 210M compute units / 30 days | unpublished | ~10.5M calls — the largest allowance here, but served over dRPC's public node pool |
| OnFinality | 400K response units per day | 40 RU/s → 20 calls/s | 2 RU per call, so ~200K calls/day (~6M/month). Note the allowance is daily |
| QuickNode | 10M credits (trial) | 15 req/s | Does not sell overage; the endpoint stops when credits run out |
| Helius | 1M credits | 10 req/s | Only 1 sendTransaction/s — the binding limit if you write |
Two of those need reading carefully. OnFinality's cap is in response units, not requests — every Solana method costs 2 RU, so 40 RU/s is 20 calls/s. And dRPC's free tier runs on its public node pool, which is slower and less reliable than its paid endpoints; it belongs in the stack as headroom, not as the leg you route latency-sensitive traffic to.
Free forever? Alchemy, Chainstack, Helius and dRPC renew (dRPC every 30 days from signup); OnFinality renews daily. QuickNode's is a trial — 10M credits once, not 10M a month. Treat QuickNode as the leg that disappears. The two no-signup endpoints have no allowance to exhaust, only unpublished (Foundation: published) throughput ceilings.
Alchemy, QuickNode and Helius verified 2026-09-05; Chainstack, dRPC and OnFinality 2026-09-06. Rates and weights for all of them are in provider pricing.
What stacking actually buys¶
Adding the caps:
| Rate | Monthly allowance | |
|---|---|---|
| Alchemy free | 25 req/s | 30M CU (~3M reads) |
| Chainstack free | 25 req/s | 3M RU (3M reads) |
| OnFinality free | 20 calls/s | 400K RU/day (~6M reads) |
| QuickNode trial | 15 req/s | 10M credits (~333k reads) |
| Helius free | 10 req/s | 1M credits (~1M reads) |
| Solana Foundation | 10 req/s | unmetered, no SLA |
| Subtotal | ~105 req/s | ~13.3M reads before anything paid |
| dRPC free | unpublished | 210M CU/30d (~10.5M calls), public pool |
| PublicNode | unpublished | unmetered, no SLA |
dRPC and PublicNode are left out of the subtotal deliberately — neither publishes a rate limit, so adding a number would be inventing one. In practice both are extra headroom on top of the 105, and dRPC's 10.5M calls would nearly double the monthly allowance if you use it.
Two honest caveats. Rate limit and monthly allowance are separate ceilings — you can be well under 105 req/s and still exhaust Helius's 1M credits in a day of steady traffic. And a sustained 105 req/s burns roughly 272M calls a month, far past every allowance here; the stack is sized for bursts and development traffic, not a constant load.
Writes are the real constraint. Helius allows 1 sendTransaction/s on free, and the public endpoint
is not somewhere to land transactions. If you are writing more than a couple of transactions a
second, a paid provider is the answer, not more free keys.
Config¶
[health]
interval_ms = 2000
window_secs = 30
circuit_open_failures = 3 # open quickly when a key rate-limits
circuit_error_threshold = 0.4
circuit_cooldown_secs = 2 # RPS windows reset per-second; recover fast
[routing]
strategy = "weighted_random" # spread load across all providers
max_retries = 7 # try all eight before giving up
[[providers]]
name = "alchemy"
url = "https://solana-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
weight = 5 # weights track capacity: 25 req/s is the biggest share
max_rps = 25
[[providers]]
name = "chainstack"
url = "${CHAINSTACK_URL}" # copy your node endpoint from the Chainstack console
weight = 5
max_rps = 25
[[providers]]
name = "onfinality"
url = "${ONFINALITY_URL}" # copy your endpoint from the OnFinality dashboard
weight = 4
max_rps = 20 # 40 RU/s at 2 RU per call
[[providers]]
name = "quicknode"
url = "https://your-endpoint.solana-mainnet.quiknode.pro/${QUICKNODE_API_KEY}/"
weight = 3
max_rps = 15
[[providers]]
name = "helius"
url = "https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}"
weight = 2
max_rps = 10
[[providers]]
name = "solana-foundation"
url = "https://api.mainnet-beta.solana.com"
weight = 2
max_rps = 10
[[providers]]
name = "publicnode"
url = "https://solana-rpc.publicnode.com"
weight = 2
max_rps = 10 # no published limit — start conservative and raise it on evidence
[[providers]]
name = "drpc"
url = "${DRPC_URL}" # copy your endpoint from the dRPC dashboard
weight = 2
max_rps = 10 # no published free-tier limit, and it runs on the public pool — stay conservative
export ALCHEMY_API_KEY=...
export QUICKNODE_API_KEY=...
export HELIUS_API_KEY=...
export CHAINSTACK_URL=... # full endpoint URL, key included
export ONFINALITY_URL=...
export DRPC_URL=...
rpc-plane -c free-tier.toml run
A bundled version ships as examples/free-tier.toml.
Why it works¶
Weights track capacity, not provider count. Equal weights send Helius the same share as
Alchemy, so Helius hits its 10 req/s cap while Alchemy sits idle at 40% utilisation — and the stack
sheds load long before it needs to. Setting weight in proportion to each cap (5/5/4/3/2/2/2/2 for
25/25/20/15/10/10/10/10) keeps every provider at roughly the same percentage of its own limit.
weighted_random over failover_ordered. failover_ordered hammers the first provider until
its circuit opens, then dumps everything on the second. That burns one monthly allowance at a time.
weighted_random spreads from the first request.
max_rps makes it proactive. The circuit breaker is reactive — it only reroutes after a key
has already returned 429s. A max_rps cap sheds
load before the 429s start. Set each one to the limit the plan actually publishes. It is a
load-shedding hint, not a hard throttle: if every key is momentarily at its cap the proxy forwards
anyway rather than dropping the request.
circuit_cooldown_secs = 2. Free-tier limits are per-second or per-minute windows that reset
continuously. The 30-second default leaves most of that capacity unused; 2 seconds lets a
rate-limited provider come back as soon as its window rolls over.
max_retries = 7. With eight providers, N - 1 means every one is tried before the proxy gives
up. Drop it to match if you leave any leg out — the no-signup and unpublished-limit legs (PublicNode,
dRPC) are the easiest to drop first.
The per-method limits are tighter than the headline¶
This is the part that catches people. Providers publish one number in the marketing table and several smaller ones underneath:
| Headline | sendTransaction |
DAS | getProgramAccounts |
|
|---|---|---|---|---|
| Helius free | 10 req/s | 1/s | 2/s | 5/s |
| Solana Foundation | ~10 req/s | — | — | 4/s for any single method |
| Chainstack free | 25 req/s | not published separately | — | — |
| Alchemy free | 25 req/s | not published separately | — | — |
| QuickNode trial | 15 req/s | not published separately | — | — |
| OnFinality free | 20 calls/s | not published separately | — | — |
Chainstack publishes its per-method caps on a different axis — not by category but by named method:
getBlock 400 RPS, getBlockTime / getBlocks / getBlocksWithLimit 500 RPS,
getTokenAccountsByOwner 80 RPS in most regions, and getSupply at 2 RPS on paid plans only, so
on the free Developer tier getSupply is not available at all. All of those sit above the free
tier's 25 req/s except getSupply, so in practice the plan limit binds first — but if you route
getSupply through Chainstack on the free tier it will simply fail, and that is worth an allowlist.
max_rps is per provider, not per method — all methods draw from one bucket — so max_rps = 10 on
Helius lets you spend the entire allowance on writes and take 429s at a tenth of the cap.
The fix uses what already ships. max_rps is per provider entry, and only name has to be
unique, so register the same key twice:
# Writes get their own 1 rps bucket.
[[providers]]
name = "helius-writes"
url = "https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}"
methods = ["sendTransaction"]
weight = 1
max_rps = 1
# Everything else uses the general limit.
[[providers]]
name = "helius-reads"
url = "https://mainnet.helius-rpc.com/?api-key=${HELIUS_API_KEY}"
weight = 2
max_rps = 10
Two independent buckets: writes cannot eat the read budget, and
rpc_plane_rate_limited_total{provider="helius-writes"} tells you exactly which limit is binding.
The write entry excludes getSlot, so it skips the health probe and is scored from live request
outcomes instead — see submission-only providers and
working around a per-method limit.
Worth doing for any provider whose write cap you actually care about. It is the difference between 1 write/s working reliably and 1 write/s working until your read traffic spikes.
Keep the history reads off the small tiers¶
The monthly allowances above assume standard reads. History calls do not cost the same:
| Standard read | getBlock / getTransaction |
|
|---|---|---|
| Helius | 1 credit | 10 credits |
| Alchemy | 10 CU | 40 CU |
| QuickNode | 30 credits | 30 credits (no premium) |
A getBlock-heavy workload drains Helius's 1M credits ten times faster than the headline figure
suggests. If you are backfilling history on free tiers, send those calls to QuickNode — it charges
no archival premium — using a methods allowlist, and let the
others take the account reads. See the pricing reference for the full
tables.
When to upgrade¶
This is a development, side-project and non-critical-traffic setup. Free endpoints are rate limited and carry no SLA.
The signal to move is not usually throughput — it is one of these:
- You need more than ~1 write/second. Helius free caps
sendTransactionat 1/s, and neither public endpoint is somewhere to land transactions. - You are exhausting a monthly allowance before the month ends.
- QuickNode's trial credits ran out and the stack quietly dropped to ~45 req/s.
- You need a rate limit you can design against — neither no-signup endpoint publishes one.
- You need someone to call when it breaks.
At that point add one paid provider as primary and keep the free stack as failover with
failover_ordered — the free keys cost nothing to leave in place,
and they are a genuinely useful backstop when the paid provider has a bad day.