RPC alternatives

Yellowstone gRPC vs parsed Solana streams: which do you need?

Yellowstone (Geyser) gRPC is a raw firehose of Solana updates you decode yourself; a parsed stream delivers ready-to-use launch, trade, and graduation events. How to choose.

8 min readAnton Gilborn

Quick answer

Serious Solana bots already stream - the real choice is the abstraction level. Yellowstone (Geyser) gRPC pushes raw account and transaction updates you decode, reconstruct, and enrich yourself. A purpose-built parsed stream pushes finished events - launches, trades, graduations, prices - ready to act on. Run the raw firehose only if you need arbitrary chain coverage; consume parsed events for everything else.

Isn't this just polling versus streaming?

No - and assuming it is where a lot of bad Solana advice starts. Polling an RPC on a timer (getProgramAccounts, getSignaturesForAddress) is not what fast bots do, and standard JSON-RPC WebSocket subscriptions like logsSubscribe are too limited and flaky to lean on in production. That is precisely why the ecosystem standardized on Yellowstone for real-time Solana data.

So streaming is table stakes. Everyone reacting to Solana in real time is already on a push stream. The question that actually decides your architecture is a different one: what does that stream hand you?

What is Yellowstone (Geyser) gRPC?

Yellowstone is the de facto standard Geyser plugin: it taps a Solana validator's Geyser interface and streams account writes, transactions, slots, and blocks over gRPC as they happen, filtered server-side by program, account, or owner. You do not have to run a validator to use it - Triton One (Dragon's Mouth), Helius (LaserStream), QuickNode, and other providers sell hosted Yellowstone endpoints.

Two properties define it. It is fast and complete - a high-throughput view of everything the chain does, which is why serious Solana infrastructure is built on it. And it is raw - the updates arrive as undecoded bytes keyed to programs and accounts, not as "a token launched" or "a $500 buy." Everything between those bytes and your strategy is your pipeline to build.

What does a raw Yellowstone gRPC stream give you?

Raw material. You subscribe to a program or set of accounts and receive account writes and transaction updates - but the contents are undecoded. Turning that firehose into something your strategy can act on is your job:

  • Decode it. Transaction instructions and account layouts arrive as bytes. You parse them against each venue's program format - pump.fun, PumpSwap, Raydium, Meteora, and the rest - to recover what happened.
  • Reconstruct events. A single logical event - a launch, a graduation, a buy - can span multiple instructions and inner instructions you have to stitch together.
  • Enrich it. The chain does not hand you "a $500 buy" or "a $48M market cap." You derive volumeUsd, marketCapUsd, and timeToGraduateSeconds yourself from raw amounts and prices.
  • Maintain it. When a program changes, your decoder changes with it. That is ongoing work, not a one-time integration.

And you pay for the whole firehose. gRPC is metered by data volume or bandwidth, mainnet endpoints are typically gated to the top tiers, and pump.fun plus PumpSwap is one of the busiest slices of the chain - so you ingest far more raw data than you end up using.

This is the right primitive if you need it. It is also a lot of undifferentiated infrastructure to own if all you wanted was launch, trade, and price events off a handful of venues.

What does a purpose-built parsed stream give you?

The same push model, one layer up. Instead of raw account and transaction updates, you subscribe to creations, graduations, trades, prices, or transfers and receive finished events as clean JSON - the decoding, reconstruction, and enrichment already done server-side. No Geyser plugin, no gRPC endpoint to provision, no program IDs, no decoder to maintain.

Here is the difference made concrete - one pump.fun buy, in full, as each stream delivers it. The first panel is the entire transaction update; scroll it.

Raw Yellowstone gRPC

One buy, as it arrives - 166 lines, no USD value anywhere in it

