# Turbo Kaldera (aRPC)

> Decoded pre-execution transactions over the same Yellowstone API, and the metadata they omit.

Source: https://docs.constant-k.com/kaldera/turbo-kaldera/

Turbo Kaldera delivers decoded pre-execution transactions over the same Yellowstone protocol as [Kaldera](https://docs.constant-k.com/kaldera/). aRPC, anticipatory RPC, is constant-k's name for pre-execution transaction streaming.

## Stage

Turbo Kaldera does the erasure decoding, reassembly and deserialization on the server, and delivers before execution. An update reaches your code as an ordinary Yellowstone transaction update. [Data Stages](https://docs.constant-k.com/get-started/data-stages/) sets out all six stages and the stage each product delivers at.

## Endpoints

| Region    | Endpoint                                                    |
| :-------- | :---------------------------------------------------------- |
| New York  | `https://turbo-kaldera-newyork.constant-k.com` (port 443)   |
| Frankfurt | `https://turbo-kaldera-frankfurt.constant-k.com` (port 443) |
| Amsterdam | `https://turbo-kaldera-amsterdam.constant-k.com` (port 443) |

The API key is the same as Kaldera's, sent as `x-token`.

## Plan access and limits

Turbo `Subscribe` on the hostnames above is Nexus only. A key on a lower plan is refused with gRPC status `PERMISSION_DENIED` (7) and the message `Permission Denied: Insufficient Tier`. Blade Runner reaches the same pre-execution data through the `SubscribeDeshred` method on any Kaldera hostname.

|                                            | Blade Runner |  Nexus  |
| :----------------------------------------- | :----------: | :-----: |
| Turbo `Subscribe` on the turbo hostnames   |      No      |   Yes   |
| `SubscribeDeshred` on any Kaldera hostname |      Yes     |   Yes   |
| `SubscribeDeshred` streams                 |      15      |    25   |
| `SubscribeDeshred` bandwidth               |   22.5 MB/s  | 75 MB/s |

Turbo streams are `Subscribe` streams. They come out of the same stream and bandwidth allowance as your standard [Kaldera](https://docs.constant-k.com/kaldera/#streams-and-limits) streams, not a separate turbo budget: a Nexus key holding its full 200 `Subscribe` streams must close one before it can open a turbo stream. `SubscribeDeshred` is counted separately. Limits apply per region; the [pricing page](https://www.constant-k.com/pricing/) has the published table.

## Client setup

An existing Yellowstone client needs only the turbo hostname. In Rust, the [Kaldera quickstart](https://docs.constant-k.com/kaldera/quickstart/) example changes by its endpoint alone.

```ts
import Client, { CommitmentLevel, type SubscribeUpdate } from "@triton-one/yellowstone-grpc";
import bs58 from "bs58";

const client = new Client(
  "https://turbo-kaldera-newyork.constant-k.com", // or turbo-kaldera-frankfurt, turbo-kaldera-amsterdam
  process.env.CK_API_KEY,
  undefined,
);
await client.connect();

const stream = await client.subscribe({
  commitment: CommitmentLevel.PROCESSED,
  transactions: {
    pumpAmm: {
      vote: false,
      accountInclude: ["pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"],
      accountExclude: [],
      accountRequired: [],
    },
  },
  accounts: {},
  slots: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  blockFooter: {},
  accountsDataSlice: [],
});

stream.on("data", (update: SubscribeUpdate) => {
  const info = update.transaction?.transaction;
  if (!info?.transaction?.message) return;

  const signature = bs58.encode(info.signature);
  const accountKeys = info.transaction.message.accountKeys.map((k) => bs58.encode(k));

  // Pre-execution: info.meta is absent, so there is no fee, status,
  // logs or balance data, and info.index is always 0.
  console.log(update.transaction!.slot, signature, accountKeys.length, "keys");
});
```

## What an update contains

Turbo sends transaction updates in the normal `SubscribeUpdate` format, with the transaction message filled in and no execution metadata.

| Present                                                               | Absent                                                  |
| :-------------------------------------------------------------------- | :------------------------------------------------------ |
| Signature                                                             | The whole `meta` object                                 |
| The transaction message: account keys, instructions, recent blockhash | Fee, success or error status, logs                      |
| Lookup table references, and the addresses they resolve to            | Pre and post balances, token balance changes            |
| Slot                                                                  | Compute units consumed, inner instructions, return data |
| Vote flag                                                             |                                                         |

`meta` is not a zeroed object: the field is absent, `undefined` in TypeScript and `None` in Rust. Code that reads `meta.fee`, `meta.err` or `meta.logMessages` gets nothing or throws, and tools that validate execution metadata, including some benchmarking tools, discard Turbo updates. `err` and the rest come from standard [Kaldera](https://docs.constant-k.com/kaldera/) or [Solana RPC](https://docs.constant-k.com/rpc/).

> **index is always 0:** Every Turbo update carries `index: 0`. Reassembly happens before the block is put together, so a per-block transaction index does not exist yet. Code that sorts, orders or deduplicates on `index` silently does the wrong thing. Arrival order and signature are the reliable keys.

A Turbo update means the transaction exists, not that it succeeded. Any of them can fail at execution, and rarely one misses the block. The reliable signal is intent and targets: which program, which accounts, which signer. Outcomes are reconciled downstream.

### Lookup table addresses are resolved

Accounts that a transaction reaches through an address lookup table are merged into `transaction.message.accountKeys`: loaded writable addresses first, then loaded readonly, in Solana's own resolution order. The raw references stay in `message.addressTableLookups`. Server-side account filters match accounts referenced through a lookup table, and so does your own check on `accountKeys`.

## Filters on Turbo

Only the `transactions` map is honoured, and only four of its fields.

| Field                                                 | On Turbo                                                                                                                          |
| :---------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| `accountInclude`, `accountExclude`, `accountRequired` | Honoured. They match the account keys in the message, lookup table addresses included.                                            |
| `vote`                                                | Honoured. `vote: false` applies as on standard Kaldera.                                                                           |
| `failed`                                              | Best left unset. `false` is accepted and changes nothing. `true` is rejected: nobody knows yet whether the transaction will fail. |
| `signature`                                           | Rejected.                                                                                                                         |
| `cuckooAccountInclude`                                | Rejected. The `SubscribeDeshred` filter defines no compressed-filter field, so there is nothing to carry the set.                 |

A subscription carrying a [compressed account filter](https://docs.constant-k.com/kaldera/filters/#compressed-account-filters) is refused rather than served without it, since serving it would mean dropping the constraint and streaming every transaction. Standard [Kaldera](https://docs.constant-k.com/kaldera/) accepts that filter on the `kaldera-<region>` hostname.

The rest of the request is either rejected or ignored.

| In the request                                                    | What happens                                                                   |
| :---------------------------------------------------------------- | :----------------------------------------------------------------------------- |
| `accounts`, `blocks`, `blocksMeta`, `entry`, `transactionsStatus` | Rejected with `INVALID_ARGUMENT` (3)                                           |
| `fromSlot`                                                        | Rejected with `INVALID_ARGUMENT` (3). Turbo has no [replay](https://docs.constant-k.com/kaldera/replay/). |
| `slots`                                                           | Accepted and ignored                                                           |

> **Slot filters are accepted and do nothing:** A Turbo request that carries a `slots` filter opens normally, reports no error, and never delivers a slot update. The chain tip comes from a small standard Kaldera stream with a `slots` filter, run beside the Turbo stream.

## Turbo or standard Kaldera

Turbo suits work where being first matters more than being complete: copy trading, MEV detection, or watching a pool for its first touch. Standard Kaldera suits logic that reads execution results.

Running both means the same accounts on each service, matched by signature: Turbo says the transaction exists, standard Kaldera at `CONFIRMED` says whether it succeeded. The two count as two streams toward your plan limits.

## SubscribeDeshred

Turbo delivers pre-execution data through the ordinary `Subscribe` method, so existing Yellowstone code works unchanged. Yellowstone also defines `SubscribeDeshred`, a separate method with its own request and update types.

|                        | Turbo `Subscribe`                           | `SubscribeDeshred`                                                |
| :--------------------- | :------------------------------------------ | :---------------------------------------------------------------- |
| Plans                  | Nexus                                       | Blade Runner and Nexus                                            |
| Hostnames              | The turbo hostnames above                   | Every Kaldera hostname, turbo and standard                        |
| Request                | `SubscribeRequest`, as on standard Kaldera  | `SubscribeDeshredRequest`: `deshredTransactions` and `slots`      |
| Update                 | `SubscribeUpdate`, `meta` absent, `index` 0 | `SubscribeUpdateDeshred`                                          |
| Lookup table addresses | Merged into `message.accountKeys`           | Separate: `loadedWritableAddresses` and `loadedReadonlyAddresses` |
| Counts against         | Your `Subscribe` allowance                  | The separate `SubscribeDeshred` allowance                         |

The two allowances are independent, so one key can hold `Subscribe` and `SubscribeDeshred` streams at the same time. A Blade Runner key may call `SubscribeDeshred` on a turbo hostname, even though it cannot use Turbo `Subscribe` there.

Turbo `Subscribe` keeps current Yellowstone code as it stands. `SubscribeDeshred` suits a new consumer, and is the only route on Blade Runner.

```ts title="subscribe-deshred.ts"
import Client, { type SubscribeUpdateDeshred } from "@triton-one/yellowstone-grpc";
import bs58 from "bs58";

const client = new Client("https://kaldera-newyork.constant-k.com", process.env.CK_API_KEY, undefined);
await client.connect();

const stream = await client.subscribeDeshred();
stream.write({
  deshredTransactions: {
    pumpAmm: {
      vote: false,
      accountInclude: ["pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"],
      accountExclude: [],
      accountRequired: [],
    },
  },
  slots: {},
});

stream.on("data", (update: SubscribeUpdateDeshred) => {
  const tx = update.deshredTransaction;
  if (!tx?.transaction) return;
  console.log(tx.slot, bs58.encode(tx.transaction.signature));
});
```
