Production tips for Yellowstone gRPC on Solana — filter subscriptions, handle reconnects, manage backpressure, and tune commitment levels for low latency.
Latency starts at the network level. No matter how optimized your code is, the speed of light remains the ultimate bottleneck. The single most impactful action you can take to minimize latency is to achieve geographical co-location with the gRPC endpoint.
Target: 0-1 milliseconds network latencyAim for sub-millisecond ping between your client application and the gRPC endpoint.
It’s possible to achieve 1-2 ms latency without co-locating if you’re in the same region. Use these tools to measure your latency:
# Test ping to EU endpointping grpc.solanatracker.io# Test ping to US endpointping grpc-us.solanatracker.io# Detailed route analysismtr grpc.solanatracker.io
Streaming multiple high-load addresses (e.g., Meteora DLMM, Pump.fun, DEX programs) in a single subscription can quickly overwhelm a single client connection.Problems with single client:
Message backlog at network layer
Single consumer thread bottleneck
Client may disconnect due to unmanageable backlog
Best Practice: Split high-load addresses across multiple gRPC clients and distribute processing across separate CPU cores/threads.
// Separate client for each high-volume programconst raydiumClient = new Client(endpoint, token);const jupiterClient = new Client(endpoint, token);const pumpfunClient = new Client(endpoint, token);// Process on different threads/coresawait Promise.all([ processRaydiumStream(raydiumClient), processJupiterStream(jupiterClient), processPumpfunStream(pumpfunClient)]);
Over-fragmenting your connections for moderate-load addresses can quickly hit connection limits.
Best Practice: Don’t create a new connection for each token, pool, or wallet address. Combine them in a single subscribe request.
Example of efficient connection planning:
class ConnectionManager { private highLoadClients: Map<string, Client> = new Map(); private moderateLoadAddresses: string[] = []; async initialize() { // Separate clients for high-load programs this.highLoadClients.set('raydium', new Client(endpoint, token)); this.highLoadClients.set('jupiter', new Client(endpoint, token)); this.highLoadClients.set('pumpfun', new Client(endpoint, token)); // Track moderate-load addresses together this.moderateLoadAddresses = []; } async addModerateLoadAddress(address: string) { this.moderateLoadAddresses.push(address); // Send this request on your active stream, or reconnect with it. return { accounts: { moderate: { account: this.moderateLoadAddresses, owner: [], filters: [] } } }; }}
When your address list changes, send an updated subscribe request on the active stream if your client supports it. If not, close the stream and reconnect with the new combined request.
Yellowstone gRPC clients have a default maximum size of 4 MB (4194304 bytes) for incoming messages. When streaming account updates or block updates, you can hit this limit.
Required: Configure your gRPC client to avoid hitting the 4 MB message limit.