All Blog Posts
What Is RPC in Blockchain? How Remote Procedure Calls Power Every dApp

What Is RPC in Blockchain? How Remote Procedure Calls Power Every dApp

By Dwellir 7th April 2026 18min read

You connect MetaMask to a dApp. A balance appears. You swap a token, and a confirmation pops up 12 seconds later. Behind every one of those interactions - the balance check, the gas estimate, the transaction broadcast, the receipt confirmation - your application made an RPC call to a blockchain node. Every read and every write to any EVM chain goes through RPC.

RPC (Remote Procedure Call) is a protocol that lets one program execute a function on another machine over a network. In blockchain, RPC is how applications communicate with nodes. A wallet checking ETH balances makes eth_getBalance calls. A DEX displaying token prices makes eth_call to read smart contracts. A deployment script submitting a contract makes eth_sendRawTransaction. Each of these is a remote procedure call to a node that holds blockchain state.

This guide covers how blockchain RPC works from protocol to production: the JSON-RPC format, essential Ethereum methods, transport trade-offs (HTTP vs WebSocket), provider evaluation criteria, and working code examples in curl, JavaScript, and Python.

What Is a Remote Procedure Call?

Bruce Jay Nelson coined "Remote Procedure Call" in his 1981 PhD dissertation at Xerox PARC. The core idea: let a program call a function on a remote machine as if it were local. The caller does not manage socket connections, serialization, or protocol details. A client stub serializes the function name and arguments, sends them over the network, and a server stub on the remote machine deserializes and executes the call. The result travels back the same way.

RPC became foundational across distributed systems. Sun RPC, gRPC, XML-RPC, and JSON-RPC all descend from this concept. In each case, the developer writes what looks like a local function call, and the RPC framework handles the network transport.

In blockchain, the node is the remote server. Your dApp, wallet, or script is the client. JSON-RPC is the protocol that structures requests and responses. When you call eth_getBalance, you are making a remote procedure call to a node that holds blockchain state.

How Blockchain RPC Works

Article Image

Every blockchain interaction follows the same five-step flow. This is the path from your code to on-chain data and back:

  1. Your application constructs a JSON-RPC request with a method name and parameters (e.g., eth_getBalance with an address and block number).
  2. The request is sent via HTTP or WebSocket to an RPC endpoint URL.
  3. The endpoint routes the request to a blockchain node running client software (Geth, Nethermind, Reth, Besu, or another implementation).
  4. The node executes the requested operation - reading state from its database, simulating a call against the EVM, or broadcasting a signed transaction to the peer-to-peer network.
  5. The node returns a JSON-RPC response containing the result (a balance, a transaction hash, a block) or an error.

This happens constantly. A block explorer displaying chain data makes thousands of RPC calls per second. Your Hardhat deployment script submitting a contract is an eth_sendRawTransaction followed by polling eth_getTransactionReceipt. The entire Web3 application layer runs on this request-response loop.

What Is an RPC Endpoint?

Two terms get used interchangeably but mean different things:

An RPC node is a server running blockchain client software (Geth, Nethermind, Reth, Erigon) that maintains a copy of the blockchain and exposes an RPC interface to accept external requests.

An RPC endpoint is the URL your application sends requests to - for example, https://api-ethereum-mainnet.n.dwellir.com/<API_KEY>. An endpoint can point to a single node, or to a load balancer distributing requests across hundreds of nodes in multiple regions.

Node Types and What They Store

Not all nodes hold the same data. The type of node behind your RPC endpoint determines what queries it can answer.

Article Image

The distinction matters in practice. Querying "what was this address's balance at block 1,000,000?" requires an archive node. A full node can only answer for recent blocks. Many providers gate archive access behind premium tiers or charge 2-3x higher rates for archive queries. Some, like Dwellir, include archive access on all paid plans at no extra cost.

JSON-RPC - The Protocol Behind Every Blockchain Call