{
  "filters": ["pumpfun"],
  "createdAt": "2026-07-14T09:21:09.412Z",
  "transaction": {
    "slot": 309812501,
    "transaction": {
      "signature": "5xY8kR3nQmZ2vLdE9fWqT1sN4pC7hUoB6yA8jK2mVxRt3wDzS9pQeH4LcM7nJb1FgKtR5zXvY2mNc8h",
      "isVote": false,
      "transaction": {
        "signatures": [
          "5xY8kR3nQmZ2vLdE9fWqT1sN4pC7hUoB6yA8jK2mVxRt3wDzS9pQeH4LcM7nJb1FgKtR5zXvY2mNc8h"
        ],
        "message": {
          "header": {
            "numRequiredSignatures": 1,
            "numReadonlySignedAccounts": 0,
            "numReadonlyUnsignedAccounts": 9
          },
          "accountKeys": [
            "5FHwkW5742VKq9W8pN3mL7jR2sT6cX4bY1zD8gH9K2pQnM",
            "8psAVNbJbrHzSA1HfxFwjnKdKy1vB7qW3mD4tR9cU6eYx2v",
            "3M6iBQx9d4h8FLpNq2sT7wJcY6zR1nGtK5uA3oXvE2mBpS8d",
            "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
            "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
            "So11111111111111111111111111111111111111112",
            "7BvK3nF2HxR8mP5qW9tL4sY6jC1dA8eU3gN2fM5A1zXY",
            "6EF8rrecthR9DkzsubwGJLLbmXVAyDMHnhFHwkWnpump",
            "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
            "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",
            "11111111111111111111111111111111",
            "SysvarRent111111111111111111111111111111111",
            "Gf3sbc5Jb62jH7WcTr3WSNGDQ1kw6wcKMZXKK1SC1E6q",
            "ComputeBudget111111111111111111111111111111"
          ],
          "recentBlockhash": "9zXvY2mNc8hAeQ4WcS7pTzL4nJb9FgKtR5uA3oXvE2mB",
          "instructions": [
            {
              "programIdIndex": 13,
              "accounts": [],
              "data": "3QCwqmHZ4mdq"
            },
            {
              "programIdIndex": 13,
              "accounts": [],
              "data": "Fj2Eoy"
            },
            {
              "programIdIndex": 7,
              "accounts": [12, 6, 4, 2, 3, 1, 0, 10, 8, 11, 12, 7],
              "data": "AJTQ2h9DXrB4mvKq7zZmNTVaUxSM2v9Fb"
            }
          ],
          "addressTableLookups": []
        }
      },
      "meta": {
        "err": null,
        "fee": 5000,
        "preBalances": [
          1250005000, 2039280, 786541320944, 79422573066,
          1461600, 934087680, 118924369, 1141440,
          934087680, 731913600, 1, 1009200, 0, 1
        ],
        "postBalances": [
          0, 2039280, 787771320944, 79447573066,
          1461600, 934087680, 131424369, 1141440,
          934087680, 731913600, 1, 1009200, 0, 1
        ],
        "innerInstructions": [
          {
            "index": 2,
            "instructions": [
              {
                "programIdIndex": 10,
                "accounts": [0, 2],
                "data": "3Bxs4h24hBtQy9rw"
              },
              {
                "programIdIndex": 8,
                "accounts": [3, 1, 2],
                "data": "92rGDVYQzSSi"
              },
              {
                "programIdIndex": 10,
                "accounts": [0, 6],
                "data": "3Bxs4NNGKgUc7YxG"
              }
            ]
          }
        ],
        "logMessages": [
          "Program ComputeBudget111111111111111111111111111111 invoke [1]",
          "Program ComputeBudget111111111111111111111111111111 success",
          "Program ComputeBudget111111111111111111111111111111 invoke [1]",
          "Program ComputeBudget111111111111111111111111111111 success",
          "Program 6EF8rrecthR9DkzsubwGJLLbmXVAyDMHnhFHwkWnpump invoke [1]",
          "Program log: Instruction: Buy",
          "Program 11111111111111111111111111111111 invoke [2]",
          "Program 11111111111111111111111111111111 success",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
          "Program log: Instruction: Transfer",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
          "Program data: vdt/007mYe5B7dR2ZniXjzk4pTUxKys0dGVhbTRnZXQ2Rk1nS3paU2Zw",
          "Program 6EF8rrecthR9DkzsubwGJLLbmXVAyDMHnhFHwkWnpump consumed 32148 of 199700 compute units",
          "Program 6EF8rrecthR9DkzsubwGJLLbmXVAyDMHnhFHwkWnpump success"
        ],
        "preTokenBalances": [
          {
            "accountIndex": 1,
            "mint": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
            "uiTokenAmount": {
              "amount": "0",
              "decimals": 6,
              "uiAmount": null,
              "uiAmountString": "0"
            },
            "owner": "5FHwkW5742VKq9W8pN3mL7jR2sT6cX4bY1zD8gH9K2pQnM",
            "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
          },
          {
            "accountIndex": 3,
            "mint": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
            "uiTokenAmount": {
              "amount": "279348211000000",
              "decimals": 6,
              "uiAmount": 279348211,
              "uiAmountString": "279348211"
            },
            "owner": "3M6iBQx9d4h8FLpNq2sT7wJcY6zR1nGtK5uA3oXvE2mBpS8d",
            "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
          }
        ],
        "postTokenBalances": [
          {
            "accountIndex": 1,
            "mint": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
            "uiTokenAmount": {
              "amount": "842110000000",
              "decimals": 6,
              "uiAmount": 842110,
              "uiAmountString": "842110"
            },
            "owner": "5FHwkW5742VKq9W8pN3mL7jR2sT6cX4bY1zD8gH9K2pQnM",
            "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
          },
          {
            "accountIndex": 3,
            "mint": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
            "uiTokenAmount": {
              "amount": "278506101000000",
              "decimals": 6,
              "uiAmount": 278506101,
              "uiAmountString": "278506101"
            },
            "owner": "3M6iBQx9d4h8FLpNq2sT7wJcY6zR1nGtK5uA3oXvE2mBpS8d",
            "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
          }
        ],
        "rewards": [],
        "loadedWritableAddresses": [],
        "loadedReadonlyAddresses": [],
        "computeUnitsConsumed": 32448
      }
    }
  }
}

