Summary
An ETH public RPC is a shared, unauthenticated JSON-RPC endpoint that lets any developer read Ethereum data and broadcast transactions without running a node. It is ideal for prototyping, wallet configuration, and low-volume scripts, but shared capacity and rate limits make it a poor fit for production workloads that need consistent throughput, archive data, or WebSocket subscriptions.
This page explains how to connect to an Ethereum public RPC, how to verify it works, and the exact signals that tell you it is time to move to a managed or dedicated endpoint. It also covers chain settings, common failure modes, and a practical migration path to OnFinality RPC when your app outgrows the public tier.
When a public ETH RPC is the right starting point
A public RPC is the fastest way to get an Ethereum app talking to the chain. You paste a URL into your wallet, script, or framework config, and you can read balances, fetch blocks, and send transactions without provisioning anything. For a hackathon prototype, a one-off script, or a wallet you are configuring for the first time, that is exactly the right tradeoff.
The decision to stay on a public endpoint is really a question about workload shape. If your requests are occasional, tolerant of retries, and never depend on subscriptions, a shared public RPC can carry you a long way. If your app serves real users, indexes history, or listens for events, the shared tier will become the bottleneck.
Use this quick guide to decide where you are today:
| Your situation | Public RPC fit | What to do next |
|---|---|---|
| Learning JSON-RPC, testing a wallet | Good | Use a public endpoint, keep request volume low |
| Local scripts, CI smoke tests | Acceptable | Add retries and a fallback URL |
| dApp with live users | Poor | Move to a managed RPC plan |
| Indexer, analytics, or archive queries | Poor | Use an archive-capable endpoint |
| Bots, event listeners, WebSocket subscriptions | Poor | Use a dedicated or managed node with WS |
If you are in the bottom three rows, the rest of this page explains the migration. If you are in the top two, read on for the endpoint details and debugging steps.
Ethereum chain settings at a glance
Before you debug anything, confirm you are pointed at the right network. Ethereum mainnet and Sepolia share the same JSON-RPC method set but have different chain IDs, and mixing them up is one of the most common causes of "wrong network" errors.
| Setting | Ethereum mainnet | Ethereum Sepolia |
|---|---|---|
| Chain ID | 1 | 11155111 |
| Chain name | Ethereum Mainnet | Ethereum Sepolia |
| Native currency | ETH (18 decimals) | Sepolia Ether (18 decimals) |
| Block explorer | https://etherscan.io | https://sepolia.etherscan.io |
| OnFinality public RPC | https://eth.api.onfinality.io/public | https://eth-sepolia.api.onfinality.io/public |
| Transport | HTTP, WebSocket | HTTP, WebSocket |
OnFinality exposes public endpoints for both networks, so you can develop against Sepolia and switch to mainnet by changing a single URL and chain ID. For network-specific details, see the Ethereum Sepolia network page and the full supported RPC networks list.
Connecting a wallet or framework
Most wallets and libraries accept a custom RPC URL plus a chain ID. A minimal wallet network configuration looks like this:
{
"chainId": "0x1",
"chainName": "Ethereum Mainnet",
"nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
"rpcUrls": ["https://eth.api.onfinality.io/public"],
"blockExplorerUrls": ["https://etherscan.io"]
}
For Sepolia, change chainId to 0xaa36a7 (11155111 in decimal) and swap the RPC URL to the Sepolia endpoint. In JavaScript, the same config works with ethers or viem:
import { createPublicClient, http } from 'viem';
import { mainnet } from 'viem/chains';
const client = createPublicClient({
chain: mainnet,
transport: http('https://eth.api.onfinality.io/public')
});
const blockNumber = await client.getBlockNumber();
console.log('Latest block:', blockNumber);
If you prefer raw JSON-RPC, a single curl call confirms the endpoint is reachable and returning the chain you expect:
curl -s https://eth.api.onfinality.io/public \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
The response should be {"jsonrpc":"2.0","id":1,"result":"0x1"}. If you get a different chain ID, you are on the wrong network. If you get an empty result or an HTTP error, the endpoint is unreachable or rate limited.
Debug path: what each failure actually means
Public endpoints fail in a small number of predictable ways. Match the symptom to the cause before you change anything.
| Symptom | Likely cause | Fix |
|---|---|---|
429 Too Many Requests | Shared rate limit exceeded | Back off, batch requests, or move to a managed plan |
-32005 or "limit exceeded" | Per-method or per-IP quota | Reduce polling frequency, cache results |
Empty result for old blocks | No archive data on the shared tier | Use an archive-capable endpoint |
| WebSocket disconnects | Idle timeout or shared connection limits | Reconnect with backoff or use a dedicated node |
eth_getLogs timeouts | Wide block ranges on shared capacity | Narrow the range or paginate |
| Wrong chain ID | Mainnet/Sepolia mismatch | Correct the URL and chain ID |
A useful habit is to log the HTTP status and JSON-RPC error code together. A 429 is a capacity signal, while a -32601 (method not found) is a capability signal. They point to different fixes.
Where public endpoints stop scaling
Shared public RPCs are designed for broad, low-intensity access. Three workload patterns break that model quickly:
- High-frequency polling. Wallets and dashboards that poll
eth_blockNumberoreth_getBalanceevery second will hit shared limits fast. Batch or cache instead. - Historical and archive queries. Reading state at an old block requires an archive node. Most public endpoints serve recent state only.
- Event-driven apps. WebSocket subscriptions (
eth_subscribe) need a stable, long-lived connection. Shared endpoints often cap concurrent sockets or drop idle ones.
If any of these describe your app, the public tier is a prototyping tool, not a production dependency. The next section covers what to evaluate when you move.
Evaluating a managed or dedicated ETH RPC
When you outgrow the public endpoint, you are choosing between a managed RPC plan and a dedicated node. Both remove the shared-capacity problem; they differ in control, cost model, and operational burden.
| Provider option | Best for | Archive / trace | WebSocket | Operational load |
|---|---|---|---|---|
| OnFinality RPC API | Teams that want managed Ethereum endpoints with predictable capacity | Available on request | Supported | Low — managed for you |
| OnFinality dedicated nodes | High-volume or compliance-sensitive workloads needing isolated capacity | Configurable | Supported | Low — OnFinality operates the node |
| Self-hosted node | Teams with strict data-residency or custom fork needs | Full control | Full control | High — you run and upgrade it |
| Other shared providers | Low-cost, low-volume apps | Varies | Often limited | Low |
OnFinality is listed first because it is the option this site operates: managed RPC endpoints plus dedicated node infrastructure for teams that need isolated capacity. Compare plans on the RPC pricing page, or review dedicated nodes if you need a private node rather than a shared endpoint.
When you evaluate any provider, ask four questions:
- Capacity model: Is throughput shared or reserved? What happens during a traffic spike?
- Method coverage: Are
debug_andtrace_methods available, and is archive data included? - Transport: Is WebSocket supported for subscriptions, and how are idle connections handled?
- Failover: Can you configure a secondary endpoint, and how do you detect a degraded primary?
These questions matter more than headline latency numbers, because they determine whether your app stays up under load.
Migration checkpoints
Moving from a public endpoint to a managed one is mostly a configuration change, but a few checkpoints prevent surprises:
- Inventory your methods. List every JSON-RPC method your app calls, including
eth_getLogs,eth_call, and anydebug_ortrace_usage. Confirm the new endpoint supports all of them. - Separate read and write paths. Reads can often use a shared endpoint; writes and subscriptions benefit from a dedicated connection.
- Add a fallback. Configure a secondary RPC URL so a single endpoint failure does not take down your app.
- Re-test on Sepolia first. Validate the new endpoint against Sepolia before switching mainnet traffic.
- Monitor after cutover. Track error rates,
429counts, and WebSocket reconnects for the first few days.
A simple monitoring probe keeps you honest:
async function probe(url) {
const start = Date.now();
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [] })
});
return { ok: res.ok, status: res.status, ms: Date.now() - start };
}
Run this against both your primary and fallback endpoints on a schedule, and alert when either degrades.
Key Takeaways
- An ETH public RPC is a shared, unauthenticated endpoint — great for prototyping, weak for production.
- Always confirm chain ID:
0x1for mainnet,0xaa36a7for Sepolia. 429errors mean capacity; empty archive results mean missing history; WebSocket drops mean connection limits.- Move to a managed or dedicated endpoint when you poll frequently, need archive data, or rely on subscriptions.
- Evaluate providers on capacity model, method coverage, transport, and failover — not just latency.
- OnFinality offers managed Ethereum RPC and dedicated nodes; see RPC pricing and supported networks.
Frequently Asked Questions
Is a public ETH RPC safe to use in production?
It can work for low-volume, read-only traffic with retries and a fallback. For user-facing apps, high-frequency polling, archive queries, or WebSocket subscriptions, a managed or dedicated endpoint is the more reliable choice.
What is the chain ID for Ethereum mainnet and Sepolia?
Ethereum mainnet uses chain ID 1 (0x1). Sepolia uses chain ID 11155111 (0xaa36a7). Setting the wrong one is a common cause of "wrong network" errors.
Why does my public RPC return empty results for old blocks?
Most public endpoints serve recent state only. Reading historical state requires an archive node, which is typically available on managed or dedicated plans.
Can I use WebSocket subscriptions on a public RPC?
Some public endpoints expose WebSocket, but shared connection limits and idle timeouts make them unreliable for long-lived subscriptions. Use a managed or dedicated endpoint for event-driven apps.
How do I switch from a public RPC to OnFinality?
Change your RPC URL and chain ID in your wallet or framework config, confirm method coverage, add a fallback endpoint, and test on Sepolia before moving mainnet traffic. See RPC pricing for plan details.