Skip to content
0%
Overview page background

Webhooks vs WebSockets vs gRPC

Uttam Singh

Written by Uttam Singh

Published on May 19, 202611 min read

Webhooks vs WebSockets vs gRPC

Every application that reads blockchain data faces the same architectural question: how should the data reach your system? Poll an API every few seconds and you waste compute, miss events, and add latency. Push the data instead, and you need to pick a delivery model.

Three protocols dominate real-time data delivery: webhooks, WebSockets, and gRPC. They aren't interchangeable. Webhooks notify your backend when something happens. WebSockets stream live data to a browser. gRPC moves data between backend services at high throughput. Pick the wrong one and the cost shows up later: missed events, wasted compute, or a system redesign you didn't plan for.

What are webhooks, WebSockets, and gRPC?

All three move data from a server to your application without polling. The similarities end there.

A webhook flips the usual API direction. Instead of your code calling the server, the server calls a URL you registered, with a JSON payload, whenever something it cares about happens. Webhooks are simple to wire up; the trade-off is that you don't control the timing or shape of what arrives.

A WebSocket is a persistent TCP connection between a client and a server. Either side can send small binary frames at any time without re-establishing the connection. The protocol starts as an HTTP request and switches to a raw socket once both sides agree to upgrade.

gRPC is a remote procedure call (RPC) framework: a system that lets one service call functions in another service as if it were calling a local function. The public successor to Stubby, Google's internal RPC system, gRPC runs over HTTP/2, serializes data as Protocol Buffers, and supports four streaming modes including full bidirectional. It's built for backend services moving structured data quickly between machines, with built-in retries, deadline propagation, and typed contracts.

DimensionWebhooksWebSocketsgRPC
Protocol
HTTP POST callbacks
Persistent TCP (RFC 6455)
Direction
Server to receiver (one-way)
Bidirectional
Bidirectional (4 streaming modes)
Connection model
Stateless (new request per event)
Stateful (persistent)
Stateful (persistent, multiplexed)
Data format
JSON
JSON or binary
Protobuf (binary)
Per-message overhead
500-2,000 bytes (HTTP headers)
2-6 bytes
5-byte frame + compressed headers
Browser support
N/A (server-side)
Native (99%+)
Requires gRPC-Web proxy
Delivery guarantee
At-least-once (with retries)
None built-in
Configurable retries + deadlines
Best for
Event notifications
Real-time browser UIs
Service-to-service pipelines

How do webhooks work?

Webhooks invert the API model. You don't call the server; the server calls you. You register a URL with a provider, tell it which events matter, and wait. When something happens, the provider POSTs JSON to your endpoint and expects a 2xx in response.

javascript
Copied
app.post('/webhook', (req, res) => { const sig = req.headers['x-alchemy-signature']; if (!verify(sig, req.rawBody, SECRET)) return res.status(401).end(); queue.enqueue(req.body); res.status(200).end(); });

The snippet above is a webhook handler: it verifies the signature, queues the payload, and returns 200. The simple version above is also where most production webhook outages come from. What separates a toy handler from a production one is how it handles three things the simple version gets wrong: signature verification, retry behavior, and burst overload.

The first failure mode is weak signature handling. The provider HMAC-signs every delivery using a shared secret (Alchemy uses X-Alchemy-Signature, Stripe uses Stripe-Signature), and your handler has to recompute the HMAC, compare it in constant time to avoid timing attacks, and reject anything with a timestamp older than five minutes. Calling verify() is one line; doing it correctly is several. Skip any step and you're trusting any process that knows your endpoint URL.

The second failure mode is non-idempotent handling under retry. When deliveries fail (timeouts, partial outages, 5xx responses) providers retry with exponential backoff (typically doubling from one second, jittered, capped at an hour) for hours or days before sending the payload to a dead-letter queue. Webhooks guarantee at-least-once delivery, not exactly-once (exactly-once is impossible in distributed systems), so duplicate deliveries are routine. Your handler has to be idempotent: processing the same event twice should produce the same result as processing it once. Track event IDs in a dedup store and return 200 on repeats.

The third failure mode is burst overload, and it's the one that breaks webhook systems at scale. A single on-chain event can trigger millions of simultaneous deliveries. If your endpoint is the bottleneck, the provider's retry queue becomes your DoS attacker.