Ethereum and most EVM-compatible chains use JSON-RPC 2.0, a stateless, transport-agnostic protocol that structures requests and responses as JSON objects. Every request contains 4 fields:

  • jsonrpc - Always "2.0"
  • method - The RPC method name (e.g., eth_blockNumber)
  • params - An array of parameters (can be empty)
  • id - A unique identifier to match responses to requests

Here is a real, copy-pasteable request for eth_blockNumber - the simplest RPC call, which returns the latest block number on the chain:

BASH
curl -X POST https://ethereum-rpc.publicnode.com \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

The response:

JSON
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x13f8e6a"
}

All Ethereum RPC values are hex-encoded with a 0x prefix. 0x13f8e6a converts to 20,906,602 in decimal. Balances, block numbers, gas values, and nonces all use this encoding. Libraries like ethers.js and web3.py handle the conversion automatically, but when working with raw JSON-RPC, expect hex everywhere.

When something goes wrong, the response includes an error object with code, message, and optional data fields instead of a result. Standard error codes are defined in the JSON-RPC 2.0 specification - the troubleshooting section below covers the ones you will encounter most.

Essential Ethereum JSON-RPC Methods

These are the methods that cover 90% of Ethereum application development. Each one maps to a specific node operation.

MethodWhat It DoesExample Use
eth_blockNumberReturns the latest block numberSyncing status, block explorers
eth_getBalanceReturns an address's ETH balance in weiWallet balance display
eth_callExecutes a read-only smart contract call without creating a transactionReading ERC-20 token balances, checking prices
eth_sendRawTransactionSubmits a signed transaction to the networkToken transfers, contract interactions
eth_getTransactionReceiptReturns the receipt of a mined transaction (null if pending)Confirming transaction success/failure
eth_getLogsReturns event logs matching a filter (address, topics, block range)Monitoring token transfers, contract events
eth_estimateGasEstimates gas needed for a transactionSetting gas limits before submission
eth_gasPriceReturns the current gas price in weiFee estimation
eth_getBlockByNumberReturns block data by number (with or without full transactions)Block explorers, chain analysis
eth_subscribeCreates a real-time subscription over WebSocketLive transaction monitoring, new block alerts

Read-only calls (eth_call, eth_getBalance, eth_getLogs) do not require a signed transaction or spend gas. State-changing operations (eth_sendRawTransaction) require the transaction to be signed client-side before submission. The node never sees your private key.

For the complete Ethereum JSON-RPC method reference with parameter details, see Dwellir's Ethereum documentation.

RPC Beyond Ethereum

JSON-RPC is the dominant protocol across blockchains, but method names, data encoding, and chain-specific concepts differ by ecosystem.

Solana

Solana uses JSON-RPC 2.0 with its own method namespace: getBalance, getTransaction, sendTransaction, getSlot. The distinctive feature is commitment levels - every read request accepts a commitment parameter (processed, confirmed, finalized) controlling the finality guarantee of returned data. processed is fastest but might be rolled back. finalized is slower but irreversible. Balances are returned in lamports (1 SOL = 1,000,000,000 lamports).

Substrate and Polkadot

Substrate-based chains use namespaced JSON-RPC methods: chain_getBlock, state_getStorage, system_health, author_submitExtrinsic. Storage values use SCALE encoding (a compact binary format) rather than ABI encoding. Transactions are called "extrinsics" - a term that extends to any externally-submitted data.

Sui

Sui uses JSON-RPC 2.0 with methods like sui_getObject and sui_executeTransactionBlock. The data model is object-centric rather than account-based - you query and manipulate objects, not account state. Sui is migrating toward gRPC and GraphQL.

The concept is the same across every chain: your application sends a structured request to a node and gets a structured response. The method names and data formats differ, but the RPC pattern is universal.

HTTP vs WebSocket - Choosing Your Transport

RPC calls travel over a transport protocol. The two options - HTTP and WebSocket - serve different use cases.

