LinkPool

Back to all posts

What is an RPC node, and what it takes to run one on a busy chain

An RPC node is a server that accepts requests from applications and wallets, translates them into blockchain operations, and returns the result. It reads chain data such as balances, blocks and contract state, and it broadcasts signed transactions to the network. Every wallet connection and every dashboard load goes through one.

That definition is where most explanations stop, and it is the part that matters least once you are responsible for keeping one running. The harder question is what an RPC node needs in order to keep answering correctly when the chain it serves gets busy.

Monad's transaction volume and app count have both climbed sharply since mainnet, which reads as a growth story for the people trading on it and a capacity event for everyone serving its data.

Transaction rate is the input. Request volume is what actually lands on your RPC nodes, and the two are different numbers. Teams that size on the first one get surprised by the second.

An RPC node is not a validator node

The two get conflated and they do different jobs. A validator node takes part in consensus. It proposes and attests to blocks, it holds a signing key, and it is penalised if it misbehaves or drops offline. An RPC node takes no part in consensus and holds no stake. It serves data.

That difference drives how you run each one. A validator is judged on signing reliability and key security. An RPC node is judged on how fast and how correctly it answers a query, and its failure mode is quieter: it can answer every request successfully while serving state that is several blocks out of date.

Request volume is a multiple of transaction volume

One user action in a front end is rarely one call. A single swap can trigger a chain id check, a block number, two or three balance reads, an allowance check, a gas estimate, a simulation, then receipt polling until it confirms. Wallets poll in the background. Dashboards hold open subscriptions. Indexers backfill. Bots poll harder than any human.

So the number that drives your sizing is not transactions per second. It is calls per user action, multiplied by concurrent actions, plus everything polling on a timer whether or not anyone is using the app.

This is why the number of applications on a chain matters more than its transaction count. Each app arrives with its own polling pattern, and you inherit all of them at once.

The measurement is cheap to do and most teams skip it. Instrument your own front end and count the calls behind one completed user action. Then find your peak hour against your daily mean rather than assuming demand is flat. Size against the peak, not the average, because the average never breaks anything.

Index depth is the second axis

Depth gets less attention than throughput and quietly costs more.

A busy chain accumulates state and logs fast, and the queries that read history do not get cheaper as it grows. Wide block-range log queries, trace calls, and historical balance lookups all scale with how much chain there is behind you. An indexer backfilling a chain that has been busy for months will hammer the archive tier in a way that normal traffic never does.

Two consequences worth planning for. Archive storage growth is continuous rather than stepped, so budget it as a rate and not a one-off. And heavy historical reads compete with light reads for the same node unless you deliberately separate them. We covered the storage side of this in our archive node hosting cost comparison.

Egress is metered and busy chains move a lot of it

A public endpoint serving a busy chain produces a lot of outbound data. On hyperscalers that data is billed per gigabyte, so the cost line most teams forget grows in direct proportion to how well the app is doing.

It is worth modelling before launch rather than reading it off an invoice. We broke the egress maths down in our RPC endpoint hosting cost comparison, and it is regularly the line that decides whether a busy endpoint is affordable.

Replica count decides reliability as much as throughput

Adding replicas to absorb load is the obvious move. The less obvious part is which calls each replica serves.

One expensive historical query can occupy a node long enough to starve the light reads queued behind it. The front end then feels slow even though the node is healthy and your request rate is well inside capacity. Splitting pools by call class fixes this: light reads on one pool, heavy historical work on another, subscriptions on a third. Each pool then needs its own spare capacity, because failover is per pool and not per cluster.

Sync lag is the metric to alert on. A node that is a few blocks behind still answers every request successfully, and it answers them wrong. Request-rate dashboards will show green while users see stale balances.

How you know an RPC node has stopped coping

The failure is gradual, which is what makes it easy to miss. The signals, roughly in the order they appear:

  • p99 latency climbs while the mean stays flat, because a small share of calls are queuing behind heavy ones
  • rate-limit responses start appearing during peak hours only
  • batch requests time out before individual calls do
  • the head block served drifts behind the actual chain head
  • subscription delivery starts lagging, so event-driven flows fire late

The user-facing version arrives before any of your dashboards go red. Quotes stop matching execution. Balances look wrong for a few seconds. Transactions appear to vanish and then confirm. Users blame the app, because from where they sit the app is what failed.

What an RPC node requires before the traffic arrives

Requirements for an RPC node are usually quoted as hardware: cores, memory, disk. Those matter, and they are the easy part, because a vendor will tell you them. The four requirements below are the ones that decide whether the node holds up, and they are much cheaper to settle in advance than during a spike.

Your call budget per user action. If you do not know it, you cannot size anything, and you cannot tell whether a traffic increase or a code change caused the load.

Which call classes get separate pools. Light reads, heavy historical, and subscriptions have different failure modes and should not share capacity.

Your headroom target. Pick the multiple of current peak you want to be able to absorb without changing anything, then hold it as capacity grows.

What your bill does under a spike. This one catches teams out. Credit and compute-unit billing means a traffic spike arrives as an invoice as well as an incident. Fixed request-per-second pricing means the number is known in advance. We price RPC at a fixed sustained request rate with no monthly cap and no overage charges. The point of capacity planning is removing surprises, and a variable bill puts one straight back in.

If you are still deciding whether to run the endpoint yourself at all, the trade-offs are in our self-hosted versus managed RPC breakdown.

The short version

An RPC node is simple to describe and harder to keep healthy. A chain getting busy creates four separate problems for it: more calls, deeper history, more egress, and less tolerance for one slow query. Size for calls rather than transactions, separate the call classes, alert on sync lag rather than error rate, and know what a spike does to the bill before it happens.

The work is cheap to do before the traffic arrives. Every part of it costs more once the endpoint is already struggling and someone is asking why quotes do not match execution.