In blockchain infrastructure, webhooks power event-driven workflows. Our Custom Webhooks support address activity monitoring, NFT transfer alerts, and GraphQL-filtered smart contract events across 30+ EVM chains plus Solana, all delivered as HTTP POST callbacks to your endpoint.

How do WebSockets work?

A WebSocket starts as a plain HTTP request with an Upgrade: websocket header. The server replies with HTTP 101 (Switching Protocols), and from that point forward the connection stops speaking HTTP. That negotiation is the WebSocket handshake. What remains afterward is a raw TCP socket with a thin framing layer on top: no headers per message, no request-response cycle.

Removing HTTP makes WebSockets dramatically cheaper per message. Each WebSocket message carries 2-6 bytes of overhead (a FIN bit, opcode, and payload length). Compare that to HTTP, where every request includes hundreds of bytes of headers. At 100 messages per second, WebSocket overhead is roughly 600 bytes per second versus 60,000 bytes per second for equivalent HTTP traffic.

javascript
Copied
const ws = new WebSocket('wss://eth-mainnet.g.alchemy.com/v2/KEY'); ws.send(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_subscribe', params: ['newHeads'] })); ws.on('message', (data) => handleBlock(JSON.parse(data)));

WebSocket connections are stateful and long-lived. Either side can send data at any time without waiting for the other. The server sends periodic ping frames; the client responds with pong frames to prove the connection is alive. Without these heartbeats, dead connections ("zombies") leak server resources, and reverse proxies kill idle connections after 30-120 seconds.

The tradeoff: you own the connection's lifecycle, and the lifecycle has more in it than first appears. When a connection drops, your client has to reconnect, and reconnect with exponential backoff (waiting progressively longer between retries) or thousands of clients reconnecting at once will overwhelm the server. When you run more than one WebSocket server behind a load balancer, the load balancer has to route every reconnect from a given client back to the same machine, because that machine holds the client's subscription state. That routing rule has a name: session affinity. And if a message originating on one server needs to reach a client connected to a different server, the servers have to share state across nodes. WebSockets give you the wire protocol; everything above it is yours to build.

For blockchain applications, WebSockets are the standard interface for live event subscriptions. Ethereum's eth_subscribe endpoint pushes new block headers, log events, and pending transactions over a persistent WebSocket connection. Our Smart WebSockets add filtered subscriptions with automatic reconnection on top of the base protocol.

Streaming live data to a browser is the problem WebSockets were built to solve. Before WebSockets, the alternatives (long-polling, server-sent events) either paid full HTTP overhead per message or only worked in one direction. WebSockets give you a persistent, low-overhead, bidirectional connection in the one place a raw TCP socket can't ordinarily live: the browser.

That clarity is also their limit. WebSockets struggle when the consumer isn't a browser, the data is structured, the volume is high, and you need things WebSockets never promised: typed schemas, multiplexed streams, deadline propagation, backpressure. That's what gRPC was built for.

How does gRPC work?

gRPC starts from the opposite end of the design space. Where webhooks are HTTP callbacks and WebSockets are a thin framing layer over TCP, gRPC is a full RPC framework with typed contracts at its core. Before you write any business logic, you write a .proto file defining your service and the messages it sends and receives. The protobuf compiler turns the file into generated client and server code in your language (called stubs), so calling a remote method in your code looks like calling a local function.

protobuf
Copied
service Geyser { rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate); }

The transport layer is HTTP/2, paired with Protocol Buffers for serialization. Together they give gRPC three advantages over a typical REST + HTTP/1.1 + JSON stack:

  • Multiplexing eliminates head-of-line blocking, the HTTP/1.1 problem where a single slow response holds up every subsequent request on the same connection. With gRPC, each call runs as an independent HTTP/2 stream sharing the same TCP connection. Square is one of many engineering teams that moved internal service-to-service traffic onto gRPC to reduce connection overhead.
  • Header compression (HPACK) replaces repeated headers with compact references. In RPC traffic where the same method, content type, and auth headers repeat on every call, this reduces header overhead by 85-90%.
  • Protocol Buffers serialize messages into compact binary instead of text. Payloads are 34% smaller than JSON in non-compressed environments, and deserialization is up to 6x faster depending on the language. The tradeoff: binary payloads aren't human-readable, so you need tools like grpcurl or Postman to inspect traffic.

gRPC supports four streaming modes. Unary (one request, one response) works like a standard API call. Server streaming (one request, many responses) fits feeds and data pushes. Client streaming (many requests, one response) handles batch uploads. Bidirectional streaming (both sides send independently) powers real-time, stateful interactions.

