> For the complete documentation index, see [llms.txt](https://docs.rpcfast.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rpcfast.com/rpc-fast-saas-solana/data-streaming/txstream.md).

# Aperture TxStream

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.

{% hint style="success" %}
Use TxStream when transaction arrival time matters more than confirmed post-execution metadata.

**TxStream is available on Aperture plan.**
{% endhint %}

## 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_only` for 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](https://s3-public-assets.rpcfast.com/streaming-speed-comparison.html) 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

| Faster endpoint in the report | Compared with | Shared transactions | Arrived first | Median lead when first | p95 lead when first |
| ----------------------------- | ------------- | ------------------: | ------------: | ---------------------: | ------------------: |
| 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

| Endpoint    | Unique transactions | Coverage |
| ----------- | ------------------: | -------: |
| 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`:

| Field                | Type               | Default           | Description                                                                                                  |
| -------------------- | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------ |
| `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: true` nor `simulation_config`, responses do not include simulation.
* The presence of `simulation_config` enables simulation even when `include_simulation` is false. An explicit config takes precedence over the legacy flag.
* Every `include` flag defaults to false. An empty config still requests simulation, but does not request compute units or any detailed output.

{% hint style="warning" %}
`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.
{% endhint %}

`SimulationConfig` contains:

| Field             | Type                | Description                                                                                                                 |
| ----------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `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

<table><thead><tr><th width="236.21875"></th><th width="269.11328125">Non-batch mode</th><th width="246.015625">Batch transaction delivery</th></tr></thead><tbody><tr><td>RPC</td><td><code>/aperture.Aperture/SubscribeTransactions</code></td><td><code>/aperture.Aperture/SubscribeTransactionBatches</code></td></tr><tr><td>Response stream</td><td><code>DecodedTransaction</code></td><td><code>DecodedTransactionBatch</code></td></tr><tr><td>Delivery behavior</td><td>Emits each matching transaction in its own gRPC message.</td><td>Immediately emits available matching transactions, up to 64 per batch, without waiting for the batch to fill.</td></tr><tr><td>Best suited for</td><td>Minimum transaction-by-transaction delivery delay.</td><td>High-throughput consumers that want fewer protobuf and gRPC messages.</td></tr><tr><td>Ordering without simulation</td><td>Transactions are delivered in stream order, with indexes <code>0, 1, 2, …</code>.</td><td>Transactions remain ordered within each batch and across consecutive batches.</td></tr><tr><td>Ordering with simulation</td><td>Transactions are delivered as soon as their simulations complete. Delivery may therefore be out of order—for example, <code>1, 2, 0</code>—while <code>index</code> preserves the original stream order.</td><td>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.</td></tr></tbody></table>

The same filters, `signatures_only` mode, and simulation option are available in both delivery modes.

{% hint style="success" icon="circle-info" %}
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.
{% endhint %}

### Transaction Response Format

`DecodedTransaction` contains:

| Field                       | Type                           | Description                                                                                                                                 |
| --------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `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:

| Field          | Type                          | Description                                               |
| -------------- | ----------------------------- | --------------------------------------------------------- |
| `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.

| Field                     | Type               | Description                                      |
| ------------------------- | ------------------ | ------------------------------------------------ |
| `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.   |

| Additional field          | Type                                   | Availability and meaning                                                                                                 |
| ------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `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:

| Field     | Type                     | Description                                                                                             |
| --------- | ------------------------ | ------------------------------------------------------------------------------------------------------- |
| `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:

| Field        | Type                | Description                                                                  |
| ------------ | ------------------- | ---------------------------------------------------------------------------- |
| `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:

<table data-search="false"><thead><tr><th>Status</th><th>Meaning</th></tr></thead><tbody><tr><td><code>SIMULATION_STATUS_SUCCEEDED</code></td><td>The simulation succeeded.</td></tr><tr><td><code>SIMULATION_STATUS_FAILED</code></td><td>The simulation failed.</td></tr><tr><td><code>SIMULATION_STATUS_INVALID_TRANSACTION</code></td><td>The transaction is invalid.</td></tr><tr><td><code>SIMULATION_STATUS_BANK_NOT_AVAILABLE</code></td><td>The required Bank state was unavailable. The transaction may still be valid, but no simulation outcome is available.</td></tr><tr><td><code>SIMULATION_STATUS_SERVER_OVERLOADED</code></td><td>Simulation capacity was exhausted or its time limit was exceeded. This is not evidence that the transaction itself failed.</td></tr><tr><td><code>SIMULATION_STATUS_INTERNAL_ERROR</code></td><td>An internal error occurred during simulation.</td></tr></tbody></table>

## Use the Official Rust Client

As a best practice, use the official [`dysnix/aperture-grpc-client`](https://github.com/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.

```rust
use aperture_grpc_client::{
    ApertureClientConfig, ApertureGrpcClient, SubscribeFilters, VoteFilter,
};
use futures_util::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let token = std::env::var("APERTURE_X_TOKEN")?;
    let config = ApertureClientConfig::new("https://aperture-txstream.rpcfast.com:443")
        .with_x_token(token);
    let client = ApertureGrpcClient::new(config);

    let filters = SubscribeFilters::default().vote(VoteFilter::NonVoteOnly);
    let mut stream = Box::pin(client.subscribe_with_reconnect(filters));

    while let Some(message) = stream.next().await {
        let transaction = message?;
        println!(
            "slot={} index={} signatures={}",
            transaction.slot,
            transaction.index,
            transaction.signatures.len()
        );
    }

    Ok(())
}
```

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:

```rust
use aperture_grpc_client::{
    ApertureClientConfig, ApertureGrpcClient, SimulationConfig, SimulationInclude,
    SimulationStatus, SubscribeFilters, VoteFilter,
};
use futures_util::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let token = std::env::var("APERTURE_X_TOKEN")?;
    let config = ApertureClientConfig::new("https://aperture-txstream.rpcfast.com:443")
        .with_x_token(token);
    let client = ApertureGrpcClient::new(config);

    let filters = SubscribeFilters::default()
        .vote(VoteFilter::NonVoteOnly)
        .simulation_config(SimulationConfig {
            include: Some(SimulationInclude {
                compute_units: true,
                account_deltas: true,
                token_balance_deltas: true,
                inner_instructions: true,
                logs: true,
                return_data: true,
            }),
            ..Default::default()
        });
    let mut stream = Box::pin(client.subscribe_with_reconnect(filters));

    while let Some(message) = stream.next().await {
        let transaction = message?;
        let Some(simulation) = transaction.simulation else {
            continue;
        };
        let status = SimulationStatus::try_from(simulation.status)
            .unwrap_or(SimulationStatus::Unspecified);

        println!(
            "slot={} status={status:?} bank_slot={:?} error={:?}",
            transaction.slot,
            simulation.bank_slot,
            simulation.error
        );
        println!("CU used: {:?}", simulation.compute_units_consumed);
        for log in &simulation.logs {
            println!("{log}");
        }
        if let Some(deltas) = &simulation.simulation_state_deltas {
            for delta in &deltas.token_balance_deltas {
                println!("token pre={:?} post={:?}", delta.pre, delta.post);
            }
        }
    }

    Ok(())
}
```

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

{% hint style="warning" %}
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.
{% endhint %}

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:

| TxStream mode            | Median added delivery time | p90 added delivery time |
| ------------------------ | -------------------------: | ----------------------: |
| 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.

```rust
use aperture_grpc_client::{
    ApertureClientConfig, ApertureGrpcClient, SubscribeFilters, VoteFilter,
};
use futures_util::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let token = std::env::var("APERTURE_X_TOKEN")?;
    let config = ApertureClientConfig::new("https://aperture-txstream.rpcfast.com:443")
        .with_x_token(token);
    let client = ApertureGrpcClient::new(config);
    let filters = SubscribeFilters::default()
        .vote(VoteFilter::NonVoteOnly)
        .signatures_only();
    let mut stream = Box::pin(client.subscribe_batches_with_reconnect(filters));

    while let Some(message) = stream.next().await {
        let batch = message?;
        println!("transactions={}", batch.transactions.len());
    }

    Ok(())
}
```

## 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`](https://raw.githubusercontent.com/dysnix/aperture-grpc-proto/main/proto/aperture/txstream.proto) file to your current directory, set `APERTURE_X_TOKEN`, and start a non-vote transaction stream:

```bash
grpcurl \
  -proto txstream.proto \
  -H "x-token: ${APERTURE_X_TOKEN}" \
  -d '{
    "vote": "VOTE_FILTER_NON_VOTE_ONLY",
    "signaturesOnly": true
  }' \
  aperture-txstream.rpcfast.com:443 \
  aperture.Aperture/SubscribeTransactions
```

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:

```bash
grpcurl \
  -proto txstream.proto \
  -H "x-token: ${APERTURE_X_TOKEN}" \
  -d '{
    "vote": "VOTE_FILTER_NON_VOTE_ONLY",
    "signaturesOnly": true,
    "simulationConfig": {
      "include": {
        "computeUnits": true,
        "accountDeltas": true,
        "tokenBalanceDeltas": true,
        "innerInstructions": true,
        "logs": true,
        "returnData": true
      }
    }
  }' \
  aperture-txstream.rpcfast.com:443 \
  aperture.Aperture/SubscribeTransactions
```

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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rpcfast.com/rpc-fast-saas-solana/data-streaming/txstream.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
