For the complete documentation index, see llms.txt. This page is also available as Markdown.

Preconfirmations gRPC

Triton Preconfs streams preconfirmed Solana transactions over gRPC, from the two block production systems that emit them: Harmonic and BAM.

What a preconfirmation is

On Solana one validator is the leader for each slot and builds the block for it. A transaction you send travels to that leader; the leader executes it, packs it into entries, splits the entries into shreds and broadcasts them; every other node receives the shreds, replays the block and only then reports the transaction, first at processed commitment, later at confirmed and finalized. Everything you can observe through an RPC node, a WebSocket or a Geyser stream sits at the end of that path.

A preconfirmation is a message emitted at the start of it. The party assembling the block, the builder or the leader itself, tells you the moment a transaction has been executed or committed into the slot under construction, before any shred exists. You learn what the block will contain while it is still being built. The message carries the raw transaction bytes exactly as the block will, plus the slot and, depending on the feed, the execution outcome and the position in the block.

A preconfirmation is a statement by the block producer, not a confirmation by the cluster. The slot can still be skipped, the block can land on a fork that is abandoned, and a builder can restart a slot. A preconfirmed transaction almost always lands, but "almost" is the operative word: act on it as the earliest possible signal, and treat confirmed and finalized as the settlement they are.

How each feed produces one

Harmonic runs block builders next to leaders that run the Harmonic validator client. Transactions reach the builder, which executes them and fixes their order for the block. As it does so it streams the executed transactions to subscribers in batches, numbered from zero within each slot and delivered in order, with a start and an end marker per slot. Each transaction carries the outcome the builder observed: success, execution failure (committed, fees charged, state reverted) or fees only (failed to load, only the fee is charged). The leader then executes the same transactions in the same order; Harmonic guarantees the resulting state is equivalent to executing them serially in batch order, so the outcome you receive is the outcome that lands. A Harmonic preconfirmation therefore means: this transaction was executed with this result and sits in the block being built.

BAM, Jito's Block Assembly Marketplace, sits between transaction senders and leaders that run the BAM validator client. A BAM node schedules the transactions it receives, first in first out with respect to the accounts they lock, and hands them to the leader; the leader executes them and acknowledges each one back to the node, which streams it to subscribers. Each transaction carries the node it came through, its position in the scheduler's sequence (transactions sharing a sequence were bundled together), its position inside that bundle, and whether the bundle reverts on error. BAM does not report an execution outcome: a BAM preconfirmation means this transaction was committed by the leader into the slot; whether it succeeded is only visible once the block lands.

Triton subscribes to both systems in every region they publish from and delivers the same bytes to you over one endpoint, filtered to the accounts, signers, instructions and signatures you ask for.

Harmonic and BAM side by side

Harmonic
BAM

who produces the preconf

the block builder, before the leader executes

the BAM node, after the leader executes and acknowledges

what it asserts

executed with this outcome, in the block being built

committed by the leader into the slot

execution outcome

success, execution failure, fees only

not reported

ordering information

batch number within the slot

scheduler sequence, bundle position, revert on error

slot framing

SlotStart and SlotEnd per slot

none, each transaction names its slot

regions

7

15

What the feeds cover, and what they do not

The questions we get most often come from expecting the feeds to be a copy of the chain. They are not. Three things decide what a stream carries.

Only slots led by a validator running that client. Harmonic preconfirms the slots of leaders on the Harmonic client; BAM preconfirms the slots of leaders on the BAM client. A slot led by any other validator has no preconfirmation on either feed, from any region. The share of slots each feed covers follows the stake running its client and changes as validators switch. Neither feed sees the other's slots, so subscribing to both is how you cover the most slots.

Static account keys only. Filters match the accounts written in the transaction message. Accounts a v0 transaction reaches through an address lookup table are not matched; legacy and v1 transactions carry every account inline and are matched in full. This is the single most common reason a filter sees fewer transactions than expected; see Address lookup tables below.

One region, one stream, and only the regions near you. Each regional stream carries the slots of the leaders that region serves, not a copy of the whole feed. A far region's preconfirmations arrive after the people located there have acted on them. See Choosing regions.

Endpoint and access

https://preconfs.rpcpool.com

The address is anycast: the connection lands on the closest point of presence, one of the servers behind that address; every point of presence serves every region of both feeds.

Token

