Hey everyone,
If you are running on-chain indexers, snipers, or event listeners on Solana and still relying on standard JSON-RPC HTTP POST or default WebSocket subscriptions, you are taking an automatic 200ms+ penalty on every state update.
During high-volatility slots, public RPCs bottleneck hard on TCP connection churn, rate limits, and JSON string serialization overhead.
Here is a lean implementation using Yellowstone Geyser and Go to stream raw transaction and account updates over gRPC with sub-15ms latency.
The Core Problem
Minimal Zero-Allocation Consumer (Go)
This pipeline connects to a Yellowstone gRPC instance, applies server-side account filters, and streams updates directly without reflection overhead:
Benchmark Takeaways
If you are competing on execution speed on Solana, standard RPCs are dead weight.
Anyone else running direct validator feeds here, or are you primarily routing bundles via Jito?
If you are running on-chain indexers, snipers, or event listeners on Solana and still relying on standard JSON-RPC HTTP POST or default WebSocket subscriptions, you are taking an automatic 200ms+ penalty on every state update.
During high-volatility slots, public RPCs bottleneck hard on TCP connection churn, rate limits, and JSON string serialization overhead.
Here is a lean implementation using Yellowstone Geyser and Go to stream raw transaction and account updates over gRPC with sub-15ms latency.
The Core Problem
- Standard RPC: Validator -> RPC Node -> JSON Serialization -> HTTP/WS -> Client JSON Parse (heavy heap allocations, constant GC pressure).
- Geyser gRPC: Validator -> Yellowstone C++ Plugin -> Binary Protobuf Stream -> gRPC Client (zero-copy binary deserialization, zero disk wait).
Minimal Zero-Allocation Consumer (Go)
This pipeline connects to a Yellowstone gRPC instance, applies server-side account filters, and streams updates directly without reflection overhead:
Code
package main
import (
"context"
"crypto/tls"
"log"
"time"
pb "github.com/rpcpool/yellowstone-grpc/examples/golang/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
)
func main() {
endpoint := "your-geyser-endpoint.internal:10000"
kacp := keepalive.ClientParameters{
Time: 10 * time.Second,
Timeout: time.Second,
PermitWithoutStream: true,
}
creds := credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})
conn, err := grpc.Dial(
endpoint,
grpc.WithTransportCredentials(creds),
grpc.WithKeepaliveParams(kacp),
)
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewGeyserClient(conn)
stream, err := client.Subscribe(context.Background())
if err != nil {
log.Fatalf("Stream initialization failed: %v", err)
}
// Filter directly at the validator plugin level (zero client-side noise)
subReq := &pb.SubscribeRequest{
Accounts: map[string]*pb.SubscribeRequestFilterAccounts{
"target_program": {
Account: []string{"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"}, // Raydium AMM
},
},
Commitment: pb.CommitmentLevel_PROCESSED.Enum(),
}
if err := stream.Send(subReq); err != nil {
log.Fatalf("Subscription filter failed: %v", err)
}
log.Println("[+] Geyser stream live. Listening for slot events...")
for {
resp, err := stream.Recv()
if err != nil {
log.Printf("Stream interrupted: %v. Retrying...", err)
break
}
processSlotUpdate(resp)
}
}
func processSlotUpdate(update *pb.SubscribeUpdate) {
if accountUpdate := update.GetAccount(); accountUpdate != nil {
slot := accountUpdate.GetSlot()
pubkey := accountUpdate.GetAccount().GetPubkey()
dataSize := len(accountUpdate.GetAccount().GetData())
log.Printf("[Slot %d] Event: %x | Payload: %d bytes", slot, pubkey, dataSize)
}
}Benchmark Takeaways
- Network Latency: WebSocket events arrived at a median of ~210ms. Pointing this Go consumer to a collocated Geyser node dropped delivery time to 11ms - 14ms.
- CPU & Memory Footprint: Skipping json.Unmarshal in favor of binary Protobuf buffers eliminated slice churn and dropped memory consumption by ~75%.
- Throughput Stability: Zero dropped frames during peak slot contention, since stream backpressure is handled at the transport layer.
If you are competing on execution speed on Solana, standard RPCs are dead weight.
Anyone else running direct validator feeds here, or are you primarily routing bundles via Jito?