Parsed stream (Anaxer)

The same buy - 23 lines, ready to use

{
  "type": "swap",
  "source": "pump_fun",
  "wallet": "5FHwkW5742VKq9W8pN3mL7jR2sT6cX4bY1zD8gH9K2pQnM",
  "volumeUsd": 187.5,
  "swap": {
    "from": {
      "mint": "So11111111111111111111111111111111111111112",
      "amount": "1250000000",
      "uiAmount": 1.25,
      "decimals": 9
    },
    "to": {
      "mint": "EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm",
      "amount": "842110000000",
      "uiAmount": 842110,
      "decimals": 6
    }
  },
  "signature": "5xY8kR3…Nc8h",
  "slot": 309812501,
  "timestamp": 1751008869000
}
The same pump.fun buy at both abstraction levels (byte fields base58-encoded for readability). Which account is the pool? What did it cost in USD? With the raw update you answer that by decoding the instruction data, the inner instructions, and the base64 'Program data' log, then joining a price feed. On the parsed event it is already answered.

Concretely, the fields you would otherwise compute from a raw stream arrive on the event: a swap already carries volumeUsd, a price already carries marketCapUsd, a graduated already carries timeToGraduateSeconds. The integration is a subscription, not a pipeline:

const ws = new WebSocket("wss://api.anaxer.com/v1/stream?key=YOUR_KEY");

ws.onopen = () => ws.send(JSON.stringify({
  subscribe: "trades",
  filters: { sources: ["pump_fun"], minVolumeUsd: 500 }
}));

ws.onmessage = (msg) => {
  const event = JSON.parse(msg.data);
  // volumeUsd is already computed - no decoding, no price join
  console.log(event.volumeUsd, event.swap.to.mint);
};

The real question

It is not "poll or stream?" - both sides here stream. It is "do I want to run a decoding pipeline on a raw gRPC firehose, or consume the finished events?" Framed that way, most bots are choosing a data-abstraction level, not a faster node.

Yellowstone gRPC vs a parsed stream: side by side

Raw Yellowstone gRPCParsed stream (Anaxer)
What arrivesAccount writes + transaction updates, as bytesDecoded JSON events: created, graduated, swap, price, transfer
DecodingYou parse each venue's program layoutsDone server-side
Event reconstructionYou stitch instructions + inner instructionsDone server-side
EnrichmentYou compute USD volume, market capOn the event: volumeUsd, marketCapUsd, timeToGraduateSeconds
MaintenanceYour decoder breaks when programs changeProvider's job
CoverageAny program on SolanaMajor launchpads + DEXes, plus wallet transfers
BillingMetered by bandwidth; mainnet often gated to top tiersFlat monthly, stream volume unmetered
Best forIndexers, custom account monitoring, arbitrary programsBots, dashboards, and alerts on launch/trade/price events

Is raw gRPC faster than a parsed stream?

On the transport hop alone, a well-placed gRPC connection is hard to beat - and if you are doing co-located, shreds-level HFT, that hop is your world and this comparison is not for you. For everyone else, the number that matters is not gRPC-vs-WebSocket; it is confirmation to actionable event. Raw gRPC hands you bytes early, then you spend your own milliseconds (and engineering months) decoding, stitching, and enriching before your strategy can react. A parsed stream spends that budget server-side and delivers the finished event inside roughly 350 ms of on-chain confirmation - and since the creations and graduations streams are free, you can timestamp it against your own pipeline rather than take anyone's word for it.

When is raw Yellowstone gRPC the right choice?

Parsed streams do not replace gRPC - they sit on top of the same on-chain activity for a narrower job. Reach for raw Yellowstone/Geyser gRPC when you genuinely need it:

  • Arbitrary programs. You track protocols beyond the launchpads and DEXes Anaxer parses, or the whole chain, and need account-level coverage a curated event set does not provide.
  • Full control of parsing. You are building your own indexer or data product and want the raw stream as your source of truth.
  • Custom account monitoring. You need specific account writes, not domain-level events.

