Summary
Solana RPC is the JSON-RPC interface your app uses to read accounts, send transactions, and subscribe to on-chain events. This overview covers the endpoint shape, the methods you will call most, and the settings that usually break first when you move from a demo to a live app. It also explains when a shared endpoint is enough and when a dedicated Solana node is the better fit.
Solana RPC is the JSON-RPC interface your application uses to talk to a Solana node. Every wallet balance, token account, transaction submission, and log subscription in a Solana app eventually becomes an RPC call. This overview explains what the endpoint looks like, which methods you will actually call, and how to decide between a shared endpoint and a dedicated node before you ship.
If you are here because you searched for the Solana RPC docs, the short version is: Solana exposes a JSON-RPC API over HTTP for request/response calls and over WebSocket for subscriptions. You point your client at an endpoint URL, send JSON-RPC requests, and get JSON back. The interesting decisions are about which endpoint you use, how you handle commitment levels, and how you keep the connection healthy under load.
When a shared Solana endpoint is enough (and when it is not)
Most teams should start on a shared or public endpoint and move to dedicated infrastructure only when a specific signal appears. Use this as a quick triage before you spend time on node operations.
| Signal you are seeing | Shared endpoint is usually fine | Time to consider a dedicated Solana node |
|---|---|---|
| Traffic profile | Low to moderate request volume, mostly reads | Sustained high request volume, bursts, or many concurrent WebSocket subscriptions |
| Workload type | Wallet balances, simple transfers, dashboards | Indexers, trading systems, backends that call getProgramAccounts or getSignaturesForAddress heavily |
| Latency sensitivity | Tolerant of shared queueing | Latency-sensitive paths where you want predictable placement |
| Data needs | Recent state only | Archive-style historical queries, large log scans, or heavy getBlock usage |
| Operational control | You do not want to run nodes | You need isolation, custom limits, or a private endpoint |
If you are still in the first column, a managed shared endpoint is the fastest path. OnFinality provides Solana RPC as a managed API, and you can review Solana network details for the current endpoint and transport support. If you are in the second or third column, read the dedicated-node section below before you assume you need to run hardware yourself.
The endpoint shape: HTTP and WebSocket
A Solana RPC endpoint is a URL. HTTP endpoints handle request/response calls. WebSocket endpoints handle subscriptions such as accountSubscribe, logsSubscribe, and slotSubscribe. OnFinality's public Solana endpoint follows this pattern:
- HTTP:
https://solana.api.onfinality.io/public - WebSocket:
wss://solana.api.onfinality.io/public-ws
For production apps you will normally use an API key or a dedicated endpoint rather than the public URL. The public endpoint is useful for quick tests, prototypes, and verifying that your request shape is correct before you wire it into an app.
A minimal configuration looks like this:
import { Connection, PublicKey } from "@solana/web3.js";
const connection = new Connection(
"https://solana.api.onfinality.io/public",
{ commitment: "confirmed" }
);
const balance = await connection.getBalance(
new PublicKey("11111111111111111111111111111111")
);
console.log(balance);
The commitment option is one of the most common sources of confusion, so it is worth setting deliberately rather than accepting a default.
Commitment levels and why they change your results
Solana does not finalize blocks instantly. A transaction moves through processed, confirmed, and finalized states. The commitment level you pass to an RPC call tells the node how much certainty you want before it returns data.
| Commitment | What it means in practice | Typical use |
|---|---|---|
processed | Fastest, least certain; the node has seen the block but it may still be skipped | UI that needs the newest possible state and can tolerate rollback |
confirmed | A supermajority of stake has voted; unlikely to be rolled back | Most application reads and transaction confirmations |
finalized | Maximum certainty; the block is rooted | Accounting, settlement, and anything that must not be reversed |
A practical pattern is to read with confirmed for user-facing balances and use finalized when you are recording a value that must not change. Mixing commitment levels across a single workflow is a common bug source: a balance read at processed and a transaction confirmed at finalized can disagree for a short window.
Core Solana JSON-RPC methods you will call most
You do not need to memorize the full method list. Most Solana apps use a small subset repeatedly, and the rest appear only for specific features.
| Method | What it returns | Watch out for |
|---|---|---|
getBalance | Lamport balance for an account | Commitment level changes the value near a slot boundary |
getAccountInfo | Account data, owner, lamports | Large accounts increase response size |
getTokenAccountsByOwner | SPL token accounts for a wallet | Can be heavy for wallets with many token accounts |
getTransaction | A single transaction by signature | Returns null if the node has not seen or has pruned it |
getSignaturesForAddress | Recent signatures for an address | Pagination matters; do not request unbounded ranges |
getLatestBlockhash | A recent blockhash for building transactions | Blockhashes expire; fetch close to send time |
sendTransaction | Submits a signed transaction | Handle preflight errors and retries explicitly |
simulateTransaction | Dry-runs a transaction | Useful before sending anything that moves funds |
getProgramAccounts | Accounts owned by a program | Expensive; filter aggressively or expect timeouts |
A direct JSON-RPC call looks like this:
curl https://solana.api.onfinality.io/public \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": [
"11111111111111111111111111111111",
{"commitment": "confirmed"}
]
}'
If you are debugging a client library, sending the raw JSON-RPC request first is a fast way to separate a library problem from an endpoint problem.
WebSocket subscriptions: what changes when you stop polling
Polling getSlot or getBalance in a loop is simple but wasteful. WebSocket subscriptions let the node push updates to you. The tradeoff is connection management: subscriptions can drop, and you need reconnect logic.
const ws = new WebSocket("wss://solana.api.onfinality.io/public-ws");
ws.onopen = () => {
ws.send(JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "logsSubscribe",
params: [
{ mentions: ["YourProgramPublicKeyHere"] },
{ commitment: "confirmed" }
]
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
// Handle notification payloads here
};
Two operational notes. First, subscriptions are stateful: if the socket closes, your subscription is gone and must be re-established. Second, a subscription that is never cleaned up will keep consuming resources, so unsubscribe when a component unmounts or a job finishes.
Common failure modes and how to read them
Most Solana RPC problems fall into a handful of patterns. Recognizing the symptom saves time.
| Symptom | Likely cause | First thing to check |
|---|---|---|
429 or throttling responses | Request rate exceeds the endpoint's allowance | Batch size, polling frequency, and whether you are retrying too aggressively |
getProgramAccounts times out | Query is too broad for the endpoint | Add filters, reduce data size, or move to a dedicated node |
Transaction returns Blockhash not found | Blockhash expired before send | Fetch a fresh blockhash immediately before sending |
| Transaction simulation fails | Account state changed or instruction is invalid | Re-run simulateTransaction and inspect logs |
| WebSocket stops delivering | Socket dropped or subscription expired | Add reconnect and re-subscribe logic |
| Inconsistent balances | Commitment levels differ across calls | Standardize commitment per workflow |
A useful habit is to log the raw JSON-RPC error code and message, not just a generic "request failed." Solana error codes are specific enough to point you at the fix.
Shared endpoint vs dedicated Solana node
Once you know your workload, the build-versus-buy question becomes concrete. Running your own Solana node means provisioning hardware, keeping up with client releases, and managing storage growth. A managed dedicated node gives you an isolated endpoint without that operational load. A shared managed endpoint gives you a working RPC API without either.
| Approach | You manage | Good fit for |
|---|---|---|
| Public endpoint | Nothing, but expect shared limits | Prototypes, tests, low-volume scripts |
| Managed shared RPC (OnFinality) | Nothing; you get an API endpoint | Production apps with moderate, mostly read traffic |
| Managed dedicated node (OnFinality) | Configuration choices, not hardware | High-volume reads, heavy subscriptions, isolation needs |
| Self-hosted node | Hardware, upgrades, monitoring, storage | Teams with specific compliance or control requirements |
OnFinality offers Solana RPC as a managed API and dedicated nodes when you need isolation. You can compare options on the RPC pricing page and review supported RPC networks if you also run on other chains. If you are still deciding between providers, the RPC provider selection guide walks through the evaluation criteria.
A practical rollout checklist
Before you point production traffic at any Solana endpoint, confirm these items:
- Commitment levels are set explicitly per call, not left to defaults.
- You have a strategy for
getProgramAccountsand other heavy reads, such as filters or a dedicated node. - Transaction sending fetches a fresh blockhash and handles preflight errors.
- WebSocket clients reconnect and re-subscribe after a drop.
- You log raw JSON-RPC error codes for debugging.
- You know your expected request volume and have matched it to an endpoint tier.
- You have a fallback endpoint or failover plan for critical paths.
If you cannot answer item six, start on a shared endpoint and measure before committing to dedicated infrastructure.
Key Takeaways
- Solana RPC is a JSON-RPC API available over HTTP for calls and WebSocket for subscriptions.
- Commitment levels (
processed,confirmed,finalized) directly change the data you receive; set them deliberately. - A small set of methods covers most apps, but heavy reads like
getProgramAccountsneed filters or dedicated capacity. - WebSocket subscriptions reduce polling but require reconnect and cleanup logic.
- Choose a shared managed endpoint for moderate traffic and a dedicated Solana node when you need isolation or handle heavy reads.
- OnFinality provides Solana RPC as a managed API; check Solana network details for current endpoints and transport support.
Frequently Asked Questions
What is the Solana RPC endpoint format?
A Solana RPC endpoint is a URL that accepts JSON-RPC requests over HTTP, with a separate WebSocket URL for subscriptions. OnFinality's public Solana endpoints are https://solana.api.onfinality.io/public for HTTP and wss://solana.api.onfinality.io/public-ws for WebSocket. Production apps typically use an API key or dedicated endpoint instead of the public URL.
Which commitment level should I use?
Use confirmed for most user-facing reads and transaction confirmations, and finalized for values that must not be reversed, such as accounting entries. Use processed only when you need the newest possible state and can tolerate the possibility of a skipped block.
Why does getProgramAccounts time out?
It scans accounts owned by a program, and without filters the result set can be very large. Add filters such as data size or memcmp constraints, request only the fields you need, or move this workload to a dedicated node with more headroom.
Do I need a dedicated Solana node?
Not always. Start on a shared managed endpoint and measure your request volume, subscription count, and heavy-read frequency. Move to a dedicated node when you need isolation, predictable capacity, or you are repeatedly hitting limits on shared infrastructure.
How do I handle WebSocket disconnects?
Treat subscriptions as stateful and disposable. Add reconnect logic, re-subscribe on reconnect, and unsubscribe when the consumer shuts down. Log disconnect reasons so you can distinguish network issues from endpoint-side limits.
Can I use OnFinality for Solana and other chains?
Yes. OnFinality provides RPC API access across multiple networks. See supported RPC networks for the current list and RPC pricing for plan details. If you need isolated capacity, review dedicated nodes.