Skip to main content

Solana Pool Price

What it is​

Every Solana DEX pool event carries the pool's own price after the event. It is the price the pool quotes for the next tiny trade, read from the venue's own state. It is not the price the swap that produced the row paid; the two differ by that swap's price impact and fee.

It also differs from the Crypto Price API. That price blends recent trades across all of a token's pools. A pool price belongs to one pool and changes on every swap or liquidity change in it.

How to get it​

DeliveryWhere
GraphQLSolana { DEXPools { Pool { Price { Price PriceInUSD Source } } } } on https://streaming.bitquery.io/graphql, in queries and subscriptions. Filterable, orderable (Pool_Price_Price, Pool_Price_PriceInUSD) and aggregatable
Kafkasolana.dextrades.proto, PoolEvents[].Price (PoolPrice message, field 7, streaming_protobuf v2.6.6). See Solana protobuf

Prices exist from 2026-10-23. DEXPools is served from the realtime dataset, so GraphQL history covers the last few hours.

How it is derived​

A pool event gives a sqrt price, curve reserves or vault balances; each becomes quote per base with decimals applied, then the pool price

Every venue reduces to one ratio: raw quote units per raw base unit after the event, r. Decimals are then applied so the price reads in whole tokens:

Price = r × 10^(base decimals − quote decimals)
PriceInUSD = Price × USD rate of the quote token at that block

Base and quote are the row's Market.BaseCurrency and Market.QuoteCurrency. Where the venue stores the price the other way round, r is inverted.

Concentrated pools: from the sqrt price​

Raydium CLMM, PancakeSwap CLMM, Orca Whirlpool, Meteora DAMM v2 and Meteora DBC report the pool's square-root price after the swap in their swap event, as a Q64.64 number.

r = (sqrtPriceX64 / 2^64)^2 token1 per token0, inverted when the base is token1

The event fields are sqrt_price_x64 on Raydium and PancakeSwap CLMM SwapEvent, post_sqrt_price on Whirlpool Traded, and the post-swap sqrt price on Meteora EvtSwap / EvtSwap2. Source is event.

Bonding curves: from virtual reserves​

VenuerEvent
pump.funvirtual_sol_reserves / virtual_token_reservesTradeEvent
Raydium Launchpad(virtual_quote + real_quote_after) / (virtual_base − real_base_after)TradeEvent

Source is event.

Constant-product pools: from vault balances​

r = quote vault balance / base vault balance after the event

PumpSwap and Raydium v4 use the vault balances on the row (Source: reserves). Raydium CPMM takes them from its swap event, as the balances before the swap plus the amount in and minus the amount out (Source: event). Its fee-collection rows fall back to the vault balances (Source: reserves).

We checked each formula on 2026-10-26 against the raw event data of live rows on every venue above. Price matched to within 0.002 %.

Rows without a price​

  • pump.fun curves in mayhem mode. The program does not trade them at their reported reserves, so every row of such a curve is unpriced. This was about a fifth of active curves when we checked.
  • pump.fun migrations, where the curve is emptied. The new PumpSwap pool's creation row has the price.
  • Fee claims and collections, Raydium CLMM limit-order instructions, and the liquidity changes of Whirlpool and DAMM v2. These do not move a concentrated pool's price, so keep the pool's last priced row.
  • Meteora DLMM, Meteora Pools (DAMM v1), and venues whose rows come only from vault balances (BisonFi, Manifest, GoonFi, Byreal, AlphaQ, Aquifer, SolFi, Bonkswap and others).

Fields​