Every request, GetVersion included, carries an x-token: the token of a subscription that has Harmonic preconfs, BAM preconfs or both enabled. It is the same token you use for other Triton gRPC services on that subscription. Send the token's value, not its name.

Enabling a feed on a subscription reaches the servers within about a minute. Until then, and for a token whose subscription does not have that feed, subscribing is refused with UNAUTHENTICATED and the message x-token not entitled to this feed. Turning a feed off closes the open streams of that token with PERMISSION_DENIED.

Which point of presence answered

GetVersion returns the server version and the point of presence that took your connection, and needs the token like every other call:

The same call is Client::version() in the Rust client.

Client

The Rust client and the protobuf definitions are on GitHub as the triton-preconfs-client and triton-preconfs-proto crates. Other languages use the proto directly, see Other languages.

Quick start

Add the client:

Subscribe to Harmonic in Amsterdam for transactions touching the SPL token program and print what arrives:

The same shape works for BAM with Feed::Bam and subscribe_bam.

The example CLI

The repository ships preconfs-subscribe, which subscribes and logs every event:

--region bam:fra, --require, --exclude, --signer, --exclude-signer, --instruction, --data-size, --signature, --result and --no-reconnect cover the other options; --help lists them. Every transaction invoking Meteora DBC create_config, from any creator:

Trying it with grpcurl

With preconfs.proto from the repository in the current directory:

For BAM call preconfs.BAM/Subscribe with "bam_region":"BAM_REGION_FRA".

Feeds and regions

Three things carry the word region; they are not the same thing.

Feed regions are the ones in the proto (HarmonicRegion, BamRegion) and in the subscribe request. Harmonic runs a block builder in each of its regions and BAM runs a node in each of its; a leader is served by one of them, and that location's stream carries the slots of the leaders it serves. The regional streams are not copies of each other: harmonic:ams and harmonic:fra deliver different slots. Subscribe to the ones near your servers; see Choosing regions.

Origin on each transaction: region on a Harmonic transaction and node on a BAM transaction name the builder or node it came through. On a single region stream it matches what you subscribed; it is there so transactions stay self describing when you merge streams.

Points of presence are Triton's servers, named after their site (ams1, fra1, lon1, nyc1 and so on). The anycast address lands you on the closest one and every point of presence relays every feed region, so where you connect never limits what you can subscribe to. Client::version returns the one that answered in its region field.

A stream serves one feed in one region. A region of the other feed is refused.

Harmonic

The builder executes the transaction and reports the outcome. Streams are framed per slot (see The stream) and carry an execution result on every transaction, so execution_results filters are accepted.

region
location

ams

Amsterdam

ewr

New York (Newark)

fra

Frankfurt

lon

London

tyo

Tokyo

sgp

Singapore

slc

Salt Lake City

BAM

The leader commits the transaction; no outcome is reported and there is no slot framing. Each transaction names its slot.

region
location

ams

Amsterdam

dfw

Dallas

dub

Dublin

ewr

New York (Newark)

fra

Frankfurt

hkg

Hong Kong

iad

Washington (Ashburn)

lax

Los Angeles

lon

London

pit

Pittsburgh

sea

Seattle

sin

Singapore

slc

Salt Lake City

sqq

Siauliai

tyo

Tokyo

Choosing regions

Pick the regions near you. Do not subscribe to all of them.

A preconfirmation is worth what its lead over the landed block is worth, and that lead is spent on the wire. Cables do not run in straight lines: a packet from Tokyo to Frankfurt takes around 250 ms on a normal route. A slot preconfirmed in Tokyo therefore reaches a server in Frankfurt a quarter of a second after it reached a server in Tokyo. By then a trader sitting in Tokyo has acted on it, and the block itself has long been broadcast. For a far region you pay for the stream and still come second every time. This is not a limit we impose; it is geography, and it is the reason the feeds publish per region in the first place.

So: subscribe to the regions whose builders and nodes sit in your own data centre or metro, one stream per region. Someone in Frankfurt subscribes to harmonic:fra and bam:fra, maybe ams and lon next to them; someone in New York to ewr, maybe iad and pit. Regions elsewhere only make sense for a server placed there. The streams of the regions you pick share one connection.

If you do open several, merge them. Each stream carries different slots, so there is nothing to deduplicate between regions of the same feed, and framing is per stream: a SlotEnd on ams says nothing about fra. In Rust, select_all polls whichever region has an event ready:

