The expensive mistake is the wrong class
"Just use gRPC" is the new "just poll faster." Both can be right. Both are wrong as defaults.
If you are building a portfolio page, a shred firehose is theater. If you are competing for the same liquidation as ten other bots, a 500ms poll loop is a gift to your competitors. The fix is a decision matrix you can put in a design doc before you open a pricing page.
We already covered pieces of this ladder in Why RPC Polling Can't Keep Up, Yellowstone gRPC vs Standard RPC, What Are Solana Shreds, and Deshred vs Processed. This post is the chooser: one table, three workloads, explicit anti-patterns.
A stream is a contract about when you learn, what commitment that means, and who owns the gaps.
Step 1: name the workload
| Workload | "Good" means | Wrong default |
|---|---|---|
| Interactive app | Users see balances and history that match reality; boring ops | Full shred stack for a settings page |
| Complete indexer | No silent holes; resume after crash; reproducible order | Earliest signal without a completeness plan |
| Latency trader | First usable signal + a send path that can act | Feature-rich API a region away from stake |
You can run all three in one company. You almost never run them on one connection design.
Step 2: the Solana stream ladder
Rows are classes, not brand SKUs. Lag numbers are order-of-magnitude teaching aids, not a bench of any single vendor.
| Class | How you learn | Lag class | Reconnect / gaps | Ops | Use when | Wrong when |
|---|---|---|---|---|---|---|
| 1. Polling JSON-RPC | Client asks on a timer | Poll interval + RTT (often hundreds of ms of structural staleness) | Re-query; no stream cursor | Low | One-shot reads, low-frequency jobs | Contested trading, dense live state |
| 2. Webhooks | Provider HTTP callback after an event | After process/confirm class events | Provider retry varies | Low-med | Alerts, async side effects | Sub-second loops |
| 3. Standard WebSocket | accountSubscribe / logs-style push | Better than poll; commitment-bound | You own retry + resync | Med | Few accounts, simple live UI | Thousands of accounts |
| 4. Enhanced / hardened WSS class | Push with better filters/resilience | Same commitment family as the node | Better than bare WSS | Med | Product live UI without self-running Geyser | Trading-scale multi-filter fan-out |
| 5. Geyser-class gRPC (Yellowstone-shaped) | Plugin pushes accounts/txs/slots | As-processed (or higher if you request it) | Client reconnect unless the product persists | High if self-host; med if managed | Bots, live indexers, filtered firehoses | Single balance once a minute |
| 6. Shred / deshred-class | Propagation-layer fragments (and early reassembly) | Earliest network view; not confirmed truth | Complex; bad decode = wrong world | Highest | HFT / RFQ / liquidations | Wallet truth, compliance replay alone |
How to run the matrix in five minutes
- Circle the workload in step 1.
- Circle the minimum class in step 2 that still hits "good."
- Write: I accept lag class X. I own reconnect story Y. Signal is / is not user-visible truth.
- Only then pick a provider and a SKU.
That order saves more money than any annual discount.
Step 3: commitment is part of the stream contract
Streams deliver updates at a commitment, or before commitment in the shred case.
| Level | Operator reading |
|---|---|
| Processed | Runtime/leader view; can fork away |
| Confirmed | Supermajority voted; still not "paint the bank balance" for every product |
| Finalized | Deep confirmation; slowest safe class for many user-truth UIs |
Rules we use with customers:
- User-facing balances and receipts → confirmed or finalized on the read-after-write path
- Strategy "something is moving" → processed or shred-class as signal
- Indexer durability → define whether confirmed is enough and how you catch up to finality
Mixing shred-class first-seen into a row labeled finalized is how you ship ghost state. See Solana Commitment Levels Explained.
Step 4: anti-patterns that burn a quarter
| Anti-pattern | Failure mode | Fix |
|---|---|---|
| Serverless long-lived gRPC | Cold starts and idle kills | Always-on workers; persistence if you need gap fill |
| One stream for all ICPs | Optimize the wrong tail | Split by workload |
| Poll harder | Rate limits + half-interval staleness | Climb the ladder |
| gRPC for everything | Ops tax without benefit | Stay on poll/WSS until live requirements appear |
| Earliest signal as ledger truth | Bad UI, bad fills | Dual path: signal + settlement read |
| Great stream, weak send | You see the opportunity and lose the land | Pair with landing path (why txs fail, sender paths) |
Step 5: where rpc edge sits on the ladder
We build for the latency trader and latency-sensitive bot row: co-location with stake and Jito, decoded shreds, Yellowstone gRPC where you need filtered live state, and a transaction sender that can act when the signal is real.
That is not a claim that we are the best dashboard API or the best multi-chain indexer. Those jobs often want a different class on the ladder. The matrix exists so you can say that out loud.
If your circled row is 6 or hard 5 with a serious send path, start with pricing and the Solana RPC product. If your row is 1-3, keep life simple: JSON-RPC and light push are fine, and you should not pay for a trading topology you will not use.
Building on the latency end of the ladder?
rpc edge is for first-seen signal and landing under contention. If that is your row, we should talk. If it is not, the matrix above still saves you a bad contract.
One week reliability (before you buy three SKUs)
Pick one workload and one class.
Done means:
- Process stayed up without babysitting
- Gaps were zero or detected
- Reconnect is explainable in two sentences
- You did not upgrade classes mid-week out of FOMO
That is the same discipline as any production loop: a trigger, a capable path, and verification. Here verification is gap detection plus a commitment policy, not a unit test.
Bottom line
Streaming is a ladder of contracts. Name the workload, pick the minimum class, write the reconnect story, and never confuse first-seen signal with finalized truth. The teams that win are not the ones with the most streams. They are the ones who bought the right row and measured it honestly.