gRPC isn't a general-purpose protocol. It's narrowly optimized for backend services moving structured data at high rates between machines you control on both ends, and that focused niche is where the upfront cost of writing schemas and running code generation pays off. What earns gRPC that position isn't just the binary encoding; it's the production primitives baked into the protocol. Deadline propagation turns every timeout into an absolute point in time that passes through the entire call chain. If Service A sets a 5-second deadline and calls Service B, which calls Service C, every hop knows exactly how much time remains. When the deadline expires, all downstream work cancels and frees resources. Flow control inherits from HTTP/2: when a slow consumer can't keep up, the sender automatically slows down to match. That's built-in backpressure, which neither webhooks nor WebSockets offer natively.

On Solana, gRPC powers the highest-performance data streaming available. The Yellowstone gRPC plugin (Geyser) loads directly into the validator's memory space, captures account and transaction updates before they hit disk, serializes them as protobuf, and pushes them over persistent HTTP/2 streams.

How do the three protocols compare on performance?

Throughput and latency benchmarks draw a clear line for service-to-service communication. Binary protobuf encoding plus HTTP/2 multiplexing gives gRPC measurably higher throughput and lower latency than REST over HTTP/1.1, especially in workloads with small payloads and many concurrent calls.

WebSockets win a different contest: lowest per-message overhead for browser-to-server streaming. After the initial handshake, each message carries 2-6 bytes of framing overhead, and the browser's native WebSocket API handles the connection without proxies or build tools.

Webhooks are not designed for performance. Each delivery is an independent HTTP request with full connection setup overhead. They solve a different problem: reliable, asynchronous event notification where simplicity and compatibility matter more than throughput.

MetricWebhooksWebSocketsgRPC
Latency per message
Highest (full HTTP round-trip)
Low (2-6 byte frame)
Lowest (binary + multiplexed)
Throughput ceiling
Limited by HTTP overhead
High for single stream
Highest (multiplexed streams)
Serialization cost
JSON only
JSON or binary
Connection setup
Per event (or connection reuse)
Once, then persistent
Once, then persistent + multiplexed
Backpressure
None (receiver absorbs or fails)
None built-in
Built-in (HTTP/2 flow control)

The blockchain-specific numbers reinforce the pattern. Solana's Yellowstone gRPC streams data at ~5ms slot latency; native WebSockets deliver at ~10ms; RPC polling lags at ~150ms. Each step up in protocol complexity buys measurable speed.

When does each protocol break down?

Webhooks struggle with high-frequency events. At hundreds of deliveries per second, HTTP overhead per callback becomes a bottleneck. Burst events create thundering-herd problems: a major on-chain event triggers millions of webhook deliveries simultaneously, overwhelming both provider retry queues and consumer endpoints. Webhooks are also strictly one-way. Any use case requiring bidirectional communication needs a different protocol. As one engineer who built webhooks infrastructure described it: "webhooks are painful to run."

WebSockets struggle at scale. Each connection holds server resources (2-10 KB idle, more when active). A tuned server handles 500K+ idle connections, but connection churn is the real bottleneck: TLS handshakes consume 1,000-3,000 per second per CPU core. When a server restarts, every connected client reconnects simultaneously, creating a reconnection storm that can cascade into a full outage. On Solana, the standard WebSocket implementation "became unreliable under load," degrading in performance and frequently disconnecting, which drove Solana teams toward gRPC.

gRPC struggles at the browser edge. Browsers can't speak gRPC natively. The gRPC-Web protocol bridges the gap through a proxy (typically Envoy), but loses client streaming and bidirectional streaming in the process. Binary protobuf payloads can't be inspected with curl or browser DevTools, making gRPC a poor fit for public-facing APIs where developer experience matters. The protobuf toolchain (schema definitions, code generation, build integration) adds meaningful setup cost for simple integrations.

How should you choose between webhooks, WebSockets, and gRPC?

Start with the communication pattern your use case requires.

Webhooks are the default. If your backend needs to know when a discrete event happens (a transaction confirms, an NFT transfers, a payment completes) and the event rate stays under a few hundred per second, webhooks are the lowest-cost integration that works with any language, any framework, and any firewall. No persistent connection, no streaming infrastructure, no client SDK.