HTTP (HTTPS)WebSocket (WSS)
Connection modelNew connection per request (or reuse via HTTP/2)Persistent bidirectional connection
Data flowRequest-response onlyServer can push data to client
Real-time supportMust poll repeatedlyNative subscriptions (eth_subscribe)
Best forDiscrete queries, low-frequency readsReal-time monitoring, event streaming
OverheadHigher per-request (connection setup)Lower per-message once connected
Example methodseth_getBalance, eth_call, eth_sendRawTransactioneth_subscribe("newHeads"), eth_subscribe("logs")
Article Image

Use HTTP for most RPC calls - balance checks, transaction submissions, contract reads. These are discrete request-response operations that do not benefit from a persistent connection. Switch to WebSocket when you need real-time data: monitoring new blocks, watching for specific contract events, or tracking pending transactions in the mempool.

A common pattern in production: HTTP for all standard reads and writes, plus a single WebSocket connection for event subscriptions that trigger application logic (new block notifications, specific contract events, pending transaction alerts).

RPC vs REST vs GraphQL

Three API paradigms exist in the blockchain ecosystem, and you will likely use more than one.

JSON-RPC is action-oriented. You call methods directly (eth_getBalance, eth_sendRawTransaction), each mapping to a node operation. This is the native interface for talking to blockchain nodes.

REST is resource-oriented. Data is exposed as URLs: /blocks/123, /transactions/0xabc, /addresses/0xdef/balance. Block explorers like Etherscan expose REST APIs over indexed and enriched data. REST suits caching, browser access, and CRUD-style queries over processed blockchain data.

GraphQL lets clients specify exactly which fields they need in a single request, avoiding over-fetching. The Graph protocol uses GraphQL for querying indexed blockchain data across subgraphs - a strong fit for complex queries that span multiple entity types.

The rule of thumb: talking to a node directly? JSON-RPC. Querying indexed historical data? REST or GraphQL.

Running Your Own Node vs Using a Provider

You can run your own RPC infrastructure or use a managed provider. The trade-offs are significant.

Self-Hosting Reality Check

An Ethereum full node requires 8+ CPU cores, 32-64 GB RAM, a 4+ TB NVMe SSD, and 300+ Mbps bandwidth. Monthly cost for a single node: $300-600. A production setup with redundancy, load balancing, and geographic distribution runs $15,000-24,000/month once you factor in DevOps time and multi-region hosting.

Maintenance is ongoing. Ethereum averages 2 major client updates per year. Missing a hard fork means your node follows the wrong chain. Disk usage grows continuously - plan for regular pruning or storage expansion. And that covers a single chain. Every additional network requires its own infrastructure stack.

Managed Providers

Managed RPC providers handle node operations, uptime, fork upgrades, and scaling. Setup takes minutes instead of days, and a single API key covers multiple chains.

Self-HostedManaged Provider
Setup timeDays to weeksMinutes
Monthly cost (moderate volume)$300-600+ per chain$49-299
MaintenanceYou handle forks, updates, disk growthProvider handles it
UptimeYour responsibility99.9-99.99% SLA
Multi-chainSeparate infrastructure per chainSingle API key
CustomizationFull controlLimited to provider options
Data sovereigntyCompleteData passes through provider

Self-hosting makes sense when you need full control over node configuration, require data sovereignty for compliance, or run latency-sensitive MEV operations where every millisecond between your application and the node matters. For most teams, a managed provider is the practical choice.

For a deeper breakdown of what to evaluate, see 7 essential things you need to know about Ethereum RPC providers.

What to Look for in an RPC Provider

Not all RPC providers are equivalent. These are the criteria that matter most in production.

Pricing Transparency

Pricing is the biggest variable across providers. Some use compute units where different methods cost different amounts - an eth_call might cost 26 compute units while an eth_getLogs request costs 255. Your actual cost per request depends on your call mix, and a shift in usage patterns can spike your bill without any increase in total request volume.

Other providers charge a flat rate per request regardless of method complexity. Flat-rate pricing makes costs predictable and eliminates the need to optimize which methods your application calls. RPC providers without compute units breaks down the difference in detail.

Uptime and Reliability

