Choosing an Ethereum RPC node provider is really a question about how your application reads and writes chain state under load. Ethereum mainnet produces a block roughly every 12 seconds, and every wallet balance check, log query, and transaction broadcast goes through a JSON-RPC endpoint. If that endpoint is slow, rate-limited, or missing the methods you need, your users feel it before your dashboards do.
This page is for developers and infrastructure buyers comparing Ethereum RPC options. It covers what a node provider actually does, which capabilities separate a shared endpoint from a dedicated node, and how to test a provider before you commit production traffic.
Start with your workload, not the provider list
Before you compare vendors, write down what your app actually sends. Most Ethereum RPC traffic falls into a few patterns, and each one stresses a different part of the node.
| Workload pattern | Typical methods | What it stresses |
|---|---|---|
| Wallet / dapp reads | eth_call, eth_getBalance, eth_getTransactionCount | Low-latency head state, high request volume |
| Indexer / analytics | eth_getLogs, eth_getBlockByNumber | Archive state, large result sets, long queries |
| Trading / bots | eth_sendRawTransaction, eth_getTransactionReceipt | Broadcast speed, mempool visibility, WebSocket |
| Bridges / relayers | eth_getProof, trace_* | Trace and proof support, deep historical state |
| Monitoring / alerting | eth_subscribe, eth_blockNumber | Persistent WebSocket, stable connection |
If you only send eth_call and eth_getBalance, a well-run shared endpoint is usually enough. If you run eth_getLogs across wide block ranges, replay history, or need trace_* and debug_* methods, you are in archive and dedicated-node territory. That distinction drives cost far more than raw request count.
What an Ethereum RPC node provider actually runs
A provider operates Ethereum execution and consensus clients, keeps them synced to the network, and exposes them through a load-balanced JSON-RPC layer. Good providers also handle client upgrades, reorg handling, peer management, and monitoring so you do not have to.
There are three common delivery models:
- Public endpoints. Free, shared, and rate-limited. Fine for prototyping and low-volume reads, but not something to point a production wallet at.
- Managed RPC API. A paid shared endpoint with higher limits, API keys, and usually archive access. This is the default choice for most production dapps.
- Dedicated nodes. Isolated node capacity for one team. You get predictable throughput, your own archive or trace configuration, and no noisy neighbors.
OnFinality offers Ethereum through a managed RPC API service and through dedicated nodes when you need isolated capacity. You can start on the shared endpoint and move up without changing your application code, because the JSON-RPC interface stays the same.
Ethereum chain settings at a glance
If you are wiring Ethereum into a wallet, a Hardhat config, or a backend service, you need the canonical network parameters. Use these values so your tooling connects to mainnet rather than a testnet.
| Setting | Value |
|---|---|
| Network name | Ethereum Mainnet |
| Chain ID | 1 |
| Native currency | ETH (18 decimals) |
| Block explorer | https://etherscan.io |
| Public RPC URL | https://eth.api.onfinality.io/public |
| Transports | HTTP and WebSocket |
A quick way to confirm an endpoint is live and on the right chain is to ask it for the chain ID and latest block:
curl -s https://eth.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# {"jsonrpc":"2.0","id":1,"result":"0x1"}
If that returns 0x1, you are on Ethereum mainnet. If it returns anything else, you are pointed at a different chain or a testnet. For testnet work, use the Ethereum Sepolia network page instead.
Provider evaluation matrix
Once you know your workload, compare providers against the capabilities that matter for it. The table below is a practical checklist rather than a ranking.
| Capability | Why it matters | What to ask |
|---|---|---|
| Transport support | Wallets and bots often need WebSocket for subscriptions | Is HTTP and WS both available? |
| Archive access | Historical eth_getLogs and state reads need archive nodes | Is archive included or a separate tier? |
| Trace / debug methods | Bridges and analytics rely on trace_* and debug_* | Which trace methods are exposed? |
| Rate limits | Bursty workloads hit shared caps | What are the request and compute-unit limits? |
| Failover | A single endpoint is a single point of failure | Are there multiple regions or endpoints? |
| Observability | You need to see errors before users do | Are usage and error metrics exposed? |
| Support model | Incidents need a human, not a ticket queue | What is the response path during an outage? |
OnFinality appears first here because it is the provider this site operates: it offers Ethereum over HTTP and WebSocket, supports archive and trace workloads on appropriate plans, and lets teams move from shared RPC to dedicated nodes. Compare every provider on the same criteria before deciding.
Testing a provider before you commit
Do not migrate production traffic on a provider's marketing page. Run a short evaluation against your real methods. A simple script that measures latency and correctness across a few endpoints will tell you more than any benchmark table.
// probe.mjs — compare Ethereum RPC endpoints on the methods you actually use
const endpoints = [
"https://eth.api.onfinality.io/public",
// add other provider endpoints you are evaluating
];
async function probe(url) {
const body = (method, params = []) =>
JSON.stringify({ jsonrpc: "2.0", id: 1, method, params });
const call = async (method, params) => {
const start = performance.now();
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: body(method, params),
});
const json = await res.json();
return { ms: Math.round(performance.now() - start), ok: !json.error };
};
const block = await call("eth_blockNumber");
const logs = await call("eth_getLogs", [
{ fromBlock: "latest", toBlock: "latest" },
]);
console.log(url, { block, logs });
}
for (const url of endpoints) await probe(url);
Run this at different times of day. Watch for endpoints that are fast on eth_blockNumber but slow or erroring on eth_getLogs, since log queries are where shared capacity usually shows its limits.
Where shared endpoints stop being enough
A managed shared endpoint is the right default for most teams. It stops being enough when one of these becomes true:
- You regularly hit rate limits during peak traffic and cannot smooth the load.
- You need eth_getLogs across large block ranges on a schedule.
- You depend on trace_* or debug_* methods that shared tiers restrict.
- You need a WebSocket connection that stays open for subscriptions without reconnects.
- You need predictable throughput for a launch, a mint, or a trading window.
At that point, a dedicated Ethereum node gives you isolated CPU, memory, and disk, plus your own archive and trace configuration. It also removes the noisy-neighbor problem, where another tenant's traffic spike becomes your latency spike. See dedicated nodes for how that model works, and RPC pricing to compare tiers.
Failover and multi-provider strategy
Even a well-run provider can have a bad hour. Production apps should assume any single endpoint will occasionally fail and design for it.
A common pattern is a primary endpoint with one or two fallbacks, selected by health checks rather than hardcoded order:
// rpc-router.mjs — simple health-checked failover across endpoints
const pool = [
"https://eth.api.onfinality.io/public",
// fallback endpoints
];
async function healthy(url) {
try {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] }),
signal: AbortSignal.timeout(2000),
});
const json = await res.json();
return !json.error;
} catch {
return false;
}
}
export async function send(payload) {
for (const url of pool) {
if (!(await healthy(url))) continue;
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (res.ok) return res.json();
}
throw new Error("all Ethereum RPC endpoints failed");
}
Keep the fallback list short and tested. An untested fallback is worse than none, because it fails exactly when you need it.
Common failure modes and what they usually mean
When an Ethereum RPC call misbehaves, the error often points at configuration rather than the provider.
| Symptom | Likely cause | Next step |
|---|---|---|
method not found |
Endpoint does not expose that method (often trace_*) | Confirm method support with the provider |
429 or rate-limit errors |
Shared tier request cap exceeded | Reduce burst size or move to a higher tier |
missing trie node |
Query hit non-archive state | Use an archive endpoint for historical reads |
nonce too low |
Local nonce tracking out of sync | Re-read eth_getTransactionCount with pending |
| WebSocket drops | Idle timeout or unstable connection | Add reconnect logic and heartbeat pings |
| Slow eth_getLogs | Wide block range on shared capacity | Narrow ranges or use a dedicated node |
If you are debugging transaction-level issues like nonce errors, the nonce explainer walks through the mechanics.
Key Takeaways
- An Ethereum RPC node provider runs the nodes; you consume JSON-RPC over HTTP or WebSocket. The delivery model (public, managed, dedicated) matters more than the brand.
- Match the provider to your workload. Reads, log queries, transaction broadcasts, and trace calls stress different parts of a node.
- Ethereum mainnet uses chain ID 1, ETH as the native currency, and supports both HTTP and WebSocket transports.
- Test providers against your real methods, especially eth_getLogs and any trace_* calls, before migrating production traffic.
- Plan for failover. A primary endpoint plus tested fallbacks is standard practice for production apps.
- Move to a dedicated node when you hit rate limits, need archive or trace access, or require predictable throughput. See supported RPC networks and RPC pricing for options.
Frequently Asked Questions
What is the difference between an Ethereum RPC provider and a node provider?
In practice they overlap. A node provider runs the Ethereum clients; an RPC provider exposes them over JSON-RPC. Most managed services do both, so the terms are often used interchangeably.
Do I need an archive node for Ethereum?
Only if you query historical state or logs beyond the recent window. Wallets and simple dapps usually do not. Indexers, analytics tools, and bridges often do.
Can I use a public Ethereum RPC endpoint in production?
Public endpoints are shared and rate-limited, so they are best for testing. Production apps generally use a managed RPC API or a dedicated node for predictable behavior.
Does OnFinality support Ethereum WebSocket subscriptions?
Ethereum on OnFinality supports HTTP and WebSocket transports. Check the Ethereum network page for current endpoint details and plan options.
How do I switch providers without rewriting my app?
Because Ethereum JSON-RPC is standardized, you usually only change the endpoint URL and API key. Keep your RPC URL in configuration, not hardcoded, so migration is a config change rather than a code change.
When should I move from shared RPC to a dedicated node?
When you consistently hit rate limits, need archive or trace methods, or require stable throughput for launches and trading windows. Dedicated nodes isolate your capacity from other tenants.
Related resources
Originally published at OnFinality.
Top comments (0)