Entries

The layout of the serialized entries payload, the decoders that read it, and the delivery properties of the feed.

Every ShredPrism response carries a slot number and an entries byte string: this page covers what is in those bytes, what decodes them, and what the feed does not promise.

ShredPrism delivers serialized entries, so deserialization is the first step the reader takes. Data Stages places that step in the pipeline.

Payload layout

entries holds a serialized list of proof-of-history entries. An entry is a link in the hash chain, with the transactions observed before that hash was generated. Most entries hold no transactions: an entry with an empty transaction list is a tick.

FieldBytesEncoding
Entry count8Unsigned 64-bit, little-endian
Per entry: num_hashes8Unsigned 64-bit, little-endian
Per entry: hash32The proof-of-history hash
Per entry: transaction count8Unsigned 64-bit, little-endian
Per entry: transactionsVariableEach one in the standard transaction wire format

constant-k confirmed this layout on 2026-09-20 against the Agave 4.2 serializer. Transaction bytes inside an entry are the same bytes a base64 RPC response carries, so a decoder that reads one reads the other. Their lengths are not in the layout, so reaching the second transaction means decoding the first.

Serialization

Since Agave 4.2 the encoding is wincode, a bincode-compatible serializer from Anza. constant-k nodes run Agave 4.3.0.

bincode cannot decode this payload

A version 1 transaction has no bincode representation, at any version of solana-entry. bincode::deserialize either fails or, on a mixed batch, stops at the first v1 transaction. Jito's own deshred example still calls bincode::deserialize and is out of date.

Rust decoding

CrateVersionWhy
solana-entry4.2 or later, feature agave-unstable-apiThe Entry type. The whole crate sits behind that feature, so a build without it sees nothing at all.
wincodeThe one solana-entry already depends on: 0.5 for solana-entry 4.2, 0.6 for 4.3The serializer. Two wincode versions in one build put Entry on one set of traits and the decode call on the other, which does not compile.

The call is wincode::deserialize::<Vec<Entry>>, the same call Agave uses to read a deshredded payload. The Quickstart has a consumer that runs.

A truncated payload fails with a read-size error. Trailing bytes after a complete list are ignored rather than reported, so a payload that decodes to fewer entries than its length suggests raises nothing.

TypeScript decoding

No JavaScript package implements wincode. The outer layout is four fixed-width fields, which DataView reads directly, and the transactions inside are in the standard wire format, which @solana/kit decodes.

getCompiledTransactionMessageDecoder() from @solana/kit 8.0.0 or later exposes read(bytes, offset), which returns the decoded message and the offset after it. That offset is what walks the payload from one transaction to the next. getTransactionDecoder() does not: it treats everything after the signatures as message bytes and consumes to the end of the buffer, so it only works on a payload holding exactly one transaction.

The transaction's first byte decides which branch reads it:

First byteFormatSignatures
Below 0x80Legacy or v0A one-byte count, then that many 64-byte signatures, then the message
0x81Version 1The message, then header.numSignerAccounts 64-byte signatures

The Quickstart has the walk in full. Transaction v1 covers the rest of that format.

Delivery properties

The response message has two fields. There is no sequence number, no batch index and no completion flag, so everything below is the consumer's responsibility.

PropertyWhat a consumer handles
GranularityA message carries a batch of entries, not necessarily every entry of its slot. Several messages can share a slot value.
OrderSlot values do not only increase. Code that keys on the last slot seen needs a tolerance window.
DuplicatesThe protocol has no message identifier and makes no at-most-once promise. A transaction signature is the key to deduplicate on, held in a set bounded by slot or by time.
CompletenessNo message marks the end of a slot, and a batch whose shreds cannot be recovered never arrives. The feed cannot confirm that a slot is whole.
Empty batchesA message that decodes to zero entries is valid. Treating it as a failure rejects good data.

Absent from the feed

Entries come from a block while its leader is producing it. A block can be skipped or lose its fork, so a transaction in the feed is not a transaction that landed.

Not in the feedSource for it
Execution result: status, fee, logs, compute unitsKaldera, getTransaction
Account state after executionKaldera, getAccountInfo
Confirmation that a transaction landedgetSignatureStatuses
Block metadata: parent slot, blockhash, rewardsgetBlock
Server-side filtersKaldera filters
Past slotsKaldera replay

The usual shape pairs the two: ShredPrism decides what to act on, and a post-execution source says what happened.

Back-pressure

gRPC runs on HTTP/2, which has flow control. A client that stops reading stops the sender instead of losing data, so falling behind costs latency rather than messages.

  1. Read the socket on a task that does nothing else.
  2. Hand each payload to a bounded queue.
  3. Decode and filter behind that queue, never in the reading loop.
  4. Decide what the queue does when it is full, and count the drops.

Differences from a self-hosted proxy

Jito's shredstream-proxy is a process an operator runs next to a node. ShredPrism serves the same service and method as a hosted endpoint.

Self-hosted proxyShredPrism
DeploymentA process to run and keep runningAn endpoint to connect to
Shred ingestUDP on a bind port, 20000 by default. NAT is not supported and the source addresses need firewall rules.None
AuthenticationA Solana keypair, approved in advance, authenticates the proxy upstreamx-token metadata on the gRPC call
Transport to your codePlaintext gRPC on a local portgRPC over HTTP/2 with TLS
Region selection--desired-regions, at most twoThe endpoint hostname
Service and methodshredstream.ShredstreamProxy/SubscribeEntriesIdentical

Upstream references

SourceWhat it covers
Jito ShredStream documentationThe service the protocol comes from. The page carries a sunset notice for Jito's own hosted service, dated 5 September 2026. The protocol it describes is unchanged.
shredstream.protoThe service definition, alongside the heartbeat and trace messages this call does not use
jito-labs/shredstream-proxyThe reference implementation, and the deshred example whose decoding is out of date
solana-entryThe Entry type and its fields
wincodeThe serialization format

On this page