Look for 99.9%+ uptime SLAs with response credits for downtime. Single-cloud providers carry concentration risk - an AWS outage can take down multiple RPC providers simultaneously because they share the same underlying infrastructure. Ask about multi-cloud and bare-metal strategies.

Latency

Sub-100ms p95 latency is the benchmark for production applications. Regional distribution matters more than raw average numbers - a provider with nodes in your users' geographic regions delivers lower latency than one with a faster global average but no presence near your users.

Rate Limits

Free tiers typically cap at 100-200 requests per minute. Production tiers range from 100 to 2,000+ requests per second depending on the plan. Burst capacity during traffic spikes (a token launch, a market crash, a viral mint) matters as much as sustained throughput.

Archive Data

If your application queries historical state (balances at past blocks, old event logs, historical contract storage), confirm that archive access is included in your plan. Some providers charge 2x or more for archive queries, or restrict archive access to enterprise tiers.

Chain Coverage

Multi-chain applications need a provider that supports all target networks. Coverage varies widely - from 30 networks at some providers to 150+ at others like Dwellir. Consolidating on a single provider simplifies key management, billing, and monitoring.

Making Your First RPC Call

Three practical examples, each querying the ETH balance of Vitalik Buterin's public address (0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045).

curl (works anywhere)

BASH
curl -X POST https://ethereum-rpc.publicnode.com \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_getBalance",
    "params": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest"],
    "id": 1
  }'

The response returns the balance in wei, hex-encoded. Divide by 10^18 to get ETH.

JavaScript (ethers.js v6)

JAVASCRIPT
import { JsonRpcProvider, formatEther } from 'ethers';

const provider = new JsonRpcProvider('https://ethereum-rpc.publicnode.com');
const balance = await provider.getBalance(
  '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'
);
console.log(`Balance: ${formatEther(balance)} ETH`);

Python (web3.py)

PYTHON
from web3 import Web3

