Back to Infrastructure

Scaling RPC Infrastructure

Learn strategies for scaling your blockchain infrastructure to handle millions of requests. Load balancing, caching, and high-availability patterns.

Scaling Strategies

Load Balancing

Distribute requests across multiple nodes for high availability

Redundancy & Performance

Caching Layer

Cache frequent RPC responses to reduce node load

10x+ Response Speed

Read Replicas

Separate read and write operations across nodes

Horizontal Scaling

Geographic Distribution

Deploy nodes in multiple regions for lower latency

Global Performance

Scalable Architecture

Client Applications

Your dApps, scripts, and services

Layer 1

Load Balancer

HAProxy, nginx, or cloud LB

Layer 2

Caching Layer

Redis, Memcached

Layer 3

RPC Nodes

Multiple execution + consensus clients

Layer 4

Load Balancer Setup (nginx)

nginx.conf
upstream eth_nodes {
    # Round-robin load balancing
    server node1:8545 weight=1;
    server node2:8545 weight=1;
    server node3:8545 weight=1 backup;  # Failover node

    # Health checks
    keepalive 32;
}

server {
    listen 80;
    server_name rpc.example.com;

    location / {
        proxy_pass http://eth_nodes;
        proxy_http_version 1.1;
        proxy_set_header Connection "";

        # Timeouts
        proxy_connect_timeout 10s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;

        # Buffer settings
        proxy_buffer_size 4k;
        proxy_buffers 8 16k;

        # Rate limiting
        limit_req zone=rpc burst=100 nodelay;
    }

    # Health check endpoint
    location /health {
        access_log off;
        return 200 "healthy\n";
    }
}

# Rate limiting zone
limit_req_zone $binary_remote_addr zone=rpc:10m rate=100r/s;

RPC Caching Strategy

Not all RPC methods should be cached. Here's a guide for common methods:

MethodTTLCacheableReason
eth_chainIdNever changes
eth_blockNumber1-2sChanges every block
eth_getBlockByNumberFinalized blocks immutable
eth_getBalance12sCache per block
eth_call12sState dependent on block
eth_sendRawTransactionNeverAlways process
eth_subscribeNeverWebSocket stream

Redis Caching Layer

Cache Middleware (Node.js)
const Redis = require('ioredis');
const redis = new Redis();

const CACHE_TTL = {
  'eth_chainId': -1,  // Never expires
  'eth_blockNumber': 2,
  'eth_getBlockByNumber': -1,
  'eth_getBalance': 12,
  'eth_call': 12,
};

async function cachedRpc(method, params) {
  const ttl = CACHE_TTL[method];

  // Skip non-cacheable methods
  if (ttl === undefined) {
    return await forwardToNode(method, params);
  }

  const key = `rpc:${method}:${hash(params)}`;
  const cached = await redis.get(key);

  if (cached) {
    return JSON.parse(cached);
  }

  const result = await forwardToNode(method, params);

  if (ttl === -1) {
    await redis.set(key, JSON.stringify(result));
  } else {
    await redis.setex(key, ttl, JSON.stringify(result));
  }

  return result;
}

Cache Benefits

  • • Reduce node load by 80%+
  • • Sub-millisecond response times
  • • Handle traffic spikes gracefully
  • • Reduce costs on RPC providers

Cache Considerations

  • • Invalidate on chain reorgs
  • • Consider block-based TTLs
  • • Monitor cache hit rates
  • • Set memory limits

High Availability Patterns

Active-Active

All nodes handle traffic simultaneously. Best for high throughput.

+ Maximum capacity

+ No wasted resources

- Complex state management

Active-Passive

Primary handles traffic, standby takes over on failure.

+ Simple failover

+ Consistent performance

- 50% capacity unused

Multi-Region

Nodes in different geographic regions for global coverage.

+ Low latency globally

+ Disaster recovery

- Higher complexity

Performance Benchmarks

50k+

Requests/second

With caching

<5ms

Cache hit latency

P95 response time

99.9%

Availability

Multi-node setup

80%

Cache hit rate

Typical workload

Scaling Best Practices

Do

  • • Start with caching before adding nodes
  • • Use connection pooling
  • • Implement graceful degradation
  • • Set up comprehensive monitoring
  • • Use async/batch requests when possible
  • • Test failover scenarios regularly

Don't

  • • Over-provision without measuring first
  • • Ignore connection limits
  • • Cache transaction submissions
  • • Skip health checks on load balancers
  • • Use single points of failure
  • • Forget about WebSocket scaling

Need Enterprise-Scale Infrastructure?

ChainLens provides auto-scaling RPC infrastructure that handles millions of requests.