What happened
Syndica shut down its Solana RPC and ChainStream APIs on February 14, 2026. The company pivoted to running a validator, a staking product, and its open-source Sig validator client. The ChainStream docs and pricing pages now return 404, and Syndica's own guidance to ChainStream customers was direct: move to Yellowstone gRPC for streaming.
If you built on ChainStream, you are not choosing whether to migrate. You are choosing where to land, and how much better your streaming layer gets on the way.
Why this is a rewrite, not a URL swap
ChainStream was a WebSocket-based PubSub service with its own subscription methods:
transactionsSubscribe, blockSubscribe, encodedBlockSubscribe, account filters
(all / oneOf / exclude), and a verified flag that waited for multi-validator
confirmation.
Yellowstone gRPC is a different model. Instead of opening a WebSocket per concern, you open
one long-lived gRPC stream, describe everything you care about in a single SubscribeRequest
with server-side filters, and updates are pushed as the validator processes them. Filtering
happens on the server, backpressure is handled by the protocol, and one stream multiplexes
accounts, transactions, slots, and blocks.
ChainStream asked you to subscribe to things. Yellowstone asks you to describe what matters, once, and then narrates the chain to you.
The practical consequence: your subscription-management code gets simpler, and your latency profile improves - Syndica itself noted that Yellowstone offers lower latency than ChainStream's WebSocket delivery.
How the concepts map
| ChainStream (retired) | Yellowstone gRPC |
|---|---|
transactionsSubscribe | transactions filter (accountInclude / accountExclude / accountRequired) |
blockSubscribe | blocks filter (full blocks) |
encodedBlockSubscribe | blocks with transaction details, or blocksMeta for headers |
Account filters all / oneOf / exclude | accounts filter by owner, pubkey, or data filters |
verified multi-validator flag | Commitment levels: processed / confirmed / finalized |
| One WebSocket per subscription | One gRPC stream, many named filters |
| Client-side filtering of the firehose | Server-side filters - you receive only what matches |
Two notes on the mapping:
- Commitment replaces
verified. ChainStream'sverifiedflag was its answer to "has more than one validator seen this?" In Yellowstone you pick a commitment level per subscription.confirmedis the closest practical equivalent;processedis earlier and faster if your logic tolerates the occasional fork. - Reconnect logic changes shape. ChainStream clients typically managed WebSocket
reconnects per subscription. With Yellowstone you reconnect one stream and resend one
SubscribeRequest. Track the last processed slot so you can detect gaps on resume.
A minimal Yellowstone client
The rewritten core is smaller than most ChainStream clients ended up being:
// One stream replaces every ChainStream WebSocket you were running.
const request = {
transactions: {
// was: transactionsSubscribe with oneOf account filters
swaps: {
accountInclude: [RAYDIUM_AMM],
vote: false,
failed: false,
},
},
accounts: {
// was: account subscriptions with owner filters
pools: { owner: [RAYDIUM_AMM] },
},
// was: the `verified` flag - pick your commitment explicitly
commitment: "confirmed",
};
const stream = await client.subscribe(request);
for await (const update of stream) {
handler.onUpdate(update);
}Port each ChainStream subscription into the request object, delete the per-socket reconnect scaffolding, and keep one reconnect loop for the stream itself.
Since you're rewriting anyway: pick the endpoint on merit
Here is the useful side effect of a forced rewrite. Yellowstone gRPC is an open standard - once your client speaks it, you can move between providers by changing an endpoint and a key. So the migration decision is really an infrastructure decision, and it is worth making deliberately:
- Where does the endpoint physically sit? ChainStream ran on a global edge-cache model. Yellowstone providers differ widely here. rpc edge runs co-located bare metal beside stake clusters and the Jito Block Engine - proximity is the product.
- What sits upstream of gRPC? Standard Yellowstone pushes at processed commitment. If your strategy wants earlier, look for decoded shreds - a first-seen view read from the propagation layer before block assembly. rpc edge streams these as preprocessed gRPC alongside standard Yellowstone.
- Does the same box cover your write path? ChainStream never had a transaction sender; most ChainStream setups paired it with a separate submission stack. A co-located endpoint that bundles the sender with the stream removes the vendor seam from your see-decide-land loop.
Migration checklist
- Inventory your ChainStream subscriptions and their filters.
- Map each to a named filter in one Yellowstone
SubscribeRequest(table above). - Replace
verifiedhandling with an explicit commitment choice. - Collapse per-socket reconnect logic into one stream-level reconnect with slot tracking.
- Run the new client in parallel against your old data expectations before cutting over.
- Benchmark the endpoint you chose with your real workload, not a synthetic one.
Land the migration on a co-located endpoint
rpc edge runs Yellowstone gRPC plus decoded shreds and a transaction sender from the same co-located box. Vetted 15-day Trader trial - no card. Request access on Telegram and benchmark it with the client you just rewrote.
The takeaway
ChainStream is gone, and the rewrite to Yellowstone gRPC is unavoidable - but it is a one-time cost that buys you a faster streaming model and a portable client. Spend the choice it forces on you well: pick the endpoint by physics and by whether it covers your whole loop, then hold it to your own benchmark.