futures = "0.3" provides select_all. The same shape with Feed::Bam and subscribe_bam covers the BAM regions near you; the two feeds have different event types, so merge them separately or map both into your own type first. Each stream reconnects on its own, so a point of presence restart shows up as one Reconnected per region.

Two more things to know when you open several streams:

  • They all draw on your account's coverage share (see Coverage). A wide filter across many regions reaches the share quickly; the share is meant for filters that select what you actually use.

  • The concurrent stream limit is 1000 per account, far above what any placement needs.

In the client

To pin one point of presence instead of letting anycast choose, Connector::dial("host:port") opens the TCP connection to that address while TLS keeps the endpoint's host name. Client::version returns the server version and the region of the point of presence answering.

Filters

A subscribe request carries one or more named filters. A transaction is delivered when it matches at least one, and every delivered transaction names the filters it matched.

A transaction matches a filter when it satisfies every condition the filter sets:

condition
matches when the transaction

account_include

references any of these accounts

account_required

references all of these accounts

account_exclude

references none of these accounts

signer_include

is signed by any of these accounts

signer_exclude

is signed by none of these accounts

instructions

has a top-level instruction passing any of these instruction filters

signatures

has one of these first signatures

execution_results

landed with one of these outcomes, Harmonic only

Every filter must select something with account_include, account_required, signer_include, instructions or signatures; the full feed cannot be subscribed. account_exclude, signer_exclude and execution_results only narrow a selection, so a filter made of them alone is refused.

"References" means the account is a static account key of the transaction message. Accounts loaded through address lookup tables do not count, for includes and for excludes alike, see What the feeds cover.

Excluding accounts

account_exclude drops a transaction that references any of the listed accounts, after the rest of the filter matched. It is the "give me A, skip anything that also touches B" filter from Yellowstone gRPC and LaserStream: follow a pool without the bot that trades it all day, or a program without a spam account.

An account a v0 transaction loads through a lookup table is not seen by the exclusion either, so a spammer reaching the account that way still gets through.

Signers

The signers of a transaction are the first num_required_signatures static account keys of its message: the fee payer first, then every other account that signed, cosigners included. signer_include matches a transaction signed by any of the listed accounts and signer_exclude drops one signed by any of them. An account that is only referenced, for example the recipient of a transfer, is not a signer and does not match.

Instructions

An instruction filter names a program and, optionally, conditions on the instruction's data, the same shape as the getProgramAccounts filters applied to instruction data:

  • program_id: the program the instruction invokes, required

  • memcmp: bytes the data must hold at an offset, up to four, all must hold

  • data_size: the exact length of the data

A transaction matches when one of its top-level instructions passes every condition of any of the listed instruction filters. Only top-level instructions exist before execution: an instruction a program invokes through CPI is not part of the transaction bytes and is not seen. Data shorter than a memcmp's end does not match.

Anchor programs start the data with an 8 byte discriminator, the first 8 bytes of sha256("global:<instruction name>"). Every Meteora Dynamic Bonding Curve create_config, from any creator and without the swaps on the same program:

Native programs start with a one byte tag and data_size pins the layout. SPL Token TransferChecked is tag 12, an 8 byte amount and a 1 byte decimals:

InstructionFilter::new(program) with no conditions matches transactions that invoke the program. account_include with the program id also matches transactions that only pass it as an account.

Limits

limit
value

filters per stream

64

accounts per account or signer list

10000

signatures per filter

1000

filter name

64 bytes

instruction filters per stream, over all filters

16

memcmps per instruction filter

4

bytes per memcmp

1 to 128

memcmp end and data_size

within 4096 bytes

concurrent streams per account

1000

The client checks every limit but the last before sending, so a request over a limit fails locally with a FilterError. A memcmp that ends past its own data_size could never match and is refused the same way.

In the client

Filters::single(filter) names a lone filter default. The client README has more recipes.

Address lookup tables

Solana has three transaction message formats, and only one of them hides accounts:

format
accounts
lookup tables

legacy

every account written in the message

no

v0

static accounts in the message, plus indexes into on-chain address lookup tables

yes

v1 (SIMD-0385, the 4 KB format)

every account written in the message, up to 64

no

For legacy and v1 transactions the bytes name every account, so a filter sees all of them. The gap is v0: its bytes carry only the table address and an index for each looked-up account, and turning those into addresses means reading the table's current state on chain.

