Summary
Solana endpoint issues can stall dApps and trading bots. This article walks through common failure modes—timeouts, 429s, WebSocket drops, and slot lag—and shows how to diagnose them with curl and monitoring. It also explains when a public endpoint is the bottleneck and how a dedicated RPC node can stabilize your workload.
Quick diagnosis path
When your Solana dApp or bot starts failing, the first step is to identify whether the problem is on your side, on the endpoint provider's side, or in the network itself. A structured diagnosis saves hours of guessing.
Start by checking the most common symptoms:
- HTTP 429 or 403 responses – you are hitting rate limits on a shared endpoint.
- Timeouts on
getLatestBlockhashorsendTransaction– the endpoint is overloaded or your request payload is too large. - WebSocket disconnects – subscriptions are dropping, often due to idle timeouts or provider limits.
- Slot lag or
getBlockHeightfalling behind – the node behind the endpoint is not keeping up with the chain. Transaction simulation failederrors – often a client-side issue, but sometimes caused by an outdated blockhash from a lagging endpoint.
If you are on a public endpoint and see any of these, the fastest fix is to switch to a dedicated RPC node or a higher-tier shared service. For example, OnFinality provides dedicated Solana nodes that give you consistent throughput and dedicated resources. You can also compare RPC pricing to see what fits your workload.
But before you switch, run the checks below to confirm the root cause. You do not want to migrate infrastructure only to find the bug is in your own code.
Common Solana endpoint failure modes
Solana's RPC interface is JSON-RPC over HTTP and WebSocket. Endpoint issues usually fall into one of these categories:
1. Rate limiting (HTTP 429)
Public endpoints and even some shared commercial endpoints enforce rate limits to protect their infrastructure. When you exceed the allowed requests per second, you get a 429 Too Many Requests response. This is the most common cause of "endpoint issue" reports from developers running high-frequency trading bots or indexing jobs.
2. Timeouts and connection resets
Solana nodes can be slow to respond when they are syncing or under heavy load. If your client sets a short timeout, you may see ETIMEDOUT or ECONNRESET. This is especially common with sendTransaction because the node needs to process and forward the transaction.
3. WebSocket subscription drops
Many Solana dApps use WebSocket subscriptions for real-time account updates or transaction logs. Providers often disconnect idle connections or limit the number of active subscriptions. If your app does not handle reconnection logic, it will silently stop receiving updates.
4. Slot lag and stale data
The Solana network produces blocks roughly every 400ms. If the node behind your endpoint is not keeping up, it will report a getSlot that is far behind the current slot. This can cause your app to read stale state or fail to land transactions because the blockhash is too old.
5. JSON-RPC errors from malformed requests
Sometimes the issue is not the endpoint but the request itself. Solana's RPC is strict about parameter types. For example, getTokenAccountsByOwner requires a specific JSON structure. A malformed request returns a -32602 invalid params error, which can be mistaken for an endpoint problem.
Diagnose with curl and JSON-RPC
You can quickly test an endpoint's health using curl. Here is a basic check that fetches the current slot and block height:
curl https://solana.api.onfinality.io/public \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}'
A healthy response looks like:
{"jsonrpc":"2.0","result":123456789,"id":1}
If you get a timeout or an error, try the same request against a different endpoint to isolate the problem. You can also check the block height to see if the node is lagging:
curl https://solana.api.onfinality.io/public \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getBlockHeight"}'
Compare the result with the current slot from a block explorer like Solana Explorer. If the difference is more than a few slots, the node is lagging.
Debugging WebSocket disconnects
WebSocket issues are trickier to debug because they happen asynchronously. Use a simple Node.js script to test subscription stability:
const WebSocket = require('ws');
const ws = new WebSocket('wss://solana.api.onfinality.io/public-ws');
ws.on('open', () => {
console.log('Connected');
ws.send(JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'slotSubscribe'
}));
});
ws.on('message', (data) => {
console.log('Message:', data.toString());
});
ws.on('close', (code, reason) => {
console.log('Disconnected:', code, reason.toString());
});
ws.on('error', (err) => {
console.error('Error:', err.message);
});
If the connection drops after a few minutes, it could be an idle timeout. Many providers close WebSocket connections that have no activity for 30–60 seconds. If you need long-lived subscriptions, consider a dedicated node where you control the connection settings.
When to move to a dedicated Solana node
Not every workload needs a dedicated node, but many do. Here is a quick guide to help you decide:
| Workload pattern | Public endpoint | Shared commercial RPC | Dedicated node |
|---|---|---|---|
| Light dApp with occasional reads | OK | OK | Overkill |
| Production dApp with steady traffic | Risky | Good | Recommended |
| High-frequency trading bot | Not suitable | Often rate-limited | Best fit |
Heavy getProgramAccounts or getSignaturesForAddress | Not suitable | May be limited | Best fit |
| Long-lived WebSocket subscriptions | Unreliable | Possible but limited | Best fit |
| Indexing or backfill jobs | Not suitable | Not suitable | Best fit |
If you see 429s, timeouts, or WebSocket drops on a regular basis, it is time to move to a dedicated node. OnFinality's dedicated Solana nodes give you a private RPC endpoint with dedicated resources, so you are not competing with other users. You can also start with a shared commercial RPC and upgrade as your traffic grows.
Monitoring your Solana endpoint health
Proactive monitoring prevents endpoint issues from becoming outages. Set up health checks that alert you when something goes wrong. Here is a simple monitoring script that checks the endpoint every minute:
#!/bin/bash
ENDPOINT="https://solana.api.onfinality.io/public"
while true; do
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 \
-X POST "$ENDPOINT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}')
if [ "$RESPONSE" != "200" ]; then
echo "Endpoint unhealthy: HTTP $RESPONSE at $(date)"
# Send alert (e.g., Slack, PagerDuty)
fi
sleep 60
done
Track these metrics over time:
- Response time – average and p95 latency for
getSlot. - Error rate – percentage of non-2xx responses.
- WebSocket uptime – how often connections drop.
- Slot lag – difference between your node's slot and the network's latest slot.
If any of these degrade, you will have data to show your provider or to justify moving to a dedicated node.
Solana endpoint configuration best practices
Once you have a stable endpoint, configure your client correctly to avoid common issues:
- Set a reasonable timeout – Solana RPC calls can take longer than typical Ethereum calls. Use a timeout of at least 10 seconds for
sendTransaction. - Retry with exponential backoff – transient errors happen. Implement retries with jitter to avoid hammering the endpoint.
- Handle WebSocket reconnection – always implement a reconnection mechanism with backoff.
- Use the correct commitment level –
confirmedorfinalizedfor critical transactions,processedfor faster feedback but less certainty. - Batch requests – if you need to fetch multiple accounts, use
getMultipleAccountsinstead of manygetAccountInfocalls.
Here is an example of setting a timeout and retry logic in JavaScript using @solana/web3.js:
const { Connection } = require('@solana/web3.js');
const connection = new Connection('https://solana.api.onfinality.io/public', {
commitment: 'confirmed',
confirmTransactionInitialTimeout: 60000,
httpHeaders: { 'Content-Type': 'application/json' }
});
async function getSlotWithRetry(retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await connection.getSlot();
} catch (err) {
if (i === retries - 1) throw err;
await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
}
}
}
getSlotWithRetry().then(console.log).catch(console.error);
Key Takeaways
- Solana endpoint issues usually stem from rate limits, timeouts, WebSocket drops, or node lag.
- Diagnose with simple
curlcalls and compare against a block explorer to isolate the problem. - Public endpoints are fine for light use, but production workloads often need a dedicated node.
- Monitor response time, error rate, WebSocket uptime, and slot lag to catch issues early.
- Configure your client with proper timeouts, retries, and reconnection logic to reduce failures.
- OnFinality offers Solana RPC endpoints and dedicated nodes to handle demanding workloads.
Frequently Asked Questions
Why does my Solana RPC endpoint return 429 errors?
429 errors mean you are exceeding the rate limit of the endpoint. Public endpoints and shared commercial services enforce limits. If you consistently hit 429s, you need a higher-tier plan or a dedicated node.
How do I fix WebSocket disconnects on Solana?
Implement automatic reconnection with exponential backoff in your client. Also, check if the provider has idle timeouts or subscription limits. A dedicated node gives you more control over WebSocket connections.
What is slot lag and why does it matter?
Slot lag is the difference between the current slot on the network and the slot your node has processed. If your endpoint lags, you may read stale data or fail to land transactions. Monitor getBlockHeight against the explorer.
Should I use a public or dedicated Solana RPC endpoint?
For development and light usage, a public endpoint is fine. For production dApps, trading bots, or heavy indexing, a dedicated node provides consistent performance and avoids rate limits. Compare options on RPC pricing.
How can I test if my Solana endpoint is healthy?
Use curl to call getHealth or getSlot. A healthy endpoint returns a 200 response with a valid result. Monitor response times and error rates over time to spot trends.