When the event rate climbs or you need data flowing in both directions, WebSockets take over. Think live price tickers, order book updates, mempool monitoring, collaborative dashboards: anything where a persistent connection to a browser saves you from hammering an API. Native browser support, no proxy, frame overhead measured in bytes.

Choose gRPC when you need maximum throughput between backend services. Indexer pipelines, validator data streaming, microservice-to-microservice communication, and any workload where you control both ends of the connection benefit from binary serialization, multiplexed streams, typed contracts, and built-in backpressure. The catch is the toolchain: protobuf schemas, code generation, no native browser support. Worth it when performance and reliability outweigh setup complexity.

Combine them when the architecture demands it. Many production systems use all three: gRPC streams data from validators to indexers, WebSockets push processed data to browser dashboards, and webhooks notify external systems of discrete events. There is no reason to go all-in on a single protocol.

Use caseRecommended protocolWhy
Transaction confirmation alerts
Webhooks
Discrete events, simple integration, at-least-once delivery
Live price feed in a trading UI
WebSockets
Continuous data to browser, low latency, bidirectional
Solana validator data pipeline
gRPC
Maximum throughput, binary serialization, backpressure
Ethereum new block subscriptions
WebSockets
Standard eth_subscribe interface, browser-compatible
Backend microservice communication
gRPC
Typed contracts, multiplexing, deadline propagation
Third-party integration callbacks
Webhooks
Universal HTTP compatibility, no persistent connection

Build with real-time blockchain data on Alchemy

We support all three protocols across 100+ chains.

Our Custom Webhooks deliver transaction confirmations, address activity, and NFT events as HTTP POST callbacks with HMAC signature verification and automatic retries. GraphQL filters let you subscribe to exactly the contract events your application needs.

Smart WebSockets provide filtered eth_subscribe streams with automatic reconnection and reduced latency for real-time frontend applications.

For Solana teams processing high-volume data, our Yellowstone gRPC streaming delivers account updates and transactions directly from validator memory with sub-10ms latency.

All three are available on our free tier. No contracts, no waitlist. Sign up and start streaming in minutes.

Frequently asked questions

What is the main difference between webhooks, WebSockets, and gRPC?

Webhooks are one-way HTTP callbacks for server-to-server event notifications; WebSockets provide persistent, bidirectional connections between client and server; gRPC is an RPC framework over HTTP/2 designed for high-throughput service-to-service communication with typed contracts.

When should I use webhooks instead of WebSockets or gRPC?

Use webhooks when you need discrete event notifications (like transaction confirmations or NFT transfers) at a rate under a few hundred per second and don't require a persistent connection. They're the simplest integration requiring no specialized client SDK or infrastructure.

When are WebSockets the better choice?

WebSockets are best for continuous, real-time data streaming to browser clients, such as live price tickers, order book updates, or dashboards. They offer native browser support and low per-message overhead (2-6 bytes) after the initial handshake.

What problems is gRPC designed to solve?

gRPC is optimized for backend services moving structured data at high rates, like indexer pipelines or validator data streaming. It provides binary serialization, multiplexed streams, typed contracts via Protocol Buffers, built-in backpressure, and deadline propagation.

Can I use webhooks, WebSockets, and gRPC together in the same system?

Yes, many production systems combine all three: gRPC for backend service-to-service communication, WebSockets for real-time browser updates, and webhooks for notifying external systems of discrete events. Each protocol solves a different architectural layer.

What are the performance differences between these protocols?

gRPC delivers the lowest latency and highest throughput through binary encoding and HTTP/2 multiplexing; WebSockets offer low overhead (2-6 bytes per message) for browser streaming; webhooks have the highest per-message cost due to full HTTP round-trip overhead but prioritize simplicity over performance.

What are the main drawbacks of each protocol?

Webhooks struggle with high-frequency events and burst traffic; WebSockets face scaling challenges with connection churn and thundering-herd reconnection storms; gRPC requires protobuf toolchain setup, lacks native browser support, and needs a proxy (gRPC-Web) for web clients.

How does Alchemy support these protocols for blockchain applications?

Alchemy provides Custom Webhooks for event notifications across 100+ chains, Smart WebSockets for filtered eth_subscribe streams with automatic reconnection, and Yellowstone gRPC streaming on Solana delivering account updates with sub-10ms latency directly from validator memory.

Background gradient

Build blockchain magic

Alchemy combines the most powerful web3 developer products and tools with resources, community and legendary support.