Preconfirmations are the raw transaction bytes, emitted before the block exists. Neither Harmonic nor BAM resolves v0 lookup tables before streaming, and Triton does not resolve them on the way through: it would mean an account lookup per transaction on the hot path, and the whole point of the feed is the milliseconds it is ahead. So for v0 transactions, filters match the static keys only. The client parses all three formats; parse::parse_static_parts returns exactly the keys a filter sees.

What this means in practice:

  • Program ids and well known accounts are almost always static keys, in every format. A filter on the SPL token program, a DEX program or pump.fun matches every transaction that invokes it.

  • Pools, positions, vaults and user token accounts in v0 transactions are often loaded through tables, especially from aggregators and bots. A filter on such an account misses the v0 transactions that reach it through a table. Legacy and v1 transactions touching the same account match normally.

  • The same v0 transaction, seen through Geyser or Deshred after the block lands, has its tables resolved. That is why a side by side comparison of "transactions touching account X" shows more on the landed stream than on the preconf stream.

If your accounts are mostly behind tables, filter on the program and on the static accounts that always accompany your transactions, and select the rest on your side. Both feed operators have said they intend to add resolution upstream, where it costs no latency; when they do, filters will match resolved accounts without any change on your side. As v1 adoption grows the gap closes on its own, since v1 has no tables.

The stream

subscribe_harmonic and subscribe_bam return a stream of Events.

event
meaning

SlotStart { slot }

a leader began streaming preconfs for this slot (Harmonic)

Transaction(matched)

a matching transaction; matched.filters names the filters, matched.transaction is the feed's message with the raw bytes

SlotEnd { slot }

no further transactions for this slot will arrive (Harmonic)

Clip { transactions }

matching transactions were withheld, see Coverage

Reconnected { attempts }

the stream dropped and was resubscribed; the data produced in between is gone

Pings are consumed by the stream.

Slot framing

On Harmonic every transaction sits between its slot's SlotStart and SlotEnd. After SlotEnd for a slot you hold everything your filters matched for it. A stream that subscribes while a slot is open joins at the next SlotStart, so the first slot you see is always complete. Slot boundaries arrive whether or not your filters matched anything in that slot.

Rarely a leader restarts a slot: a second SlotStart for a slot that already ended, followed by its definitive transactions and a new SlotEnd. Rebuild your view of that slot from the new frame; the last SlotEnd wins.

BAM has no framing. Each transaction names its slot.

Transaction bytes

matched.transaction.transaction holds the raw transaction bytes. The client parses what filtering needs without a full decode:

Legacy, v0 and v1 message formats are supported.

Transaction fields

Harmonic (HarmonicTransaction):

field
meaning

transaction

raw transaction bytes

slot

slot the transaction was preconfirmed in

result

the builder's outcome: success, execution failure or fees only

region

Harmonic region it was received from

seq

preconf batch within the slot, numbered from 0 and delivered in order

BAM (BamTransaction):

field
meaning

transaction

raw transaction bytes

slot

slot the transaction was preconfirmed in

node

BAM node it was received from

sequence

scheduler order on that node; transactions sharing a sequence were bundled together

bundle_position

execution order within that bundle

is_revert_on_error

the bundle reverts on error (bundle intent, not an outcome)

Slow consumers

A stream that cannot keep up ends with an explicit RESOURCE_EXHAUSTED status. Nothing is ever thinned silently: if you hold the stream open, it is complete for your filters, minus what Clip announces.

Coverage

Each account may receive up to a share of a feed's traffic. This is a condition of the feeds: Harmonic and BAM license preconfirmations for your own use, and the share is what makes the full firehose impossible to obtain or resell through Triton. It is not a rate limit on the server; a narrow filter never hits it.

How it is measured:

  • The share is 33% of what a feed publishes in the region you subscribe, counted over a sliding 60 second window. Harmonic and BAM are counted separately. The percentage is agreed with the feed operators and can change; this page states the current value.

  • It belongs to the account and the region: every token, connection and stream of your subscription on one region draws on that region's share. Opening more streams on a region or rotating filters does not widen it, and each region you subscribe has a share of its own, so streams on ams and fra do not eat into each other.

  • A burst cap holds instantaneous delivery to half the feed's current rate, so a spike cannot take the whole window's share in a second.

  • Each point of presence measures on its own.

