UDP vs gRPC vs WebSocket for Solana data
UDP exposes fresh independent datagrams and leaves loss recovery and decoding to the receiver. gRPC provides typed, ordered streams with flow control and server-side filtering. WebSocket provides persistent, widely compatible message delivery, often through JSON-RPC. The right choice follows the required data product and overload behavior, not the transport label alone.
network desk · updated 2026-08-31
Three interfaces expose three different products
UDP, gRPC, and WebSocket are often compared as transport choices, but a Solana provider usually changes more than the transport. A raw UDP shred feed exposes packet-sized protocol data near the point of production. A gRPC feed commonly exposes decoded transactions, account updates, or validator events through an HTTP/2 stream. A WebSocket subscription commonly exposes JSON-RPC notifications after an RPC node has processed the relevant state.
Those pipelines start and end at different places. Comparing a raw shred's receive timestamp with a decoded WebSocket notification measures decoding, execution, serialization, provider queuing, and transport behavior together. That can be the correct product comparison, but it is not a transport benchmark.
Begin with the decision payload. If the application needs signed shreds and owns recovery and decoding, UDP is a direct fit. If it needs structured binary messages with schema evolution and server-side filtering, gRPC is attractive. If it needs broad compatibility, browser support, and RPC-style subscriptions, WebSocket is convenient. Latency, completeness, and engineering ownership follow from that boundary.
UDP exposes independent datagrams
UDP preserves message boundaries and offers no session, ordering, retransmission, congestion control, or backpressure. A receiver binds a port and processes each surviving datagram independently. A lost packet creates a gap, not a stalled stream. A duplicate remains visible, and reordering must be handled by the application.
This behavior matches raw Solana shreds. Each shred has protocol identity, and coding shreds can recover some missing data. A subscriber can process later shreds while an earlier one is absent. The feed does not wait for an acknowledgement from the destination. One underprovisioned subscriber therefore does not slow other subscribers.
The cost is operational ownership. The receiver needs firewall rules, socket buffer sizing, queue monitoring, gap detection, duplicate suppression, and a defined response to unrecoverable loss. It must accept traffic from the configured source, 64.130.40.90 for shredstream.sh, on the destination port. The provider cannot infer end-to-end health from a persistent transport connection because no such connection exists.
gRPC provides typed streaming over HTTP/2
gRPC defines services and messages with Protocol Buffers, then normally carries them over HTTP/2. A server-streaming method gives the client an ordered sequence of typed messages. HTTP/2 provides flow control, framing, and multiplexing over a reliable TCP connection. TLS is common, and authentication metadata fits established service patterns.
The type system is a substantial benefit. Generated clients reduce parsing ambiguity, optional fields can evolve under protobuf rules, and status codes give control-plane failures a shared vocabulary. Server-side filters can prevent irrelevant account or transaction data from crossing the network. These features reduce application work when the product is decoded data rather than raw packets.
Reliability changes tail latency. A lost TCP segment blocks bytes that follow on that connection until retransmission. HTTP/2 also has connection-level and stream-level flow-control windows. A client that stops reading eventually limits the server. Libraries may add message queues, decompression, deserialization, callbacks, and executor handoffs. Each layer is measurable and configurable, but none is free.
WebSocket provides a persistent message channel
WebSocket begins as an HTTP request, upgrades to a persistent TCP connection, and carries framed text or binary messages in both directions. Solana RPC commonly uses JSON-RPC subscription methods over this channel. Client ecosystems are broad, and operations teams understand TLS termination, proxies, load balancers, and connection health checks.
JSON messages are readable and easy to inspect. They are also larger than compact binary data and require parsing field names, numbers, arrays, and encoded payloads. Providers may batch, filter, or transform notifications. The subscription layer also inherits the RPC node's observation point, commitment settings, and execution pipeline. A notification may be more semantically useful than a shred while arriving later.
WebSocket runs over TCP, so loss recovery and ordered delivery have the same head-of-line behavior. Reverse proxies can add idle timeouts, buffering, frame limits, and per-connection queues. Ping and pong frames prove a path can exchange small control messages. They do not prove the application is current with the newest slot.
Latency starts at the observation point
A fair measurement needs a common event and a common clock basis. For a shred feed, the event might be the first valid packet containing bytes that later decode into a target transaction. For a gRPC stream, it might be the callback containing that transaction. For WebSocket, it might be the corresponding logs or account notification. The first timestamp is taken immediately after receive, before logging or allocation-heavy parsing.
Wire transport is only one term. UDP may save an upstream decoder and several queue transitions because it transfers that work to the customer. A filtered gRPC stream may save the customer far more CPU and bandwidth because the provider performs those steps. WebSocket may be late for a latency-sensitive strategy yet ideal for reconciliation and user-facing state.
Report paired deltas for the same events rather than unpaired averages. Quantiles should include p50, p99, p99.9, and missing-event rate. A feed that wins the median but omits events under load has a different contract from one that arrives later and complete.
Serialization changes CPU and bandwidth
Raw UDP shreds require protocol parsing, erasure recovery, entry reconstruction, and transaction decoding. The wire payload is compact, but receiver compute is significant. A gRPC provider can send decoded protobuf messages, moving compute upstream. Protobuf encodes field numbers and values compactly, although the exact size depends on the schema and selected fields.
WebSocket RPC notifications are frequently JSON. JSON names fields repeatedly and represents binary content through an encoding such as base64. Base64 expands binary data by about one third before JSON quoting and metadata. The format is useful for interoperability, not minimum wire size.
Compression is workload dependent. gRPC compression can reduce repetitive structured payloads but adds CPU and latency. WebSocket per-message deflate has similar trade-offs and can interact poorly with tiny messages. Raw shreds are already packetized protocol data and should not be recompressed in the receive loop. Benchmark serialization with realistic messages, warm allocators, and production compiler settings.
Flow control decides slow-consumer behavior
UDP has no receiver feedback. When an application falls behind, packets accumulate in finite NIC, kernel, socket, and application queues. Once those fill, new packets drop. The receiver can remain current only by processing faster, shedding work, or discarding stale packets. The failure is explicit in counters and sequence gaps.
gRPC and WebSocket inherit TCP flow control. A slow reader causes bytes to queue in the client, kernel, network, proxy, or server. Eventually the receive window and server writes apply pressure. That can preserve every message while increasing age. Providers often enforce maximum pending bytes or disconnect consumers that remain slow.
Neither model removes overload. UDP converts overload into loss. Reliable streams convert it into delay, memory growth, backpressure, or disconnects according to queue policy. A trading receiver should track newest-event age for all three interfaces. Message count and connection status are inadequate health indicators.
Filtering moves work and changes meaning
Raw UDP delivery normally sends the entire offered shred stream to each destination. The measured shredstream.sh feed is 54.3 Mbps and 5,585 packets/sec, with a 1,216 byte mean packet. Filtering occurs after receive and often after partial decoding. The bandwidth and initial packet cost are fixed even if the strategy uses one program.
gRPC services can filter accounts, owners, programs, transaction signatures, or commitment levels at the server, depending on their schema. A narrow filter reduces customer bandwidth and decode work. It also asks the provider's filter implementation to decide what is relevant. An omitted field or semantic mismatch can hide an event before the customer has any chance to inspect it.
WebSocket RPC subscriptions also filter by method and parameters. They are useful for targeted monitoring and state updates. Subscription limits, provider-specific extensions, and commitment behavior must be recorded as product dependencies. Raw feeds maximize local control. Structured filtered feeds reduce local work. That is an ownership trade, not a universal ranking.
Failure detection differs by interface
A UDP socket has no disconnect event. Silence could mean a quiet source, a firewall change, a route failure, a dead sender, or a local receive problem. Detection needs an expected packet-rate range, last-packet age, slot progress, protocol validation, and local drop counters. An external control plane can report entitlement and destination state separately.
gRPC exposes connection state and status codes such as UNAVAILABLE, RESOURCE_EXHAUSTED, and DEADLINE_EXCEEDED. Keepalive pings can detect a broken path, although aggressive settings may conflict with a server's policy. A clean status still does not prove freshness before the error occurred.
WebSocket clients see close frames, TCP failures, ping timeouts, and JSON-RPC errors. Intermediaries may close idle connections without an application error. Every reliable interface needs a resume rule. Record the last processed sequence or slot, then determine whether reconnection continues, replays, or starts only with new data.
Network devices treat them differently
UDP is frequently subject to short NAT and conntrack timeouts. Inbound delivery also needs an explicit firewall rule or prior state. Direct public destinations should restrict the source address and port as tightly as the product permits. Large conntrack tables can drop new flows before the application sees them.
gRPC over TLS generally uses TCP port 443 and traverses enterprise networks well. HTTP/2 support must be end to end. Some proxies terminate HTTP/2 and create a different upstream connection, which adds buffering and changes failure boundaries. Load balancers also impose maximum stream durations and idle policies.
WebSocket over TLS also uses port 443 but requires upgrade support. Proxy configuration must preserve long-lived connections and disable unintended response buffering. Browser availability is a unique advantage for WebSocket, although a browser is not an appropriate raw shred receiver. Network convenience can dominate for dashboards and control planes even when it does not dominate the trading data path.
Operational visibility needs interface-specific counters
For UDP, start with nstat -az UdpInDatagrams UdpInErrors UdpRcvbufErrors, the drops column in /proc/net/udp, softnet statistics, and ethtool -S eth0. Add application counters for received datagrams, invalid lengths, duplicates, reorder depth, fec recoveries, unrecoverable gaps, and newest slot.
For gRPC, instrument messages received, bytes, callback duration, deserialization duration, active stream state, reconnect count, status codes, HTTP/2 flow-control stalls, and newest-event age. Channel state is diagnostic context, not the service objective. Library tracing should be sampled because verbose per-message logs can become the bottleneck.
For WebSocket, record frames, JSON parse time, message method counts, ping round-trip time, close codes, reconnects, subscription acknowledgements, and notification age. The Linux command ss -tinp reveals transport queue size and TCP details for both reliable options. A growing Recv-Q with an open connection means the process is not keeping up.
Architecture should separate live and control lanes
One interface does not need to carry every concern. A latency-sensitive stack can ingest raw UDP shreds for the live decision path, use gRPC for targeted decoded data or replay, and use WebSocket RPC for reconciliation and operator-visible state. The paths should converge through explicit event identities rather than arrival order.
This split contains failures. A WebSocket reconnect does not stop raw ingest. UDP loss does not prevent a control service from reporting entitlement. A gRPC filter change can be tested against locally decoded raw data. It also creates more software and more chances for inconsistent semantics.
Document the authority of each lane. Raw shreds represent proposed block data, not final state. A confirmed RPC subscription may be slower but authoritative for reconciliation. The fastest interface should not silently become the source of final truth, and the most complete interface should not sit in the latency-critical loop without a measured reason.
Choose from the required invariant
Choose UDP when the invariant is freshness: later packets must remain visible after loss, and the team can own decoding and recovery. Choose gRPC when the invariant is typed structured delivery with server-side filtering and explicit service errors. Choose WebSocket when the invariant is broad client compatibility and RPC subscription semantics.
Then test the failure you fear. Drop packets, pause the consumer, restart the server, expire a proxy idle timer, and exceed an application queue. Observe event age and correctness, not only reconnect time. The interface that behaves acceptably under that failure is more useful than the one with the lowest unloaded median.
For a Solana MEV system, UDP often belongs closest to the signal and a reliable structured interface belongs closer to recovery and state. Teams with no raw-decoding budget may rationally accept the additional pipeline latency of gRPC. WebSocket remains valuable where portability and RPC meaning outweigh microseconds.
In practice
Run three receivers on one Linux host and measure local pressure before comparing event timestamps. The UDP service listens on port 9000, gRPC connects to TCP port 10000, and WebSocket connects to TCP port 8900. Record socket state every second:
watch -n 1 "ss -u -a -n -m '( sport = :9000 )'; ss -t -n -i '( dport = :10000 or dport = :8900 )'" nstat -az UdpInDatagrams UdpInErrors UdpRcvbufErrors TcpRetransSegs sudo ethtool -S eth0 | grep -E 'rx_(missed|no_buffer|discard|drop)'
Give UDP a 4 MiB requested receive buffer under a 128 MiB ceiling, and provide a backlog for short input bursts:
sudo sysctl -w net.core.rmem_max=134217728 sudo sysctl -w net.core.netdev_max_backlog=8192
At 5,585 packets/sec, a 200 ms consumer pause represents 1,117 packets. At the 1,216 byte mean, that is 1,358,272 payload bytes. The 4 MiB request has room for that payload plus kernel accounting overhead, but it is not intended to hold multiple seconds.
Emit one CSV row per event with source, event_identity, receive_monotonic_ns, decoded_monotonic_ns, and valid. Match identities after the run. Suppose 100,000 matched events produce these paired receive deltas relative to UDP:
source,p50_us,p99_us,p999_us,missing udp,0,0,0,12 grpc,820,2410,8900,0 websocket,7300,18800,44200,0
Those numbers describe that pipeline and workload, not universal transport constants. Inspect ss during an induced 250 ms consumer pause. A growing TCP Recv-Q indicates queued reliable data. A rising UdpRcvbufErrors or final drops value in /proc/net/udp indicates local UDP loss. Compare newest-event age after the pause. Reliable delivery is successful only if its recovered messages remain useful.
What this does not cover
This page compares common interface behavior, not a specific gRPC or WebSocket provider. Schemas, filters, commitment levels, replay guarantees, compression, proxy topology, and queue limits vary by implementation. A vendor name alone does not establish any of those properties.
The worked numbers are a measurement format, not promised latency. Internet paths, datacenter placement, decoding work, and event definitions change results. Raw shred arrival also cannot be equated with confirmed Solana state. Strategies must reconcile observations against the commitment level required by their risk model.
Related questions
- Is gRPC always faster than WebSocket?
- gRPC often uses compact protobuf messages and efficient generated clients, while many WebSocket RPC feeds carry JSON. That can reduce parse time and bytes, but provider pipelines, filters, proxies, and observation points dominate many comparisons. Measure matched events and tail latency from the actual services instead of treating the interface name as a latency guarantee.
- Can gRPC carry raw Solana shreds?
- A gRPC schema can carry arbitrary bytes, including raw shreds. Doing so adds HTTP/2, TCP reliability, flow control, framing, and usually TLS around the messages. That may help authentication and operations, but one lost TCP segment can delay later messages that raw UDP would have delivered independently.
- Why use WebSocket for Solana data?
- WebSocket provides persistent bidirectional messages, broad library support, browser compatibility, and established JSON-RPC subscription patterns. It is well suited to dashboards, reconciliation, and applications that value RPC semantics over the earliest raw observation. Operators still need reconnect, resubscription, queue-age, and commitment-level handling.
- Which interface handles a slow consumer best?
- No interface removes a slow consumer. UDP drops when finite queues fill, preserving the possibility of current data. gRPC and WebSocket queue, apply flow control, disconnect, or combine those behaviors according to implementation policy. The correct choice depends on whether the application can tolerate gaps, age, or reconnection.
- Should one trading system consume all three feeds?
- Multiple interfaces can separate live signal, structured recovery, and confirmed reconciliation. The design is useful only when event identities and authority are explicit. Without careful deduplication, clock measurement, and state transitions, three feeds create conflicting observations and additional failure modes rather than dependable redundancy.