Turbo Kaldera (aRPC)

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

Turbo Kaldera delivers decoded pre-execution transactions over the same Yellowstone protocol as 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 sets out all six stages and the stage each product delivers at.

Endpoints

RegionEndpoint
New Yorkhttps://turbo-kaldera-newyork.constant-k.com (port 443)
Frankfurthttps://turbo-kaldera-frankfurt.constant-k.com (port 443)
Amsterdamhttps://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 RunnerNexus
Turbo Subscribe on the turbo hostnamesNoYes
SubscribeDeshred on any Kaldera hostnameYesYes
SubscribeDeshred streams1525
SubscribeDeshred bandwidth22.5 MB/s75 MB/s

Turbo streams are Subscribe streams. They come out of the same stream and bandwidth allowance as your standard Kaldera 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 has the published table.

Client setup

An existing Yellowstone client needs only the turbo hostname. In Rust, the Kaldera quickstart example changes by its endpoint alone.

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.

PresentAbsent
SignatureThe whole meta object
The transaction message: account keys, instructions, recent blockhashFee, success or error status, logs
Lookup table references, and the addresses they resolve toPre and post balances, token balance changes
SlotCompute 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 or Solana 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.

FieldOn Turbo
accountInclude, accountExclude, accountRequiredHonoured. They match the account keys in the message, lookup table addresses included.
voteHonoured. vote: false applies as on standard Kaldera.
failedBest left unset. false is accepted and changes nothing. true is rejected: nobody knows yet whether the transaction will fail.
signatureRejected.
cuckooAccountIncludeRejected. The SubscribeDeshred filter defines no compressed-filter field, so there is nothing to carry the set.

A subscription carrying a compressed account filter is refused rather than served without it, since serving it would mean dropping the constraint and streaming every transaction. Standard Kaldera accepts that filter on the kaldera-<region> hostname.

The rest of the request is either rejected or ignored.

In the requestWhat happens
accounts, blocks, blocksMeta, entry, transactionsStatusRejected with INVALID_ARGUMENT (3)
fromSlotRejected with INVALID_ARGUMENT (3). Turbo has no replay.
slotsAccepted 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 SubscribeSubscribeDeshred
PlansNexusBlade Runner and Nexus
HostnamesThe turbo hostnames aboveEvery Kaldera hostname, turbo and standard
RequestSubscribeRequest, as on standard KalderaSubscribeDeshredRequest: deshredTransactions and slots
UpdateSubscribeUpdate, meta absent, index 0SubscribeUpdateDeshred
Lookup table addressesMerged into message.accountKeysSeparate: loadedWritableAddresses and loadedReadonlyAddresses
Counts againstYour Subscribe allowanceThe 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.

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));
});

On this page