At a glance
Both v1 and v2 give you the decoded transaction: signatures, account keys, instructions, the
message header, and any address-lookup-table references. What v2 adds is enrichment on top of
that (the pre-computed fields above), plus the live-subscription, slot, and liveness features.
Enrichment is opt-in; see below.
More data, fewer RPC calls
With v1 you get the decoded transaction and work out the rest yourself. Anything past the core fields is on you: who paid the fee, the compute-unit price it set, which accounts are writable, and the real accounts behind a versioned transaction’s lookup tables. v2 can do that work for you. Turn on enrichment and each transaction also carries the fields below.compute_unit_price is the compute-unit price — the micro-lamports-per-CU value from
SetComputeUnitPrice, not the total priority fee. For the total priority fee in lamports, multiply
by the compute-unit limit and divide by 1,000,000: compute_unit_price × compute_limit / 1e6.
compute_limit reflects only an explicit SetComputeUnitLimit (0 if the transaction sets none).For a versioned transaction, the resolved lookup-table addresses are included. If any can’t be
fully included,
alt_resolution_incomplete is set on that transaction so you resolve those
yourself (fetch the tables via RPC) — no silent gaps.Enrichment is opt-in and off by default. Flip it on per subscription (
include_enrichment: true on a filter) whenever you want the extra fields — turning it on adds no latency to the
stream; the only difference is a modestly larger message. It is subscription-wide: if any active
filter turns it on, every transaction the session receives is enriched.Manage your stream without reconnecting
In v1 you set your filters once, in the message that opens the stream. To watch something different you drop the connection and open a new one, losing the live stream while you reconnect. v2 keeps the stream open and lets you add and remove filters as you go. You give each filter your ownfilter_id, the server acknowledges every add and remove (and tells you why if it rejects one), and
every transaction lists the filter_id values it matched. Run several filters on one connection,
change them on the fly, and always know which filter produced a given transaction. Account
include / exclude / required behave exactly as in v1 — required is any-of (a transaction
matches if it references at least one listed account), not all-of.
Follow the chain with slot events
v2 adds a second, separate stream,SubscribeSlots, that v1 has nothing like. You get an event when
a slot starts (ALIVE), finishes (COMPLETE), or is skipped or superseded by later slots without
completing (DEAD), along with that slot’s leader and parent. It is a cheap way to track where the
chain is instead of inferring it from the transaction flow.
Know when you have missed something
Two things v1 never gave you:- Every v2 message, transactions and slot events alike, carries a
sequencenumber that climbs by one. See a gap and you know you dropped a message. - When a transaction stream goes quiet, v2 sends a
Heartbeatevery 60 seconds, stamped with the server’s clock. That keeps the connection alive through load-balancer idle timeouts, and tells a quiet stream apart from a dead one.
Why this adds up to a faster result
- A round-trip off your critical path. On v1, resolving a lookup table is a full RPC request and response, much slower than the stream itself. With v2 enrichment on, a versioned transaction’s resolved addresses arrive inline, so that call never sits between a transaction arriving and you acting on it.
- Less work per transaction on your side. The enrichment fields arrive already computed, so your client doesn’t re-derive them on every transaction.
- No reconnect gaps. Changing filters live means you never drop the stream to re-subscribe.
- Loss and stalls are visible immediately through sequence numbers and heartbeats, instead of being inferred after the fact.
Which should you use
Use v2 for new integrations. It is where enrichment, slot events, live filters, and the liveness signals live, and where every new capability lands. v1 stays fully supported and has no set retirement date yet, so an existing v1 client can keep running as it is. We do encourage moving over, though: as more traffic consolidates onto v2, it frees the capacity we dedicate to v1 today for the next generation of OrbitFlare streaming. Either way, migrating is a change in your client code, not your connection: same endpoints, same authentication, running side by side.See Also
Jetstream v2 Overview
The streaming model, connecting, and best practices.
v2 Protocol Reference
Full v2 Protocol Buffer specification, endpoints, and code generation.
Jetstream (v1)
The v1 overview, client examples, and filtering guide.