What happens over the share:

  1. Matching transactions are withheld. The count arrives as a Clip event at most once a second, and on Harmonic always before the affected slot's SlotEnd, so a completed slot is never silently short.

  2. If the account stays over the share for 30 seconds without recovering, the stream ends with RESOURCE_EXHAUSTED and the message account exceeded its coverage limit, cooling off.

  3. Subscribing again to that region is refused for 60 seconds, with the remaining time in the error message. The client's reconnect waits and retries on its own. Your other regions are not affected.

Staying under it: subscribe to what you act on rather than to whole programs. A filter on the SPL token program or pump.fun asks for most of the chain and reaches the share within a minute; the same program narrowed to one instruction with instructions, to your pools or wallets with account_required or signer_include, or with the spam removed by account_exclude, does not. If your use needs a larger share, ask through support; the share can be set per account.

Billing

Two quantities are counted per subscription and per feed:

quantity
counts

messages

transactions delivered on your streams

slots

slots your streams were open for, on Harmonic, whether or not a transaction matched your filters

Harmonic is priced at the greater of a per slot and a per message amount, so the slot count is a floor: a stream open on a Harmonic region pays for every slot that region produces while it is open, matched or empty. BAM is priced per message only.

Not counted as messages: SlotStart, SlotEnd, pings, Clip notices, transactions your filters did not match, and transactions withheld by coverage.

Streams add up. Two streams whose filters overlap receive, and are counted for, the same transactions twice, and two streams on the same Harmonic region are two streams open on those slots. A transaction matching several filters on one stream is delivered and counted once; reconnecting within a slot does not count the slot again on the same point of presence.

Prices per message and per slot for each feed are on your subscription in the customer panel, together with the daily usage.

Errors and reconnect

Error types

type
from
when

ConnectError

Connector::connect, connect_lazy

bad endpoint URI, token not ascii, TLS setup, connection refused or timed out

SubscribeError

subscribe_harmonic, subscribe_bam

region of the wrong feed, filters over a limit, or the server refused the subscribe (bad token, region not served, feed not entitled, cooling off)

StreamError

a stream item

the server ended the stream with a status, or closed it

RegionError, FilterError and ParseError are the smaller types behind them. For one top level type wrap them with anyhow or Box<dyn Error>.

Status codes

status
meaning
what to do

UNAUTHENTICATED

no x-token, unknown token, or the subscription does not have this feed enabled

check the token value and that the feed is enabled

PERMISSION_DENIED

the feed was disabled on the subscription while the stream was open

the stream is closed; re-enable the feed

INVALID_ARGUMENT

region missing, unspecified or of the other feed; a filter over a limit or with no selector

fix the request

FAILED_PRECONDITION

the region is not served by this deployment

use one of the regions listed above

RESOURCE_EXHAUSTED

over the coverage share for 30 seconds, still cooling off, or the client cannot keep up

narrow the filters, read faster, retry after the cooloff

DATA_LOSS

the client fell so far behind that the server dropped its position

reconnect; the gap is gone

UNAVAILABLE

the point of presence is restarting

reconnect; anycast lands on another

Reconnect

Points of presence restart on every deploy, so a long lived stream will drop. By default the stream resubscribes with the same request after a backoff and yields Event::Reconnected. Preconfs produced in between are gone; on Harmonic, framing restarts at the next SlotStart.

Errors that retrying cannot fix end the stream instead: Unauthenticated, PermissionDenied, InvalidArgument, FailedPrecondition, NotFound, Unimplemented. Unavailable, DataLoss, ResourceExhausted, Internal, Aborted, DeadlineExceeded and a closed stream are retried.

The default schedule waits 100ms, then doubles up to 10s between attempts, and never gives up. Tune or disable it on the connector:

With reconnect off the stream yields the error and ends.

Other languages

The wire contract is preconfs.proto in the repository (preconfs-proto/proto/preconfs.proto); the same file is exported by the Rust proto crate as PROTO_SOURCE. Generate a client for your language from it.

Calls

service
rpc

preconfs.Harmonic

Subscribe(SubscribeRequest) returns (stream HarmonicUpdate)

the Harmonic stream

preconfs.Harmonic

GetVersion(VersionRequest) returns (VersionResponse)

server version and point of presence region; needs the token

preconfs.BAM

Subscribe(SubscribeRequest) returns (stream BamUpdate)

