> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/real-time-streaming/deshred-transactions.md).

# Deshred Transactions gRPC

SubscribeDeshred streams Solana transactions rebuilt from shreds before execution, with vote and account filters and best-effort ALT resolution.

Deshred is the `SubscribeDeshred` method on the same gRPC service as Dragon's Mouth `Subscribe`.

## Use cases

Deshred is for strategies that act before the node replays transactions:

* **HFT and arbitrage** that react to transaction intent the moment entries form from shreds.
* **MEV and market making** that need an early view of price-impacting transactions.
* **Copy-trading and liquidations** that follow specific accounts as soon as they act.

**What not to use it for.** If you need execution results (status, balance changes, logs) or any confirmation guarantee, use the [Dragon's Mouth](/solana/real-time-streaming/dragon-s-mouth-grpc.md) `transactions` stream instead, or run it in parallel on its own connection and join on `signature`. Stream Dragon's Mouth at `processed` and track `confirmed` and `finalized` on the client from [slot notifications](/solana/real-time-streaming/dragon-s-mouth-grpc.md#slots). Deshred shows intent, not outcome: a transaction may fail, land on a dead fork, or never confirm.

## Features and benefits

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-eye">:eye:</i> <strong>Pre-execution stream</strong></td><td>Transactions reconstructed from shreds, before the node replays them.</td><td></td></tr><tr><td><i class="fa-code-fork">:code-fork:</i> <strong>Same gRPC interface</strong></td><td>Same client library, separate method. Open a separate connection for each stream, including your Dragon's Mouth stream.</td><td></td></tr><tr><td><i class="fa-tags">:tags:</i> <strong>Resolved ALT addresses</strong></td><td>Includes writable and readonly addresses resolved from Address Lookup Tables.</td><td></td></tr></tbody></table>

## How it works

Unlike the standard `Subscribe` transaction stream, deshred updates are emitted **before** Replay. You receive the decoded transaction earlier, but without execution context.

The lead over Dragon's Mouth varies per transaction. Measure it against the `transactions` stream at `processed`, not `confirmed` or `finalized`, which arrive later. Run both streams on separate connections and join on `signature`. Subtract the `processed` arrival time from the Deshred arrival time, so a negative value means Deshred arrived first. Compare P50 and P99 of that difference. P99 is the slow tail, the transactions where Deshred arrived latest relative to `processed`. Real-time workloads care about that tail.

```mermaid
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#F2EDF6','primaryBorderColor':'#7A4BA0','primaryTextColor':'#171717','lineColor':'#956FB3','secondaryColor':'#E4DBEC','tertiaryColor':'#D7C9E3','edgeLabelBackground':'#F2EDF6'},'flowchart':{'nodeSpacing':20,'rankSpacing':35,'curve':'linear'}}}%%
flowchart LR
    s["Shreds"] --> r["Reconstruct<br/>transactions"]
    r --> e["Execute + replay"] --> g["Regular gRPC"]
    r --> d["Deshred Transactions gRPC<br/>(pre-execution)"]
    style d fill:#D6EAF8,stroke:#259DD0
```

## Filter configuration

`SubscribeDeshred` matches transactions on four filter fields, combined as logical AND, and has one opt-in flag:

| Parameter               | Type       | Required | Description                                                                                                                                                                                                         |
| ----------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `vote`                  | `bool`     | No       | `true` returns vote transactions. `false` returns non-vote transactions. Omitted returns both. Alpenglow blocks have none.                                                                                          |
| `account_include`       | `string[]` | No       | Match transactions that mention any of these accounts, including ALT addresses the node resolves at its root slot. Empty list: no restriction.                                                                      |
| `account_exclude`       | `string[]` | No       | Exclude transactions mentioning any of these accounts, including ALT addresses the node resolves at its root slot. A transaction that reaches an excluded account only through an unresolved table is not excluded. |
| `account_required`      | `string[]` | No       | Accounts that MUST all be mentioned (every one of them), including ALT addresses the node resolves at its root slot.                                                                                                |
| `include_update_parent` | `bool`     | No       | Also send `SubscribeUpdateDeshredUpdateParent` updates. Omitted or `false`: transactions are sent, update parents are not.                                                                                          |

For the full request and update fields, see the [SubscribeDeshred method reference](/solana/rpc-methods/real-time-streaming/yellowstone-grpc/deshred.md).

## Subscribe and consume

The latest protobuf files live in the [yellowstone-grpc repo](https://github.com/rpcpool/yellowstone-grpc/tree/master/yellowstone-grpc-proto/proto). For Rust, use the [yellowstone-grpc-client](https://crates.io/crates/yellowstone-grpc-client) and [yellowstone-grpc-proto](https://crates.io/crates/yellowstone-grpc-proto) crates.

{% tabs %}
{% tab title="TypeScript" %}
The examples use top-level `await`. Set up the project as in the [streaming quickstart](/solana/real-time-streaming/quickstart.md) (`type=module`, `moduleResolution` bundler).

```typescript
import Client, {
  SubscribeDeshredRequest,
} from "@triton-one/yellowstone-grpc";

const client = new Client(
  "https://<your-endpoint>.mainnet.rpcpool.com",
  "<your-token>",
  undefined
);

await client.connect();
const stream = await client.subscribeDeshred();

stream.on("data", (data) => {
  console.log("data", data);
});

const request: SubscribeDeshredRequest = {
  slots: {},
  deshredTransactions: {
    client: {
      vote: false,
      accountInclude: [],
      accountExclude: [],
      accountRequired: [],
    },
  },
  ping: undefined,
};

await new Promise<void>((resolve, reject) => {
  stream.write(request, (err) =>
    err ? reject(err) : resolve()
  );
});
```

{% endtab %}

{% tab title="Rust" %}
{% code title="Cargo.toml" %}

```toml
[dependencies]
yellowstone-grpc-client = "17"
yellowstone-grpc-proto = "14"
solana-signature = "3"
tokio = { version = "1", features = ["full"] }
futures = "0.3"
tonic = { version = "0.14", features = ["tls-native-roots", "tls-ring"] } # TLS roots and crypto provider
anyhow = "1"
```

{% endcode %}

{% code title="src/main.rs" %}

```rust
use {
    futures::{sink::SinkExt, stream::StreamExt},
    solana_signature::Signature,
    std::collections::HashMap,
    yellowstone_grpc_client::{ClientTlsConfig, GeyserGrpcClient},
    yellowstone_grpc_proto::prelude::{
        subscribe_update_deshred::UpdateOneof, SubscribeDeshredRequest,
        SubscribeRequestFilterDeshredTransactions, SubscribeRequestPing,
    },
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let endpoint = std::env::var("ENDPOINT")
        .unwrap_or("https://<your-endpoint>.mainnet.rpcpool.com:443".into());
    let x_token = std::env::var("X_TOKEN").ok();

    let mut client = GeyserGrpcClient::build_from_shared(endpoint)?
        .x_token(x_token)?
        .tls_config(ClientTlsConfig::new().with_native_roots())?
        .http2_adaptive_window(true)
        .initial_connection_window_size(8 * 1024 * 1024) // 8 MiB
        .initial_stream_window_size(4 * 1024 * 1024) // 4 MiB
        .connect()
        .await?;

    let request = SubscribeDeshredRequest {
        deshred_transactions: HashMap::from([(
            "deshred".into(),
            SubscribeRequestFilterDeshredTransactions {
                vote: Some(false),
                account_include: vec![],
                account_exclude: vec![],
                account_required: vec![],
                ..Default::default()
            },
        )]),
        ping: None,
        ..Default::default()
    };

    let (mut tx, mut stream) =
        client.subscribe_deshred_with_request(Some(request)).await?;

    while let Some(msg) = stream.next().await {
        match msg?.update_oneof {
            Some(UpdateOneof::DeshredTransaction(update)) => {
                let info = update.transaction.as_ref().unwrap();
                let sig = Signature::try_from(info.signature.as_slice())?;
                println!("slot={} sig={sig} vote={}", update.slot, info.is_vote);
            }
            Some(UpdateOneof::Ping(_)) => {
                tx.send(SubscribeDeshredRequest {
                    ping: Some(SubscribeRequestPing { id: 1 }),
                    ..Default::default()
                }).await?;
            }
            Some(UpdateOneof::Pong(_)) => {}
            Some(UpdateOneof::Slot(_)) => {}
            // Other update types, such as update parents, are sent when you opt in
            Some(_) => {}
            None => break,
        }
    }

    Ok(())
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Response payload example

A `SubscribeUpdateDeshred` update carries a `deshred_transaction` with a single transaction reconstructed from shreds. This is a simplified shape of that field.

Clients return `signature`, `signatures`, `account_keys`, `recent_blockhash`, `loaded_writable_addresses` and `loaded_readonly_addresses` as raw bytes. The example shows them base58-encoded and with proto snake\_case names. The TypeScript client returns camelCase names, such as `deshredTransaction` and `isVote`.

```json
{
  "slot": 275123456,
  "transaction": {
    "signature": "5j7s4Hk3QmZ9xT2pK8nLm9VbY3wQ8aRf6dGjXwE5pN1",
    "is_vote": false,
    "transaction": {
      "signatures": ["5j7s4Hk3..."],
      "message": {
        "header": { "...": "..." },
        "account_keys": ["...", "..."],
        "recent_blockhash": "GpJjHvT...",
        "instructions": [{ "...": "..." }]
      }
    },
    "loaded_writable_addresses": ["..."],
    "loaded_readonly_addresses": []
  }
}
```

The `loaded_writable_addresses` and `loaded_readonly_addresses` fields contain addresses the node resolves from Address Lookup Tables (ALTs) at its root slot, so deshred filters match static account keys and, when resolution succeeds, dynamically loaded addresses. When resolution fails, both fields are empty and only static account keys match.

## Limitations

Deshred carries the raw transaction, captured before execution, so what it returns differs from the standard `transactions` stream:

| What you get             | Standard transactions (Dragon's Mouth)                                 | Deshred                                                  |
| ------------------------ | ---------------------------------------------------------------------- | -------------------------------------------------------- |
| Timing                   | At `processed`: after execution and replay                             | Pre-execution, from shreds                               |
| Transaction              | Full transaction                                                       | Full transaction                                         |
| ALT addresses            | Resolved                                                               | Resolved (writable and readonly)                         |
| Execution context        | Full: status, balance changes, inner instructions, logs, compute units | None: intent, not outcome                                |
| Confirmation or finality | Yes: track `confirmed` and `finalized` from slot notifications         | None: a transaction may fail, fork off, or never confirm |

If your pipeline needs status, logs, or balance deltas, run a parallel Dragon's Mouth `transactions` subscription on a separate connection and join on `signature`.

For architecture and tradeoffs, see [Deshred transactions on the Triton blog](https://blog.triton.one/deshred-transactions-the-fastest-path-to-solana-data/).

## Availability

* `SubscribeDeshred` runs on Triton One gRPC servers.
* Self-hosted, it needs Agave 4.1 or later and a `yellowstone-grpc-geyser` release built for your Agave version, 14.1.1 or later.
* On Agave 4.1 and 4.2, start the validator with `--full-rpc-api` and an RPC port (`--rpc-port`), or it does not emit deshred transaction notifications.

## Pricing

For rates, see the [pricing page](https://triton.one/pricing). For how billing works across Triton services, see [Plans and billing](/account-and-billing/plans-and-billing.md).

## What's next

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-tower-broadcast">:tower-broadcast:</i> <strong>Dragon's Mouth gRPC</strong></td><td>Sub-slot real-time updates for accounts, transactions, slots, and blocks via gRPC.</td><td><a href="/solana/real-time-streaming/dragon-s-mouth-grpc.md">Dragon's Mouth gRPC</a></td></tr><tr><td><i class="fa-newspaper">:newspaper:</i> <strong>Deshred blog post</strong></td><td>Architecture, tradeoffs, and how Deshred fits the Solana shred pipeline.</td><td><a href="https://blog.triton.one/deshred-transactions-the-fastest-path-to-solana-data/">https://blog.triton.one/deshred-transactions-the-fastest-path-to-solana-data/</a></td></tr></tbody></table>

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
