Public vs dedicated Solana RPC: when to use each

On April 30, 2022, Solana’s Candy Machine mint collapsed the entire network. Bots racing to mint NFTs fired off millions of transactions in minutes, validators buckled under the load, and the chain went down for roughly seven hours. It became one of the most cited failure stories in Solana’s history, a cautionary tale about what happens when demand outpaces infrastructure.
But that story is dated now. Since then, Solana rolled out QUIC for connection handling, stake weighted quality of service (SWQoS), and priority fees, all designed specifically so a demand spike doesn’t take the whole network down again. The chain itself has gotten much harder to break.
What hasn’t gone away is the risk underneath it. During a hot mint or a trading surge, block leaders now prioritize connections from staked validators and reliable RPC providers. That’s good for network stability, but it means if your RPC provider isn’t staked or dedicated, your transactions are far more likely to stall or get dropped, even while the network itself hums along fine.
What public RPC actually is
How it works
Public RPC endpoints, like api.mainnet-beta.solana.com, are free and run by the Solana Foundation or community node operators. Traffic from thousands of unrelated apps hits the same pool of nodes, and none of them get dedicated compute, bandwidth, or memory. You’re sharing hardware with everyone else hitting that endpoint at the same time.

What it’s designed for
These endpoints exist for prototyping, testing, and learning the JSON-RPC methods, not for sustained production load. Rate limits reflect that, often 40 to 100 requests per 10 seconds per IP, with no guarantee of historical data access. Solana’s own docs are blunt about this: public endpoints aren’t intended for production apps.
When public RPC is enough
That said, public RPC isn’t something to avoid outright. Hackathons, weekend projects, and early prototypes rarely need more — uptime and speed don’t matter yet at that stage. The same goes for personal scripts, small bots, or one-off data pulls with no real users depending on them. If you’re still learning the JSON-RPC methods themselves, before your app has any production traffic to worry about, public RPC does exactly what it’s built for.
The hidden costs of staying public
Reliability issues
On public RPCs, sendTransaction calls frequently time out or get silently dropped during high congestion — like NFT drops or airdrops — because everyone is hitting the same shared pool. Confirming whether a transaction actually landed requires polling getSignatureStatuses. However, under heavy load, public nodes aggressively rate-limit these polling requests.
If a transaction’s blockhash expires (around 60–90 seconds) before you can get a successful response, you have to pass searchTransactionHistory: true to check if it ever landed. This forces a heavy ledger search that public nodes will often throttle, reject, or fail to support entirely. You’re left completely blind, unsure if the transaction failed, is still pending, or succeeded but is invisible due to rate limits. And since these are free community endpoints, there’s no SLA. An outage costs you users, not the provider.
User experience impact
Inconsistent latency also breaks the actual product experience. A trading dashboard or a game that depends on real-time state updates can’t tolerate response times swinging from 50ms to several seconds depending on who else is hitting the node. Slow confirmations are especially damaging in apps handling money or in-game assets, where users expect near-instant feedback that a transaction went through. Most teams respond by writing retry logic and exponential backoff to survive the rate limits, which works until it doesn’t — and it means engineers spend time building resilience around someone else’s infrastructure instead of shipping product.
One technical detail worth calling out here: premium infrastructure providers change the game entirely. Any developer can pass skipPreflight: true to bypass time-consuming local simulation checks, but doing so on a public node usually just means dropped packets during high traffic.
Signals your app has outgrown public RPC
| Signal | What it looks like | What it means |
|---|---|---|
| Frequent errors | 429 responses or connection timeouts during normal, non-spike traffic | Your baseline usage already exceeds public rate limits |
| Scaling traffic | User base pushing beyond a few hundred requests per second | Shared nodes can’t isolate your load from everyone else’s |
| Stakeholder pressure | Investors or partners asking about uptime guarantees and infrastructure resilience | Reliability has become a business requirement, not a nice-to-have |
| Latency-sensitive features | Roadmap includes trading, gaming, or payments where milliseconds matter | Public RPC’s inconsistent latency becomes a product blocker |
| Compliance needs | Audit or regulatory requirements demanding documented infrastructure ownership | Shared, third-party infra can’t satisfy accountability requirements |
At Chainstack, we pair that speed with Warp transactions, which route payloads directly through bloXroute’s ultra-high-speed relay network, pushing your transaction via optimized, staked connections straight to the active leader validator. That’s the kind of infrastructure lever that simply doesn’t exist on public RPCs, where you get one generic, heavily throttled path for every request regardless of urgency.
What dedicated RPC solves
Performance
With dedicated infrastructure, your app stops competing with thousands of unrelated apps for the same compute and bandwidth. Rate limits get matched to your actual traffic patterns instead of a one-size-fits-all cap designed to protect a free public node from abuse.
The practical result is lower, more predictable latency — especially on time-sensitive calls like sendTransaction during a mint or getAccountInfo in a live trading flow, where a few hundred milliseconds of jitter is the difference between a good and bad user experience.
Capability
Dedicated access also opens up methods and data that public RPC can’t really support. Archival nodes let you query historical data without hitting the lookback limits public endpoints impose. Depending on the provider, you also get access to extended APIs, webhooks for event-driven architectures, and Geyser plugins for streaming data directly out of the validator — all things we support on Chainstack. Geographic node placement matters too: running nodes physically closer to your users cuts latency in a way a single, centrally located public endpoint can’t, which is part of why we run infrastructure across multiple global regions.
Technical tradeoffs to weigh
Cost versus control
Dedicated infrastructure has a real monthly cost, but so does downtime or a dropped transaction during a major launch. Self-hosting your own Solana RPC nodes gives you full control over the stack, but it also means owning hardware provisioning, heavy NVMe snapshot management, urgent version upgrades, and 24/7 monitoring. That demands actual DevOps headcount, not just a budget line. As a managed provider, Chainstack removes that operational burden while still providing dedicated compute and bandwidth, giving you isolation without the infrastructure overhead.
Elasticity and hybrid setups
Dedicated doesn’t have to mean a single, fixed box sized for peak load year-round. With Chainstack, you can scale your node footprint as traffic grows without a full re-architecture.
Hybrid setups take this efficiency even further. You can route low-priority, high-volume reads — like continuous getAccountInfo polling — through a cost-effective shared tier. Meanwhile, you send critical, time-sensitive write calls — like sendTransaction during a mint — through dedicated nodes with guaranteed throughput and Warp routing.
The result is a budget that scales with what actually needs guaranteed performance, preventing you from over-provisioning dedicated resources for every basic read your app makes.
Bypassing JSON-RPC for heavy reads
There’s another tier above hybrid setups worth knowing about: skipping JSON-RPC entirely. Geyser plugins let dedicated architecture stream data directly out of the validator into Postgres or Kafka, no request-response cycle at all.
This matters most for apps doing heavy indexing, historical queries, or high-frequency account monitoring. Polling JSON-RPC repeatedly for the same data is slow and wasteful at that scale — you’re paying the latency cost of a request every single time, even when nothing’s changed. Streaming flips that: the data pushes to you the moment it changes onchain.
It’s also only viable with dedicated or validator-level access. Public and most shared RPC tiers have no path to this kind of pipeline — there’s no validator to plug a plugin into in the first place.
Architecture decisions
Once you’re running dedicated infrastructure, a few more decisions come into play. Single provider versus multi-provider setup affects your redundancy: one provider is simpler to manage, multiple providers protect you if one has an incident. Load balancing across regions matters if your user base is global (as we discussed earlier), not just where your primary node happens to sit. And failover strategy needs to be decided ahead of time — what happens automatically the moment one node starts degrading, not worked out live during an outage.
Choosing between public and dedicated
| Workload | Public RPC | Dedicated RPC |
|---|---|---|
| Hackathon or weekend prototype | Sufficient | Overkill |
| Personal script or one-off data pull | Sufficient | Overkill |
| NFT mint or token launch | High risk of dropped transactions | Built for burst traffic and priority landing |
| Real-time trading or DeFi app | Latency too inconsistent | Predictable, low latency required for execution |
| On-chain game with live state updates | Rate limits break real-time sync | Custom limits match actual usage |
| Historical data or analytics queries | No archival guarantees | Archival node access built in |
| High-frequency account monitoring | Polling hits rate limits fast | Geyser streaming bypasses polling entirely |
| Production app with real users | Not intended for production, per Solana’s own docs | Designed for production reliability and SLAs |
Making the transition smoothly
Migration steps
Run public and dedicated RPC side by side first. That’s the only real way to compare latency, error rates, confirmation times, and other metrics before you commit to anything. While you’re doing that, keep an eye on your actual request volume and which methods dominate your traffic, so you’re sizing a dedicated plan around real usage instead of a guess. Then roll it out in pieces, updating SDK configs or endpoint URLs service by service rather than one hard cutover across the whole app.
Testing
It is always recommended to load-test against your expected peak, not your average day. Average traffic won’t tell you what happens during a mint or a market spike, which is exactly when you can’t afford surprises. Simulate failover too — kill a node in staging and see what actually happens instead of finding out during a real outage.
Finally, before calling the migration done, double-check that your critical calls hold up under pressure. Pay extra attention to heavy queries like getProgramAccounts, which most public nodes heavily throttle into unusability since it scans an entire program’s account state. On dedicated infrastructure, verify that secondary indexing is properly configured so calls like this actually return instead of timing out.
Conclusion
Dedicated RPC isn’t really a cost line item. It’s more of a marker — it usually means your app has moved past the prototype stage and now has real users depending on it working.
Go back to that Candy Machine mint from 2022. The network itself wouldn’t buckle that way today, QUIC and SWQoS took care of that. But your app still could — not because Solana broke, but because your RPC provider got deprioritized while better-connected traffic got through.
That gap is only going to matter more over time. As Solana’s throughput ceiling keeps climbing, the constraint stops being how fast the chain can go and starts being how fast whoever is serving you data can keep up. RPC isn’t just plumbing anymore — it’s becoming the actual bottleneck on how fast your app can move.
The infrastructure decisions you make now aren’t just about handling today’s traffic. They set the ceiling on how far this app can scale before you’re back here again, rebuilding under pressure instead of by choice.
FAQ
Not literally unusable, but not recommended. It’s possible to run a low-traffic production app on public RPC for a while, but you’re accepting rate limits, no SLA, and no guarantee of consistent uptime as your real risk profile.
Watch for 429 errors or timeouts during normal (non-spike) traffic, sustained usage beyond a few hundred requests per second, stakeholder questions about uptime, or a roadmap that includes latency-sensitive features like trading or live gaming. Any one of these is a signal it’s time to move.
Public RPC is free, but that’s not really the comparison that matters. The real cost of staying on public RPC shows up as dropped transactions, lost users during a launch, and engineering time spent building retry logic around someone else’s infrastructure. Dedicated plans have a real monthly cost, but it should be weighed against what an outage or a botched mint would cost you.
Yes, this is a common and cost-effective approach. Route high-volume, low-priority reads (like routine getAccountInfo polling) through a cheaper shared tier, and send time-sensitive writes (like sendTransaction during a mint) through dedicated infrastructure with guaranteed throughput.
Dedicated RPC still uses the request-response JSON-RPC model, just with isolated compute and better rate limits. Geyser plugins skip JSON-RPC entirely, streaming account and transaction data directly out of the validator into a database like Postgres or Kafka. It’s a step beyond dedicated RPC, and only available with dedicated or validator-level access.