the BAM stream

preconfs.BAM

GetVersion(VersionRequest) returns (VersionResponse)

grpc.health.v1.Health

Check

standard health service

Authentication

Send the token as gRPC metadata on every call, GetVersion included: key x-token, value the token. A token that is not entitled to at least one feed is refused with UNAUTHENTICATED.

Request

SubscribeRequest has two fields:

  • transactions: a map from filter name to TransactionFilter: account_include, account_required, account_exclude, signer_include, signer_exclude, signature and execution_results, accounts and signatures as base58 strings, and instructions, each an InstructionFilter with program_id (base58), memcmp (offset and bytes) and an optional data_size.

  • region: exactly one of harmonic_region or bam_region, matching the service called. Unspecified or the other feed's region is INVALID_ARGUMENT; a region the server does not serve is FAILED_PRECONDITION.

The limits in Filters apply; a request over them is INVALID_ARGUMENT. In the JSON form grpcurl uses, bytes is base64. Every Meteora DBC create_config on BAM Frankfurt:

Updates

HarmonicUpdate and BamUpdate carry filters (the names that matched, empty for slot boundaries and pings) and one payload: transaction, ping, clip, and on Harmonic slot_start and slot_end. The contract in The stream holds as described; pings arrive on quiet streams and can be ignored.

Transactions carry the raw bytes in transaction, in the wire format of their message version. Legacy and v0 transactions start with a compact-u16 signature count and the signatures; v1 transactions carry the message first and the signatures after it. Decode them with a Solana SDK that knows all three rather than reading fixed offsets.

Questions we get asked

I filter on my accounts and see far fewer transactions than Geyser shows for the same accounts. Two causes, in this order. Accounts a v0 transaction reaches through address lookup tables are not matched, only static keys are; see Address lookup tables. And only slots led by validators on the Harmonic or BAM client exist on the feeds; other leaders' slots have no preconfirmation anywhere. See What the feeds cover.

Can I get the whole feed? No. Every filter must select something, by accounts, signers, instructions or signatures, and the coverage share caps what one account receives. This is the condition under which the feeds are offered.

Why was my stream closed with "cooling off" within a minute? Wide filters, usually a whole program, took more than the share of that region's feed. Narrow them with account_required, signer_include, an instruction filter or account_exclude, and resubscribe after the cooloff. See Coverage.

Does the coverage share apply per region? Yes. Each region you subscribe has its own share, measured against what the feed publishes there, and all your streams on that region share it. Subscribing to four nearby regions gives four shares, not one split four ways.

How do I use the signature filter if signatures are only known once I send? It is for following transactions you already know: the ones you just sent, or a list you track. A stream's filters are fixed for its lifetime, so to follow new signatures open a stream with the new list and close the old one; streams on one connection are cheap. To see everything a wallet sends without knowing the signatures in advance, filter on the wallet with signer_include instead.

Is there an account_exclude like other providers have? Yes, as a further condition on a filter that selects something: include A, minus B. It does not allow the whole feed except some accounts. See Excluding accounts.

Can I filter on an instruction instead of accounts? Yes, on the top-level instructions: the program, bytes at offsets of the data and its exact size, which is enough to select one instruction by its discriminator. Instructions invoked through CPI only exist after execution and are not seen. See Instructions.

Can I get only the transactions my wallet signed, not every one that mentions it? Yes, with signer_include. See Signers.

Should I subscribe to all regions? No. A preconfirmation from a far region reaches you after the people located there have acted on it, so it is paid for and always late. Subscribe to the regions next to your servers, one stream each, and place servers where you need other regions. See Choosing regions.

Which point of presence am I on? GetVersion returns it. Anycast picks the closest; Connector::dial pins one.

Am I billed for slots with no matching transactions? On Harmonic yes: the slot fee is a floor for every slot your stream is open on. Pings and slot markers are not messages. See Billing.

Does the execution_results filter cost anything? No. Transactions it filters out are never delivered and never counted.

Does a BAM subscription elsewhere give me BAM preconfs here? No. Access is per Triton subscription; the feed is enabled on your subscription and used with your Triton token.

Where exactly are the builders and nodes? In the cities listed under Feeds and regions. The data centre is the feed operator's; Triton's points of presence sit close to them, and the region you subscribe is what decides the slots you get, not where you connect.

Last updated

Was this helpful?