TxStream gRPC
RPC Fast's optimised protocol for real-time deshredded Solana transactions and transaction simulation.
TxStream is RPC Fast's purpose-built gRPC protocol for receiving decoded Solana transactions directly from the shred pipeline. It is a highly flexible protocol with transaction filtering, real-time transaction simulation, signatures-only responses, and batch transaction delivery.
We reinvented shred-level transaction streaming: RPC Fast reconstructs, recovers, deshreds, decodes, filters, and streams transactions through one optimised path, before normal validator replay metadata is available.
Use TxStream when transaction arrival time matters more than confirmed post-execution metadata.
TxStream is available on Aperture plan.
Why Use TxStream?
Faster transaction delivery. The protocol is optimised specifically for transaction streaming, with compact payload and batch delivery modes.
Lower client overhead. Transactions arrive decoded, with no raw shred or Solana Entry reconstruction required in your application.
Server-side filters. Filter by vote status, signature, included accounts, excluded accounts, or required accounts before data crosses the network.
Compact modes. Use
signatures_onlyfor timing and monitoring workloads, or batch transaction delivery to reduce per-message gRPC overhead.Resolved Address Lookup Tables. RPC Fast was one of the first providers to resolve ALTs for deshredded transactions. Loaded writable and read-only addresses are included when available and participate in account filters.
Real-time transaction simulation. RPC Fast is the first provider to offer real-time simulation of deshredded transactions. Transaction-status simulation achieves approximately 95% accuracy compared with actual execution results.
Performance Comparisons
The latest gRPC stream speed report was generated on August 25, 2026 from a 3-minute run. It compared identical transaction signatures at the same observer using local receive timestamps. All three streams used the account-include filter pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA.
Pairwise results
TxStream
Yellowstone
103,073
99.8%
5.02 ms
17.08 ms
ShredStream
Yellowstone
58,688
99.9%
4.82 ms
16.04 ms
ShredStream
TxStream
58,688
50.9%
30 us
571 us
TxStream and ShredStream were effectively neck-and-neck on shared transactions: ShredStream arrived first in 50.9% of matched races and TxStream in the remaining 49.1%.
Both shred-derived streams delivered transactions before Yellowstone in more than 99.8% of their matched races.
Coverage observed in this run
TxStream
103,073
99.9%
ShredStream
58,688
56.9%
Yellowstone
103,177
100.0%
Coverage describes this specific run and filter; it is not a general availability or reliability guarantee. ShredStream coverage is lower here because the benchmark collector does not resolve Address Lookup Tables (ALTs), so transactions that reference the filter account only through an ALT are not matched. This is a filter-coverage difference, not evidence that those transactions were absent from the raw shred stream. Pairwise speed results are calculated only from signatures observed by both endpoints.
Protocol Reference
Full protocol reference can be found at https://github.com/dysnix/aperture-grpc-proto
TxStream uses the aperture.Aperture gRPC service and a single request format for both delivery modes.
Request Format
Both subscription methods accept SubscribeTransactionsRequest:
vote
VoteFilter
VOTE_FILTER_ALL
Stream all transactions, votes only, or non-votes only.
signature
bytes
empty
Match one 64-byte primary transaction signature.
account_include
repeated bytes
empty
Match when any listed 32-byte static or loaded account is present.
account_exclude
repeated bytes
empty
Reject when any listed 32-byte static or loaded account is present.
account_required
repeated bytes
empty
Match only when every listed 32-byte static or loaded account is present.
signatures_only
bool
false
Return only transaction identity and timing fields.
include_simulation
bool
false
Legacy. Prefer simulation_config.include.compute_units: true for lightweight simulation.
simulation_config
SimulationConfig
absent
Enable simulation and explicitly select logs, state deltas, CPI instructions, return data and compute units.
Different filter fields are combined with logical AND. Values inside account_include and account_exclude use OR, while every account_required value must match. With no filters, TxStream delivers all transactions.
Simulation Request Format
Simulation is available on both subscription methods, including with signatures_only.
With neither
include_simulation: truenorsimulation_config, responses do not include simulation.The presence of
simulation_configenables simulation even wheninclude_simulationis false. An explicit config takes precedence over the legacy flag.Every
includeflag defaults to false. An empty config still requests simulation, but does not request compute units or any detailed output.
include_simulation is a legacy field, retained for backward compatibility. For new integrations, use simulation_config.include.compute_units: true instead. This requests lightweight simulation: status, error, compute units when available, Bank slot and timing, with logs and other details disabled.
SimulationConfig contains:
include
SimulationInclude
Select response details using the flags below.
account_include
repeated bytes
Restrict deltas to these 32-byte account addresses. Empty means unrestricted.
owner_include
repeated bytes
Restrict deltas to accounts owned by any of these 32-byte program IDs before or after simulation. Empty means unrestricted.
SimulationInclude flag
Response field
compute_units
simulation.compute_units_consumed
account_deltas
simulation.simulation_state_deltas.account_deltas
token_balance_deltas
simulation.simulation_state_deltas.token_balance_deltas
inner_instructions
simulation.inner_instructions
logs
simulation.logs
return_data
simulation.return_data
Delta filters versus transaction filters
Top-level account_include selects which transactions enter your stream. Nested simulation_config.account_include only selects accounts in the returned deltas; it does not select transactions or limit which instructions execute in simulation.
Within each nested list, matching is OR. When both nested lists are non-empty, the account address and its pre- or post-simulation owner program must match. owner_include matches the Solana account's owning program, not the token authority stored in TokenBalanceState.owner. For example, a token program ID selects its token accounts; a wallet address is not a token-owner-program filter.
These filters affect account and token balance deltas only. They do not filter logs, CPI instructions, return data or compute units.
All public keys use raw 32-byte values in protobuf and base64 strings in protobuf JSON, rather than base58 text. The examples below use protobuf JSON's lowerCamelCase field names; the reference tables use protobuf snake_case names.
Non-Batch and Batch Delivery
RPC
/aperture.Aperture/SubscribeTransactions
/aperture.Aperture/SubscribeTransactionBatches
Response stream
DecodedTransaction
DecodedTransactionBatch
Delivery behavior
Emits each matching transaction in its own gRPC message.
Immediately emits available matching transactions, up to 64 per batch, without waiting for the batch to fill.
Best suited for
Minimum transaction-by-transaction delivery delay.
High-throughput consumers that want fewer protobuf and gRPC messages.
Ordering without simulation
Transactions are delivered in stream order, with indexes 0, 1, 2, ….
Transactions remain ordered within each batch and across consecutive batches.
Ordering with simulation
Transactions are delivered as soon as their simulations complete. Delivery may therefore be out of order—for example, 1, 2, 0—while index preserves the original stream order.
Transaction order is preserved. A batch is delivered only after all simulations in that batch finish, so its latency is determined by the slowest simulation.
The same filters, signatures_only mode, and simulation option are available in both delivery modes.
Use the non-batch stream when the lowest possible simulation latency is the priority. Use the batch stream when preserving delivery order is more important.
Transaction Response Format
DecodedTransaction contains:
slot
uint64
Solana slot containing the transaction.
index
uint64
Transaction index within the subscription.
is_vote
bool
Whether this is a vote transaction.
created_at_unix_nanos
uint64
Transaction stream timestamp in Unix nanoseconds.
signatures
repeated bytes
Transaction signatures; each signature is 64 bytes.
version
TransactionVersion
TRANSACTION_VERSION_LEGACY or TRANSACTION_VERSION_V0.
header
MessageHeader
Required-signature and read-only-account counts.
static_account_keys
repeated bytes
Static 32-byte account keys from the transaction message.
loaded_writable_addresses
repeated bytes
Resolved writable 32-byte ALT addresses.
loaded_readonly_addresses
repeated bytes
Resolved read-only 32-byte ALT addresses.
recent_blockhash
bytes
The transaction's 32-byte recent blockhash.
instructions
repeated CompiledInstruction
Compiled transaction instructions.
simulation
TransactionSimulation
Present when include_simulation is true or simulation_config is provided.
alt_resolution
optional string
FULL when every ALT lookup was resolved, PARTIAL when one or more could not be resolved, and absent when ALT resolution is unavailable.
MessageHeader contains num_required_signatures, num_readonly_signed_accounts, and num_readonly_unsigned_accounts. CompiledInstruction contains program_id_index, the instruction's account indexes, and its raw instruction data.
Instruction account indexes refer to the following concatenated key list:
static_account_keys + loaded_writable_addresses + loaded_readonly_addresses
When signatures_only is enabled, responses retain slot, index, is_vote, created_at_unix_nanos, signatures, version, and an optional simulation result. Transaction message fields are omitted.
Batch Response Format
DecodedTransactionBatch contains one field:
transactions
repeated DecodedTransaction
One to 64 transactions matching the subscription request.
Each transaction has the same format as a non-batch response.
Simulation Response Format
When requested, TransactionSimulation contains the outcome and timing fields below, plus the selected details. Optional values may be absent when unavailable; repeated fields are empty when not requested or when there are no results. Missing compute units must not be interpreted as zero.
bank_slot
optional uint64
Slot used for the simulation result.
status
SimulationStatus
Simulation outcome.
error
optional string
Error details when simulation is not successful.
simulated_at_unix_nanos
uint64
Simulation timestamp in Unix nanoseconds.
processing_time_nanos
uint64
Simulation processing duration in nanoseconds.
compute_units_consumed
optional uint64
CU used, when available. Enabled by legacy include_simulation, or explicitly by include.compute_units.
fee
optional uint64
Transaction fee in lamports, when supplied by the simulator. There is no include flag for this field.
logs
repeated string
Program logs from simulation when include.logs is true.
return_data
TransactionReturnData
Program return value when requested and available: program_id (bytes) and data (bytes).
simulation_state_deltas
SimulationStateDeltas
Selected account and/or token deltas when requested and available. Contains account_deltas and token_balance_deltas.
inner_instructions
repeated SimulationInnerInstructions
Simulated CPI instructions when include.inner_instructions is true.
Account deltas
Each AccountDelta contains:
account
bytes
The 32-byte writable account address.
pre
SimulationAccountState
State before simulation, when present.
post
SimulationAccountState
Effective state after simulation, when present.
changed
bool
True for returned entries; includes changes to account data even if the returned metadata is identical.
SimulationAccountState contains lamports (uint64), owner (owning program, bytes), executable (bool) and rent_epoch (uint64). Raw account data is not returned.
Only changed writable accounts are included. A missing pre/post account state represents account creation or closure. For failed execution, deltas describe effective rollback state, including applicable fee and nonce changes, rather than intermediate writes from a failed instruction.
Token balance deltas
Each TokenBalanceDelta contains:
account
bytes
The 32-byte token account address.
pre
TokenBalanceState
Parsed token state before simulation, when present.
post
TokenBalanceState
Parsed token state after simulation, when present.
pre_owner
bytes
Solana account's owning program before simulation, used by the owner filter.
post_owner
bytes
Solana account's owning program after simulation, used by the owner filter.
TokenBalanceState contains mint (bytes), owner (token authority, bytes), program_id (token program, bytes) and amount (uint64).
Only changed token states from writable accounts are returned. Missing pre/post token state can represent creation, closure or conversion to/from a token account. Amounts are raw integer token units: decimals and UI amounts are not included, and simulation does not fetch mint accounts to convert them. Token-2022 reports the base token balance without extension balances.
For an unchanged mint, calculate the signed token amount change as post.amount - pre.amount, treating a missing side as zero for creation/closure. Use signed or arbitrary-precision arithmetic to avoid unsigned underflow. If the mint changes, interpret the pre and post states separately.
Inner instructions
Each SimulationInnerInstructions group contains instruction_index (uint32, the outer instruction index) and repeated instructions.
Each SimulationInnerInstruction contains program_id (bytes), accounts (repeated bytes), data (bytes) and stack_height (uint32). Program and account keys are already resolved public keys, rather than indexes into the transaction's account list.
These logs, deltas, inner instructions and return values are predictions from simulation, not confirmed execution metadata.
SimulationStatus values:
SIMULATION_STATUS_SUCCEEDED
The simulation succeeded.
SIMULATION_STATUS_FAILED
The simulation failed.
SIMULATION_STATUS_INVALID_TRANSACTION
The transaction is invalid.
SIMULATION_STATUS_BANK_NOT_AVAILABLE
The required Bank state was unavailable. The transaction may still be valid, but no simulation outcome is available.
SIMULATION_STATUS_SERVER_OVERLOADED
Simulation capacity was exhausted or its time limit was exceeded. This is not evidence that the transaction itself failed.
SIMULATION_STATUS_INTERNAL_ERROR
An internal error occurred during simulation.
Use the Official Rust Client
As a best practice, use the official dysnix/aperture-grpc-client. It provides byte-safe filters, tuned HTTP/2 flow control, TLS native roots, keepalives, X-Token authentication, and automatic reconnection.
Set APERTURE_X_TOKEN to your RPC Fast token before running the example.
An empty filter streams all transactions. Apply the narrowest server-side filter that serves your workload to reduce bandwidth and client-side work.
Request Real-Time Simulation
Use aperture-grpc-client 0.6.1 or later for SimulationConfig and the detailed response types. Regenerate other clients from the current official proto.
Use the client's simulation_config with include.compute_units: true for lightweight predictions, and enable additional flags for details. The legacy include_simulation option remains supported for backward compatibility. The following example requests all supported details for every matching deshredded transaction:
Simulation results can include:
simulation status, error, Bank slot and timing
compute units consumed
program logs and return data
writable account metadata and token balance changes
CPI instructions with resolved accounts and stack heights
Enabling simulation adds latency. Simulation results are predictive and may differ from the transaction's eventual execution outcome; transaction-status simulation accuracy is approximately 95% compared with actual execution results.
Clients that do not request simulation remain on the immediate pre-execution path. For a compact prediction feed, combine simulation_config with include.compute_units: true and signatures_only. Enable only the details you need: recording logs, CPI and state deltas adds work and payload.
Simulation Delivery Latency
The matched-signature comparison measured simulation-enabled TxStream against the equivalent non-simulation stream:
Signatures only
832 us
1.72 ms
Full transaction payload
791 us
1.62 ms
Receive Transaction Batches
Use the batch stream when throughput and lower protobuf/gRPC overhead matter more than emitting each transaction in its own message.
Important Semantics
TxStream is an early transaction feed, not a final source of execution truth.
A streamed transaction can fail, never confirm, or land on a fork that does not survive.
The normal pre-execution stream does not contain confirmed balances, inner instructions, rewards, execution status, or final program logs.
ALT addresses are emitted when resolved. You must tolerate unresolved addresses and must not treat the stream as authoritative replay state.
Reconnect after transport failures. The official client does this automatically with exponential backoff.
Use Yellowstone gRPC when you need confirmed execution metadata, account updates, blocks, or other replay-derived data.
Test TxStream with grpcurl
Download the official txstream.proto file to your current directory, set APERTURE_X_TOKEN, and start a non-vote transaction stream:
For lightweight simulation, add "simulationConfig": {"include": {"computeUnits": true}} to the request body. includeSimulation is a legacy field; prefer simulationConfig.include.computeUnits: true for new integrations.
To request detailed simulation, use:
Use the same request with aperture.Aperture/SubscribeTransactionBatches for batched delivery. In protobuf JSON responses, byte fields are base64 and uint64 values, including token amounts and timestamps, are decimal strings.
When to Use TxStream
The use cases can be split into two categories:
1/ Decoded, reconstructed transactions – better developer experience, less engineering work.
Key benefit: less custom infrastructure, faster integration, and no need to decode shreds or reconstruct transactions yourself.
Best for
HFT bot developers looking for the fastest path to production with minimal engineering effort.
Trading platforms that need transaction parsing without maintaining their own decoder.
Wallets tracking pending user transactions.
Analytics & monitoring platforms consuming structured real-time transaction data.
Copy trading platforms monitoring market activity before block confirmation.
Solana developers who need pre-confirmation data without building a shred reconstruction pipeline.
2/ Real-time execution simulation – decision-making edge for latency-sensitive applications).
Key benefit: fewer wasted transactions, fewer false positives, lower compute costs, and faster decision-making under tight latency constraints.
Best for
MEV searchers filtering profitable opportunities from transactions that will actually execute.
Arbitrage bots avoiding failed swaps and reducing false-positive signals.
Liquidation bots confirming liquidation candidates before committing capital.
High-frequency trading (HFT) systems making routing decisions with higher confidence.
Market makers reacting only to executable market events.
Copy-trading platforms replicating only transactions likely to succeed.
Risk engines estimating execution outcomes before block inclusion.
Last updated