If that is you, Yellowstone is the correct primitive and worth the infrastructure. But if you need launches, trades, graduations, or prices from the venues a parsed provider already covers, decoding them yourself off a raw gRPC firehose is undifferentiated heavy lifting - the exact work a purpose-built stream exists to remove.

Where does Anaxer fit?

Anaxer is the parsed layer for real-time Solana DEX and launchpad data. You open one WebSocket, subscribe to a channel, and receive decoded events - launches, graduations, trades, prices, transfers - across the major venues (pump.fun and PumpSwap, Raydium, Meteora, Orca), with transfers covering wallet activity across Solana. Each event carries a slot for ordering and REST-based gap recovery. You are consuming events, not running a Geyser pipeline.

Because you are not ingesting and decoding a raw firehose, the pricing works differently too - flat, rather than metered by gRPC bandwidth. That flat-versus-metered gap is its own topic: the Anaxer vs Helius comparison works through it with current numbers, and the pricing page has the plans.

Want to see the events rather than read about them? The creations and graduations streams are on the free plan - subscribe and watch decoded events arrive, no card required. The streams reference covers the full protocol.

The bottom line

The question was never polling versus streaming, and it is not which node is fastest. Everyone serious is already streaming over Yellowstone gRPC. The decision that actually shapes your bot is the abstraction level: a raw gRPC firehose you decode, reconstruct, and enrich yourself, or a purpose-built stream that hands you finished events from Solana's major launchpads and DEXes. If you need arbitrary chain coverage, run the firehose. If you need launch, trade, price, or transfer events, consume them parsed.

Start with the Solana WebSocket streams guide for the protocol, or get a free key and subscribe to decoded events instead of building a decoder.

Frequently asked questions

What is Yellowstone gRPC?

Yellowstone is the standard Geyser plugin that streams Solana account writes, transactions, slots, and blocks over gRPC in real time, filtered server-side by program or account. Hosted endpoints are offered by Triton One (Dragon's Mouth), Helius (LaserStream), QuickNode, and others. It is the raw transport most serious Solana infrastructure builds on - fast and complete, but undecoded: turning the bytes into usable events is still your job.

Do I need Yellowstone gRPC for a Solana trading bot?

You need a real-time stream, and Yellowstone (Geyser) gRPC is the standard raw option - it pushes account and transaction updates you decode yourself. But you do not need to run or rent gRPC just to get parsed DEX and launchpad events. A purpose-built data stream delivers launches, trades, graduations, and prices - across venues like pump.fun, PumpSwap, Raydium, Meteora, and Orca - already decoded over a WebSocket, so you skip the Geyser plugin, the gRPC endpoint, and the decoding pipeline entirely.

What is the difference between Yellowstone gRPC and a parsed data stream?

Both are real-time push streams - the difference is abstraction. Yellowstone/Geyser gRPC gives you raw account writes and transaction updates filtered by program or account, which you then decode, reconstruct into logical events, and enrich (for example, computing USD volume or market cap). A parsed data stream does that work server-side and pushes finished events - created, graduated, swap, price - as clean JSON.

Is Yellowstone gRPC faster than a parsed WebSocket stream?

On the transport hop alone, a well-placed gRPC connection is hard to beat. But the number a bot lives on is confirmation-to-actionable-event, and raw gRPC hands you bytes - you add your own decode, reconstruction, and enrichment time before the event is usable. A parsed stream spends its latency budget server-side and delivers the finished event inside roughly 350 ms of on-chain confirmation. Unless you are doing co-located, shreds-level HFT, the pipeline you avoid matters more than the hop you optimize.

Why is a raw Solana gRPC firehose expensive to run?

Raw gRPC is metered by data volume or bandwidth and the mainnet endpoints are usually gated to the top provider tiers. A busy source like pump.fun and PumpSwap moves a large, continuous stream, so you pay to ingest far more raw data than you actually use, then spend engineering time decoding it. A parsed stream sends only the events you subscribed to, which is why it can be priced flat.

Are logsSubscribe and accountSubscribe enough for a production bot?

Usually not. Standard JSON-RPC WebSocket subscriptions are limited and unreliable under load, which is exactly why real-time Solana infrastructure converged on Yellowstone/Geyser gRPC. For a production bot you want either a robust gRPC firehose you decode, or a purpose-built parsed stream that sits above that layer and hands you finished events.

Last updated July 14, 2026.

Start streaming Solana data

Anaxer gives you real-time pump.fun and PumpSwap streams and REST APIs on a flat plan. The free tier needs no card.

Written by Anton Gilborn · Senior Platform Engineer, Anaxer

Anton is a senior platform engineer at Anaxer, where he builds the real-time streaming infrastructure behind its Solana data API - token launches, graduations, DEX trades, prices, and transfers. He writes about low-latency streaming architecture and building fast on-chain apps.

Keep reading