FieldTypeMeaning
Pool.Price.PriceFloatQuote per base in whole tokens, oriented as Market.BaseCurrency / Market.QuoteCurrency
Pool.Price.PriceInUSDFloatPrice × the quote token's USD rate at that block. 0 when the quote has no rate
Pool.Price.SourceStringevent (read from the venue's event) or reserves (vault balances). Empty when the row has no price

A row without a price has 0, 0 and "" in GraphQL and a nil Price in protobuf. Treat an empty Source as "no price", never as a price of zero.

Examples​

Latest price of a pool​

Run query

Click to expand GraphQL query
query SolanaPoolLatestPrice {
Solana {
DEXPools(
limit: { count: 1 }
orderBy: { descending: Block_Slot }
where: {
Pool: {
Market: {
MarketAddress: { is: "2AXXcN6oN9bBT5owwmTH53C7QHUXvhLeu718Kqt8rvY2" }
}
Price: { Source: { not: "" } }
}
}
) {
Block {
Slot
Time
}
Pool {
Market {
MarketAddress
BaseCurrency {
Symbol
}
QuoteCurrency {
Symbol
}
}
Dex {
ProtocolName
ProtocolFamily
}
Price {
Price
PriceInUSD
Source
}
Base {
PostAmountInUSD
}
Quote {
PostAmountInUSD
}
}
}
}
}

Live pool prices of a token​

Every pool where WSOL is the base, as each pool event lands. Quote.PostAmountInUSD shows the liquidity behind each price.

Run query

Click to expand GraphQL query
subscription SolanaPoolPricesOfToken {
Solana {
DEXPools(
where: {
Pool: {
Market: {
BaseCurrency: {
MintAddress: { is: "So11111111111111111111111111111111111111112" }
}
}
Price: { Source: { not: "" } }
}
Transaction: { Result: { Success: true } }
}
) {
Block {
Slot
Time
}
PoolEvent {
Index
}
Pool {
Market {
MarketAddress
QuoteCurrency {
Symbol
}
}
Dex {
ProtocolName
}
Price {
Price
PriceInUSD
Source
}
Quote {
PostAmountInUSD
}
}
}
}
}

Price history of a pool over the last hour​

Run query

Click to expand GraphQL query
query SolanaPoolPriceHistory {
Solana {
DEXPools(
orderBy: { ascending: Block_Slot }
where: {
Block: { Time: { since_relative: { hours_ago: 1 } } }
Pool: {
Market: {
MarketAddress: { is: "2AXXcN6oN9bBT5owwmTH53C7QHUXvhLeu718Kqt8rvY2" }
}
Price: { Source: { not: "" } }
}
}
) {
Block {
Slot
Time
}
Pool {
Price {
Price
PriceInUSD
}
}
}
}
}

Open, high, low and close of a pool's price​

Price(minimum: Block_Slot) is the first price in the window and Price(maximum: Block_Slot) the last.

Run query

Click to expand GraphQL query
query SolanaPoolPriceStats {
Solana {
DEXPools(
where: {
Block: { Time: { since_relative: { hours_ago: 1 } } }
Pool: {
Market: {
MarketAddress: { is: "2AXXcN6oN9bBT5owwmTH53C7QHUXvhLeu718Kqt8rvY2" }
}
Price: { Source: { not: "" } }
}
}
) {
Pool {
Market {
MarketAddress
}
Price {
open: Price(minimum: Block_Slot)
close: Price(maximum: Block_Slot)
high: Price(maximum: Pool_Price_Price)
low: Price(minimum: Pool_Price_Price)
}
}
average: average(of: Pool_Price_Price)
updates: count
}
}
}

Highest-priced pools with real liquidity​

Order by Pool_Price_PriceInUSD only with a liquidity floor; without one, drained pools fill the list.

Run query

Click to expand GraphQL query
query SolanaHighestPricedPoolsWithLiquidity {
Solana {
DEXPools(
limit: { count: 10 }
limitBy: { by: Pool_Market_MarketAddress, count: 1 }
orderBy: { descending: Pool_Price_PriceInUSD }
where: {
Block: { Time: { since_relative: { hours_ago: 1 } } }
Pool: {
Price: { Source: { is: "event" }, PriceInUSD: { ge: 1 } }
Quote: { PostAmountInUSD: { gt: "10000" } }
}
}
) {
Block {
Time
}
Pool {
Market {
MarketAddress
BaseCurrency {
Symbol
}
QuoteCurrency {
Symbol
}
}
Dex {
ProtocolName
}
Price {
Price
PriceInUSD
Source
}
Quote {
PostAmountInUSD
}
}
}
}
}

Pitfalls​

  • Not the trade price. For a swap, the pool price sits on the far side of the executed price: above it after a buy of the base, below it after a sell. On CLMM, Whirlpool, Raydium v4, CPMM, DBC, pump.fun and PancakeSwap, 94–100 % of swap rows were within 3 % of the trade when we checked. Use DEXTradeByTokens for executed prices.
  • PumpSwap is the vault ratio. Some PumpSwap pools trade well away from it: boosted pools by a few percent, and we have seen gaps of 15–50 %. For what a trader pays, use DEXTradeByTokens.
  • Drained pools. A pool with dust left on one side reports prices like 1e-18 or 2e17. A concentrated pool drained to the edge of its range can report the edge value (2^64 or 2^-64 after decimals). Filter on Base.PostAmountInUSD / Quote.PostAmountInUSD first.
  • Use it per market. Never average prices across pools. Very large or very small prices are often genuine for tokens with huge or tiny supplies, so weigh each pool by its liquidity.
  • Pool.Base.Price is a different number. Pool { Base { Price } } and Pool { Quote { Price } } are the ratio of the row's vault balances. They match Pool { Price } only on constant-product pools.
  • Check USD by mint. Many tokens share a symbol. Compare PriceInUSD per MintAddress.
  • Precision. Price and PriceInUSD are 32-bit floats, about 7 significant digits.
  • Recent history only. For price history beyond the last few hours, use Trading.Pairs.

Frequently Asked Questions

How do I get the current price of a Solana pool?

Use Pool { Price { Price PriceInUSD Source } } on Solana.DEXPools, or PoolEvents[].Price in the solana.dextrades.proto Kafka stream. It is the pool's own price after each event, quote per base. An empty Source means the row has no price.

How is a Solana pool price calculated from sqrt price?

For Raydium CLMM, PancakeSwap CLMM, Orca Whirlpool and Meteora DAMM v2 and DBC, the price is (sqrtPriceX64 / 2^64)^2 from the swap event, inverted when the base is token1, times 10^(base decimals - quote decimals).

How is the pump.fun bonding curve price calculated?

virtual_sol_reserves divided by virtual_token_reserves from the pump.fun TradeEvent, with decimals applied. Curves in mayhem mode carry no price.

Is the pool price the same as the trade price?

No. It is the price the pool quotes after the event. The executed price of the swap differs by that swap's price impact and fee. Use DEXTradeByTokens for executed prices.

How is it different from the Bitquery token price?

The Crypto Price API blends recent trades across all of a token's pools into one price. The pool price belongs to one pool and changes on every event in it.

Which Solana DEXs have a pool price?

pump.fun, PumpSwap, Raydium v4, CPMM, CLMM and Launchpad, PancakeSwap CLMM, Meteora DAMM v2 and DBC, and Orca Whirlpool. Meteora DLMM, DAMM v1 and vault-only venues have none.

Build with Bitquery

Ready to run this in production?

Get an API key and run these queries in minutes, or talk to us about plans and enterprise delivery.