Summary
Solana RPC nodes expose the JSON-RPC interface your app uses to read accounts, submit transactions, and subscribe to slot or account changes. This page covers the endpoint shape, the methods that matter most in practice, and how to decide between shared public RPC and a dedicated node as your workload grows.
You will get a connectable endpoint example, a workload-to-setup table, a debugging path for common failures, and a short checklist for evaluating a provider before you move traffic to it.
Solana does not look like an EVM chain from an RPC point of view. There is no eth_getLogs, no block-by-block receipt model, and no mempool you can poll for pending transactions. Instead you read account state, submit signed transactions, and subscribe to slot or account updates. Understanding that shape is the fastest way to pick the right RPC node setup.
Which Solana RPC setup fits your workload
Before comparing providers, match your workload to the kind of endpoint it actually needs. Most teams over-provision early and under-provision later, so use this table as a starting filter.
| Workload | Typical call pattern | Setup that usually fits |
|---|---|---|
| Wallet or portfolio UI | getBalance, getTokenAccountsByOwner, occasional sendTransaction | Shared RPC endpoint with a provider key |
| Trading bot or sniper | High-frequency sendTransaction, getLatestBlockhash, priority fee reads | Dedicated node or low-latency private endpoint |
| Indexer or analytics | getProgramAccounts, getSignaturesForAddress, large getTransaction batches | Archive-capable node with generous compute limits |
| dApp frontend | Mixed reads plus WebSocket accountSubscribe | Shared RPC plus a WebSocket endpoint |
| Validator tooling | Slot and epoch reads, vote account queries | Dedicated node close to your validator |
If your app only reads balances and occasionally submits a transaction, a shared endpoint is usually enough. If you submit transactions in bursts, run getProgramAccounts against a large program, or need predictable compute-unit headroom, a dedicated Solana node gives you capacity that is not shared with other tenants.
OnFinality provides both shared Solana RPC API access and dedicated node infrastructure, so you can start on a shared endpoint and move to a dedicated node without changing your client code. See the Solana network page for current endpoint details and RPC pricing for plan shapes.
The endpoint shape: HTTP and WebSocket
A Solana RPC node exposes a JSON-RPC 2.0 interface over HTTP for request/response calls, and a separate WebSocket URL for subscriptions. The two are not interchangeable: accountSubscribe, slotSubscribe, and logsSubscribe only work over WebSocket.
A public OnFinality Solana endpoint follows this pattern:
# HTTP JSON-RPC
https://solana.api.onfinality.io/public
# WebSocket subscriptions
wss://solana.api.onfinality.io/public-ws
A minimal curl call to confirm the endpoint is live and returning the expected cluster:
curl https://solana.api.onfinality.io/public \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getHealth"
}'
A healthy mainnet node returns {"jsonrpc":"2.0","result":"ok","id":1}. If you get a cluster mismatch or a -32005 style error, you are likely pointed at the wrong network or hitting a rate limit.
For client-side use, the @solana/web3.js connection object takes both URLs:
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://solana.api.onfinality.io/public",
{ wsEndpoint: "wss://solana.api.onfinality.io/public-ws" }
);
const balance = await connection.getBalance(
new PublicKey("11111111111111111111111111111111")
);
console.log(balance);
Keep the HTTP and WebSocket URLs from the same provider and the same cluster. Mixing a mainnet HTTP endpoint with a devnet WebSocket is a common source of confusing subscription failures.
Methods that shape your node requirements
Not all JSON-RPC methods cost the same. A few Solana methods dominate node load and are the ones worth testing before you commit to a provider.
| Method | What it does | Why it stresses a node |
|---|---|---|
getProgramAccounts | Returns all accounts owned by a program | Large result sets, heavy compute, often needs filters |
getSignaturesForAddress | Lists signatures for an address | Deep history scans on busy addresses |
getTransaction | Fetches a full transaction | Expensive when called in loops without batching |
sendTransaction | Submits a signed transaction | Latency-sensitive, competes for block inclusion |
getLatestBlockhash | Returns a recent blockhash | High frequency in trading and bot workloads |
accountSubscribe | Streams account changes | Requires a stable WebSocket connection |
If your app depends on getProgramAccounts or deep signature history, confirm the provider supports those calls with reasonable limits and, where needed, archive data. Some shared endpoints restrict or throttle these methods because a single caller can consume a large share of node resources.
Connecting a wallet or client to Solana
For a wallet or a frontend, you usually register the network once and let the user switch. A typical Solana network entry looks like this:
{
"chainName": "Solana Mainnet",
"rpcUrls": ["https://solana.api.onfinality.io/public"],
"nativeCurrency": { "name": "SOL", "symbol": "SOL", "decimals": 9 },
"blockExplorerUrls": ["https://explorer.solana.com"]
}
If you are building or testing before mainnet, point at a devnet endpoint instead and keep the two configurations separate. The Solana Devnet page covers the testnet-side setup.
Two practical notes:
- Solana transactions expire quickly. Fetch a fresh blockhash close to submission time rather than caching one.
- Priority fees matter under load. Read recent prioritization fees and set a fee that reflects current network conditions rather than a fixed value.
Debugging common Solana RPC failures
Most Solana RPC problems fall into a small set of symptoms. Match the symptom to the likely cause before changing providers.
| Symptom | Likely cause | First thing to check |
|---|---|---|
Blockhash not found | Stale or expired blockhash | Fetch a fresh getLatestBlockhash right before sending |
429 or rate-limit errors | Shared endpoint quota exceeded | Request rate, batching, and whether a dedicated node is warranted |
| WebSocket disconnects | Idle timeout or unstable connection | Reconnect logic and subscription heartbeat |
Empty getProgramAccounts result | Missing or wrong filters | Data size filters and account discriminator |
| Transaction lands slowly | Low priority fee or congested slot | Recent prioritization fees and retry strategy |
| Cluster mismatch errors | HTTP and WS point at different clusters | Both URLs from the same network |
A simple monitoring probe helps you catch endpoint problems before users do:
while true; do
curl -s https://solana.api.onfinality.io/public \
-X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}' \
| head -c 200
echo
done
Run this against each endpoint in your failover list and log the response time. If one endpoint drifts, you can shift traffic before it becomes an outage.
Shared endpoint or dedicated node?
The decision usually comes down to three questions: how bursty is your traffic, how heavy are your methods, and how much control do you need over the node itself.
- Shared RPC fits read-heavy apps, wallets, and early-stage products. You get a managed endpoint without running infrastructure, and you pay for access rather than for a machine.
- Dedicated node fits trading systems, indexers, and apps that call expensive methods or need consistent compute headroom. You get a node that is not shared with other tenants, which makes performance more predictable.
A common pattern is to run shared RPC for general reads and a dedicated node for the latency-sensitive path, then fail over between them. OnFinality supports both models, and you can review the tradeoffs in How to choose an RPC provider and the dedicated node option.
Provider evaluation checklist for Solana
When you compare Solana RPC providers, test against your real workload rather than a generic benchmark.
- Method coverage — Confirm
getProgramAccounts,getSignaturesForAddress, and WebSocket subscriptions work with your filters. - Compute and rate limits — Ask how limits are applied and whether they scale with your plan.
- Archive depth — If you query old transactions or signatures, verify historical data is available.
- WebSocket stability — Test long-lived subscriptions, not just a single message.
- Failover — Check whether you can run multiple endpoints and switch between them.
- Observability — Look for request metrics, error rates, and status information you can act on.
- Support path — Know how to reach the provider when a transaction path breaks.
You can review available networks on the supported RPC networks page and compare plan shapes on RPC pricing.
Key Takeaways
- Solana RPC nodes expose JSON-RPC over HTTP plus a separate WebSocket URL for subscriptions.
getProgramAccounts,getSignaturesForAddress, andsendTransactionare the methods that most affect node requirements.- Shared endpoints fit read-heavy apps; dedicated nodes fit bursty, latency-sensitive, or compute-heavy workloads.
- Most failures trace back to stale blockhashes, rate limits, WebSocket drops, or cluster mismatches.
- Test providers against your real call pattern, including WebSocket stability and archive depth.
Frequently Asked Questions
Do I need a dedicated Solana node? Not always. If your app reads balances and submits occasional transactions, a shared endpoint is usually enough. Move to a dedicated node when you need predictable compute headroom, heavy method support, or lower latency for transaction submission.
What is the difference between the HTTP and WebSocket Solana endpoints?
HTTP handles request/response calls like getBalance and sendTransaction. WebSocket handles subscriptions like accountSubscribe and slotSubscribe. You need both URLs if your app uses subscriptions.
Why does getProgramAccounts fail or return nothing?
It is a heavy method that often needs filters, and some shared endpoints restrict it. Check your data size filters and account discriminator, and confirm the provider supports the call at your expected volume.
How do I handle Solana transaction failures?
Fetch a fresh blockhash close to submission, set a priority fee based on recent network conditions, and implement retries. Most Blockhash not found errors come from stale blockhashes.
Can I use the same endpoint for mainnet and devnet? No. Mainnet and devnet are separate clusters with separate endpoints. Keep the two configurations distinct and make sure your HTTP and WebSocket URLs point at the same cluster.