All articles
Solana·June 26, 2026·6 min read

Pyth vs Switchboard for Solana Trading Bots: Oracle Latency Compared

Pyth vs Switchboard Solana bot latency compared: real update cadence, confidence intervals and staleness handling for on-chain trading bots that trigger off price feeds.

A price feed that updates every 400ms sounds fine until your liquidation bot triggers on a number that's already three slots stale and you eat a bad fill. On Solana, the gap between "the oracle account holds a price" and "the price reflects the market right now" is where most on-chain trigger bots quietly bleed. Pyth and Switchboard are the two feeds you'll actually reach for, and they behave differently enough that picking the wrong one for your strategy costs you basis points on every trigger.

Both are pull oracles now, which is the first thing that trips people up. There's no daemon pushing fresh prices onto every account for free. Someone pays a transaction to write the latest price on-chain, and if nobody has done that recently, you're reading a stale value with a confident-looking timestamp. The question isn't "which oracle is faster" in the abstract — it's who is landing update transactions on the feed you care about, how often, and what your bot does when they stop.

How each feed actually updates

Pyth aggregates prices off-chain through its publisher network (Jump, Wintermute, market makers pushing directly) and produces a signed price update roughly every 400ms on the Pythnet appchain. That update is available — but on Solana it only exists on-chain once someone posts it. With the Pyth pull model you fetch a PriceUpdateV2 VAA from Hermes, post it in your own transaction, then read it in the same transaction. That's the key property: you control freshness. If you post the update yourself in the instruction that consumes it, your price is as fresh as the last Hermes tick, no matter what anyone else is doing.

Switchboard's On-Demand feeds work similarly — you pull a signed update from their oracle gateway and submit it — but the aggregation is job-based. You define feed jobs (which exchanges, what aggregation, median vs. mean), and the oracle TEE resolves them on request. That flexibility is real: you can build a feed off Raydium and Orca pool reserves that no Pyth publisher covers. The cost is that resolution isn't a fixed 400ms drumbeat; it's however long the jobs take to fetch and the gateway to sign, typically a few hundred milliseconds but variable under load.

For a bot that snipes new listings, Switchboard's job model is often the only option because Pyth simply doesn't have a feed for a token that launched ninety seconds ago. If you're building around fresh-mint execution, the oracle question folds into the same latency budget we obsess over in our Solana sniper bot work — the price source is just another hop before you sign.

The staleness trap

Here's the part people skip and then regret. Both feeds expose a publish timestamp, and both SDKs give you a "max age" guard. Use it. Every time.

With Pyth's Solana receiver:

let price = price_update.get_price_no_older_than(
    &Clock::get()?,
    30, // maximum age in seconds
    &feed_id,
)?;

If the on-chain update is older than 30 seconds, this returns an error instead of a price. That error is a feature — it means your bot refuses to trigger on a corpse. But 30 seconds is a garbage threshold for anything latency-sensitive. For a market maker or a liquidation keeper you want single-digit seconds, sometimes sub-second, and if you're that tight you should be posting the update yourself in the same transaction so the age is effectively zero. Don't read a shared feed and hope someone kept it warm.

Switchboard exposes the same idea through the feed's max_staleness config and the result slot. The mechanic differs but the discipline is identical: read the timestamp, compare against Clock, bail if it's cold.

The failure mode I've seen most in production isn't a stale read that errors out. It's a stale read that doesn't error because the max-age guard was set to something lazy like 120 seconds, so during a fast move the bot happily fires on a price from four candles ago. The chain didn't lie to you. You just didn't ask it the right question.

Confidence intervals are not decoration

Pyth ships a confidence interval with every price — a ±conf band representing publisher disagreement and uncertainty. Most bots ignore it. That's a mistake, because conf blows out exactly when you least want to trade: thin liquidity, a depeg, an exchange outage feeding bad ticks. A sane rule is to skip the trigger when conf / price exceeds some fraction of your edge. If your arb captures 15bps and the confidence band is 40bps wide, you're not looking at a price, you're looking at a shrug.

let conf_bps = (price.conf as f64 / price.price as f64) * 10_000.0;
if conf_bps > MAX_CONF_BPS {
    return Ok(()); // don't trigger into uncertainty
}

Switchboard gives you an analogous signal through the standard deviation across the samples in a feed's result. Same logic applies. Any bot that reads the point price and ignores the dispersion around it will look great in backtests and lose money on the days that matter — which is the same reason we build cross-oracle sanity checks into every MEV and arbitrage bot rather than trusting one number.

So which one, for which bot

  • Liquidation / perp keepers, blue-chip pairs: Pyth. The 400ms cadence, tight publisher coverage on majors, and the confidence interval are exactly what you want, and self-posting the update kills staleness.
  • Fresh-mint sniping and long-tail tokens: Switchboard On-Demand, because you can point a feed at the actual pools. Pyth won't have coverage in time.
  • Custom aggregation (LP-weighted, multi-venue medians): Switchboard's job model wins outright.
  • Copy-trading and wallet-driven fills: oracle choice matters less — you're mirroring flow, not triggering on a threshold — but you still want a staleness guard so you don't confirm a fill against a dead price. That's a detail we bake into our copytrading and wallet-tracking builds.

The deeper point: oracle latency is one term in a chain of latencies, and it's rarely the dominant one. If your update transaction lands three slots late because of QUIC throttling or you lost the leader race, a 400ms feed didn't help you. It's worth reading up on how QUIC connection throttling drops bot transactions and how stake-weighted QoS changes transaction priority, because those decide whether your fresh price even makes it on-chain in time. When you're squeezing the last few milliseconds, pairing a self-posted feed with a low-latency shred source like Jito ShredStream matters more than the oracle brand on the label.

Benchmark both against your own strategy before you commit. Log the on-chain publish slot next to your trigger slot for a week, measure the real distribution of staleness under load, not the marketing number. If you'd rather have that measured for you and wired into feeds that fit your latency budget, our team handles exactly this kind of oracle and data infrastructure end to end.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Solana#Pyth#Switchboard#Oracles#Latency