Scaling Infrastructure
Strategies for scaling RPC endpoints, load balancing, caching, and handling high-traffic blockchain applications.
Scaling Strategies
Load Balancing
Distribute RPC requests across multiple nodes to handle high traffic.
Benefits
Tools
Caching Layer
Cache frequently requested data to reduce node load and improve response times.
Benefits
Tools
Read Replicas
Use multiple read-only nodes to scale read operations independently.
Benefits
Tools
Connection Pooling
Reuse connections to nodes instead of creating new ones for each request.
Benefits
Tools
Nginx Load Balancer
upstream ethereum_nodes {
least_conn; # Route to node with fewest connections
server node1.internal:8545 weight=5;
server node2.internal:8545 weight=5;
server node3.internal:8545 weight=3 backup;
keepalive 32;
}
# Rate limiting zone
limit_req_zone $binary_remote_addr zone=rpc_limit:10m rate=100r/s;
server {
listen 80;
server_name rpc.yourdomain.com;
location / {
# Rate limiting
limit_req zone=rpc_limit burst=50 nodelay;
# Proxy settings
proxy_pass http://ethereum_nodes;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Timeouts
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# CORS headers
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Content-Type' always;
if ($request_method = 'OPTIONS') {
return 204;
}
}
# Health check endpoint
location /health {
access_log off;
return 200 "OK";
}
}Least Connections
Routes to node with fewest active connections
Rate Limiting
100 req/s with burst of 50 per IP
Keep-Alive
Connection pooling for better performance
RPC Response Caching
Many RPC methods return immutable data or data that can be safely cached for short periods. Implementing a caching layer can dramatically reduce load on your nodes.
| Method | TTL | Notes |
|---|---|---|
eth_chainId | ∞ | Chain ID never changes |
eth_blockNumber | 1-3s | Cache for block time |
eth_getBlockByNumber (finalized) | ∞ | Finalized blocks are immutable |
eth_getTransactionReceipt | ∞ | Receipts are immutable |
eth_getBalance | ~12s | Cache per block |
eth_call | ~12s | Cache per block for same params |
eth_gasPrice | 3-10s | Short cache for gas estimates |
eth_getLogs | ∞ | Historical logs are immutable |
import Redis from 'ioredis';
const redis = new Redis(process.env.REDIS_URL);
const CACHE_TTL: Record<string, number> = {
'eth_chainId': -1, // Infinite
'eth_blockNumber': 3, // 3 seconds
'eth_gasPrice': 10, // 10 seconds
'eth_getBlockByNumber': -1, // Infinite for finalized
'eth_getTransactionReceipt': -1 // Infinite
};
export async function cacheMiddleware(method: string, params: any[]) {
const ttl = CACHE_TTL[method];
if (ttl === undefined) return null; // Not cacheable
const cacheKey = `rpc:${method}:${JSON.stringify(params)}`;
// Try cache first
const cached = await redis.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Call node
const result = await callNode(method, params);
// Cache result
if (ttl === -1) {
await redis.set(cacheKey, JSON.stringify(result));
} else {
await redis.setex(cacheKey, ttl, JSON.stringify(result));
}
return result;
}Multi-Region Architecture
For global applications, deploy nodes in multiple regions and route users to the nearest one:
US East
Primary region
EU West
European users
Asia Pacific
Asian users
Use GeoDNS or Cloudflare Load Balancing:
rpc.yourdomain.com → Routes to nearest region based on user IPWebSocket Considerations
WebSocket connections for subscriptions (newHeads, logs) require special handling:
Sticky Sessions
Use session affinity to keep WebSocket connections on the same node
Connection Limits
Set limits per node (typically 1000-5000 concurrent connections)
Pub/Sub Fan-out
Consider using Redis pub/sub to fan out events from a single node subscription
WebSocket Load Balancing
Standard HTTP load balancers may not work well with WebSockets. Use sticky sessions or dedicated WebSocket proxies like Nginx with ip_hash.
Capacity Planning
| Scale | Requests/sec | Nodes | Infrastructure |
|---|---|---|---|
| Small | < 100 | 1-2 nodes | Single node with backup |
| Medium | 100 - 1,000 | 3-5 nodes | Load balancer + caching |
| Large | 1,000 - 10,000 | 10-20 nodes | Multi-region + aggressive caching |
| Enterprise | > 10,000 | 50+ nodes | Custom solution / managed service |