w3 = Web3(Web3.HTTPProvider('https://ethereum-rpc.publicnode.com'))
balance = w3.eth.get_balance('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
print(f"Balance: {w3.from_wei(balance, 'ether')} ETH")

These examples use a public endpoint for demonstration. Public endpoints work for learning and testing, but production applications need a dedicated endpoint with an API key for higher rate limits, uptime guarantees, and support. Dwellir's free tier provides 5 million requests per month across 150+ networks to get started.

Common RPC Errors and How to Fix Them

These are the errors you will encounter most in development and production.

Error CodeMessageCommon CauseFix
-32700Parse errorMalformed JSON in request bodyValidate JSON before sending
-32600Invalid RequestMissing jsonrpc or method fieldCheck required fields
-32601Method not foundTypo in method name, or method not supported by nodeVerify method name and case sensitivity
-32602Invalid paramsMissing 0x prefix, wrong parameter count, block range too wideCheck hex encoding, reduce eth_getLogs block range
-32603Internal errorExecution reverted, bad payload, or node issueTest with eth_call first; check revert reason in error data
-32000Server errorBlock not found, nonce too low, filter expiredVerify node is synced; check nonce; recreate filters
HTTP 429Rate limitedToo many requests per secondImplement exponential backoff; cache stable values; batch requests

Rate limiting (HTTP 429) is the most common production issue. Three strategies help: cache values that change slowly (eth_chainId never changes, eth_blockNumber changes every ~12 seconds on Ethereum), batch independent requests into a single call, and implement exponential backoff with jitter on retries.

Advanced RPC Patterns

Batch Requests

JSON-RPC 2.0 supports sending an array of requests in a single HTTP call. Instead of 3 round trips, you make 1:

JSON
[
  {"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1},
  {"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 2},
  {"jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest"], "id": 3}
]

The server returns an array of responses. Match results to requests by id - response order is not guaranteed. Batching reduces round trips and works well for pages that need multiple pieces of chain data on load. One caveat: a single slow query (like a large eth_getLogs range) delays the entire batch response.

WebSocket Subscriptions

eth_subscribe over WebSocket enables real-time data streams without polling overhead. Three subscription types cover most use cases:

  • newHeads - Pushes block header data each time a new block is produced. Useful for updating UIs, triggering batch jobs, or tracking chain progress.
  • logs - Pushes filtered contract events as they are included in blocks. You specify an address and topics to match. This is how DeFi dashboards track swaps, transfers, and liquidity events in real time.
  • newPendingTransactions - Pushes transaction hashes as they enter the node's mempool. High-volume stream used for gas estimation and MEV detection. See the mempool guide for deep coverage of pending transaction monitoring.

gRPC

gRPC is an alternative transport that uses Protocol Buffers (binary serialization) instead of JSON text. The result: 3-10x smaller payloads and significantly faster serialization/deserialization compared to JSON-RPC. Solana's Yellowstone gRPC, Cosmos/Tendermint, and Sui all use gRPC for high-throughput data streaming.

For most dApp developers, JSON-RPC over HTTP and WebSocket covers all requirements. gRPC becomes relevant when you process high volumes of chain data - indexers, analytics pipelines, or infrastructure-level tooling.

Getting Started

The fastest way to start making RPC calls is with a free endpoint from any major provider. Most offer free tiers ranging from 3 to 30 million requests per month - enough to build and test applications before committing to a paid plan.

When evaluating production providers, pay attention to the pricing model. Compute-unit pricing means your cost varies by method - a debug_traceTransaction might cost 10-30x more than an eth_chainId. Flat-rate providers like Dwellir charge 1 credit per response regardless of method, which simplifies cost forecasting for applications with mixed call patterns.

To get started with Dwellir: register for a free account, create a project, and copy your endpoint URL. First RPC call in under 2 minutes.

Frequently Asked Questions

What does RPC stand for?

Remote Procedure Call - a protocol for executing functions on remote machines over a network. In blockchain, it is the standard interface between applications and nodes.

What is the difference between an RPC node and a full node?

An RPC node is a full node with its RPC interface enabled, allowing it to accept external requests over HTTP or WebSocket. Not all full nodes expose an RPC interface - some run only for peer-to-peer network participation.

Is JSON-RPC the same as REST?

No. JSON-RPC is action-oriented - you call methods (eth_getBalance). REST is resource-oriented - you access URLs (/blocks/123). Both use HTTP as a transport, but the interaction models differ. JSON-RPC sends all requests to a single endpoint with method names in the body; REST maps operations to distinct URLs and HTTP verbs.

Can I use a public RPC endpoint in production?

Not recommended. Public endpoints typically have low rate limits (often 100 requests per minute), no uptime guarantees, shared capacity with every other user, and no support. Use a dedicated endpoint with an API key for production applications.

What is the difference between HTTP and WebSocket RPC?

HTTP is request-response: you send a request, the node returns an answer. WebSocket maintains a persistent bidirectional connection where the node can push data to your application in real time - new blocks, contract events, pending transactions - without polling.

Do I need an archive node?

Only if your application queries historical blockchain state older than ~128 blocks. Current balances, recent transactions, and new contract events all work on standard full nodes. Historical balance lookups, old event log queries, and block explorer functionality require archive nodes.

How much does an RPC endpoint cost?

Free tiers exist at most providers, ranging from 3 to 30 million requests per month. Paid plans typically range from $49 to $999/month depending on volume and features. Self-hosting a single Ethereum full node costs $300-600/month in infrastructure alone, before accounting for maintenance time.

What is a compute unit in RPC pricing?

A compute unit (CU) is a billing metric some RPC providers use to weight different methods by complexity. A simple eth_blockNumber call might cost 1 CU, while eth_getLogs costs 20-255 CUs depending on the provider. The same total request count produces different bills depending on the method mix. Flat-rate providers charge the same per request regardless of method.

How do I handle RPC failover in production?

Configure at least two RPC endpoints from different providers. If your primary endpoint returns errors or exceeds latency thresholds, route requests to the backup. Most Web3 libraries support fallback providers - ethers.js has FallbackProvider, and viem supports fallback transports. This protects against single-provider outages.

read another blog post