Anchor Discriminator
Account model
An Anchor discriminator is the first eight bytes Anchor adds in front of every instruction payload and every account's data. It is a SHA-256 of a fixed string (for example "global:swap" for an instruction or "account:Whirlpool" for an account), truncated to 8 bytes. The program reads it, looks up the handler, and dispatches.
Detailed explanation
Solana programs are raw byte handlers. When a transaction sends instruction data, the program has to figure out which internal handler to call. Anchor solved this by hashing a namespaced string and using the first 8 bytes as a routing key. For instructions the namespace is "global", so the discriminator for a swap is sha256("global:swap")[0..8]. For accounts the namespace is "account", so a Whirlpool account starts with sha256("account:Whirlpool")[0..8].
This matters for off-chain decoding. To filter Geyser writes for a specific account type, you compare the first 8 bytes. To classify an instruction without parsing every program's arguments, you read the discriminator and look it up in a table. Most parsed-stream pipelines run a discriminator table per program before they touch the rest of the bytes.
Caveats: the same hash function applies to events too, so Anchor event payloads emitted via emit! also start with an 8- byte discriminator. Programs that are not built with Anchor do not use this convention, which is why a generic Solana decoder needs both Anchor and non-Anchor paths.
One opinion: a discriminator collision in 64 bits of hash space is theoretical, but a collision between two different programs is real if you forget to namespace by program ID in your decoder map. Always key by (program_id, discriminator).
When you'll see this
Every Anchor program emits discriminators on every instruction and every account. Examples in production: Whirlpools, Raydium CLMM, Drift v2, and most major DeFi programs. If you grep an account dump and see a stable 8-byte prefix shared across many accounts, that is the discriminator.
How NoLimitNodes uses this
Our Enhanced Streams dispatch on (program_id, discriminator) before they decode any field, which is how we keep latency consistent even when a program emits dozens of event types. The full table of decoded events lives on our Program Streams catalogue.
Related terms
- IDL · An Anchor Interface Definition Language file. JSON describing a program’s instructions, accounts, and event layouts.
- Program Derived Address · A PDA. An off-curve address derived from seeds plus a program ID, signable only by the program that owns it.
- Geyser Plugin · A shared library a Solana validator loads to push account, slot, and transaction updates into your own pipeline.
- Yellowstone gRPC · The Triton-built Geyser plugin that exposes a gRPC stream of accounts, transactions, and slots over the wire.
- Whirlpool · The Orca CLMM pool account that stores the active sqrt-price, current liquidity, fee tier, and tick spacing.