Solana Firehose: one WebSocket feed of every non-vote transaction

Last updated:

What arrives: transaction and stats frames

This is an activity feed after execution, not a full transaction decoder or a pre-execution signal. Each JSON object has a t discriminator: tx for a transaction, or stats for hub telemetry. The client cannot select commitment. The examples below are illustrative frame shapes from the reference, not measured traffic or capacity.

{"t":"tx","l":449495511,"s":"3zc9xQTnBwpa...GRo","f":5000,"urps":0,"brps":0,"drop":0,"cc":0}
{"t":"stats","urps":3120,"brps":3118,"drop":0.1,"cc":42}
Firehose frame fields
FrameFieldsMeaning
txl, s, fSlot, base58 signature, fee in lamports. Fee is omitted when zero or unknown.
statsurps, brpsTransactions received and frames broadcast in the last second.
statsdrop, ccHub-wide drop percentage for slow clients and connected client count.

The telemetry fields are zero on transaction frames. A tx frame carries no instructions, accounts, logs or balances. Use its signature for a follow-up getTransaction lookup if you need the full transaction. Those reads consume your plan's JSON-RPC request budget.

When to use Firehose

Use the feed for live activity counters, sampling, dashboards and triggers for your own reads. Receive the compact signal continuously, then send selected signatures to a separate worker. Keep parsing and intake independent of database writes or expensive transaction lookups so a slow dependency does not block the consumer.

For server-side account filters or execution metadata, choose filtered transactions over Yellowstone gRPC. For transactions before execution, choose Shred stream. For individual account or signature subscriptions, use WebSocket (Pub/Sub). Firehose receives the same feed regardless of what your application later discards.

How much data is the Firehose?

There is no published measurement of daily volume or sustained frame rate yet. Estimate your own payload volume as received frames × mean encoded frame size over your observation window, including both transaction and stats frames. Measure actual socket traffic separately if you need to include WebSocket, TLS and network overhead. We will publish measured volumes when measurements are available.

Record the date, client region, observation window and reconnect gaps with the result. Traffic changes with chain activity. The stats rates describe frames and transactions, not bytes, and the hub-wide drop percentage is not a per-client completeness guarantee. No per-GB charge changes the bill; your network, storage and consumer throughput still need to handle the feed.

Delivery semantics and reconnecting

Delivery is at-most-once with no replay or backfill. Each client has a bounded buffer; when it fills, frames for that client are dropped. They do not wait for the consumer to catch up. The stats.drop value reports the hub-wide drop share, so monitor your own intake and processing checkpoints too.

Persist your last processed slot and signature, reconnect with backoff, and recover the missing range separately: backfill a missed slot with getBlock. Deduplicate the overlap between recovered data and live intake. A slot checkpoint alone does not prove you received every transaction within that slot. Reopening the WebSocket starts the live feed again; it does not request older frames.

The server sends a WebSocket ping every 30 seconds; standard clients answer with pong automatically. There is no application heartbeat or subscribe message to send. Client messages do not apply filters, and a message larger than 1 KiB closes the connection.

Connect with wscat or ws

Open wss://triport.io/ws/sol-stream with your API key in the upgrade header. Frames start without a subscribe request. The examples use environment variables;Authorization: Bearer is accepted as an alternative to x-token.

wscat -c wss://triport.io/ws/sol-stream -H "x-token: $TRIPORT_API_KEY"

A Node.js consumer using the ws package:

import WebSocket from "ws";

const ws = new WebSocket("wss://triport.io/ws/sol-stream", {
  headers: { "x-token": process.env.TRIPORT_API_KEY },
});
ws.on("message", (raw) => {
  const frame = JSON.parse(raw.toString());
  if (frame.t === "tx") console.log(frame.l, frame.s, frame.f ?? 0);
  else if (frame.t === "stats") console.log("hub drop %", frame.drop);
});
ws.on("error", console.error);
ws.on("close", (code, reason) => console.log("closed", code, reason.toString()));

This minimal example prints frames; add checkpoint persistence and reconnect handling for a continuous service. An absent or unknown key returns HTTP 401 before upgrade. A key below Pro receives an error frame and close code 4003 after upgrade; an expired subscription receives 4030. See the Firehose error reference.

Plans and connection limits

Firehose is included on Pro ($249/mo), Business ($499/mo) and Enterprise. No per-key connection cap; separate from the gRPC stream limit. Firehose connections do not count toward the 8/20 concurrent gRPC streams on Pro/Business. No per-GB charge and no credits apply. Follow-up JSON-RPC reads remain subject to the plan's RPS limits.

Create a Pro API key or review plans and request budgets.

When Triport is the wrong choice

Firehose is unsuitable if you require lossless accounting, stream-native historical replay, failed or vote transactions, a full transaction payload, selectable commitment or server-side filters. Triport does not offer raw UDP shreds. Standard Pro and Business regions are eu and us; if you require a region outside them or more than 20 concurrent gRPC streams, discuss Enterprise terms. The Firehose connection policy does not remove these other constraints.

FAQ

Can I filter the Firehose?
No. All clients receive the same fixed feed. Sending a subscription or filter request does not change it. Filter locally after receiving the frames, or use Yellowstone gRPC when filtering must happen on the server.
Does it include vote transactions?
No. The Firehose subscription excludes vote transactions. Its transaction frames are compact activity signals rather than full blocks or transaction payloads.
Does it include failed transactions?
No. The current feed requests non-failed transactions. The frame schema reserves an e field for failure, but that does not mean failed transactions are included in this feed.
How is it different from Yellowstone gRPC?
Firehose uses WebSocket and pushes fixed transaction summaries without client filters or selectable commitment. Yellowstone gRPC supports typed updates, server-side filters and execution metadata. Firehose has no per-key connection cap and does not consume the 8/20 concurrent gRPC streams included on Pro/Business.