Solana SWQoS: Why Your Endpoint Lands at a Different Rate

Stake-weighted quality of service decides whose transactions validators accept during congestion — why it stays invisible until the network is busy.

BoltTx Team··10 min read
solanaswqostransaction-landingrpccongestioninfrastructure

Two teams run the same code. Same retry logic, same getRecentPrioritizationFees calculation, same getLatestBlockhash handling. One of them loses a noticeable share of transactions during busy periods; the other does not.

The usual first guess is that something in the application differs. Often nothing does. The difference is which path the transactions took to reach a validator, and that is governed by a mechanism most people never have to think about until it starts costing them: stake-weighted quality of service.

What SWQoS Actually Is

A Solana validator has finite capacity for accepting transactions forwarded to it. When more arrive than it can process, it has to choose.

It does not choose randomly, and it does not choose first-come-first-served. It allocates capacity in proportion to the stake weight of the node doing the forwarding. A node backed by a large amount of staked SOL gets a larger share of that validator's attention than a node backed by little or none.

That is the whole mechanism. The consequence is what matters.

Why You Have Probably Never Noticed It

When the network is quiet, validators have spare capacity. Everything forwarded gets accepted, regardless of who forwarded it. A zero-stake endpoint and a heavily-staked one behave identically, and any benchmark you run will say they are the same.

When block space is contested, the allocation starts binding. Transactions arriving through a low-stake path get accepted at a lower rate. Not rejected with an error — just accepted less often, which from your side looks like transactions quietly not landing.

So SWQoS has an unusual property: it is invisible exactly when you are testing, and it dominates exactly when it matters.

This is why "I benchmarked two providers and they were the same" is a common and misleading finding. A benchmark run on a calm afternoon measures the case where SWQoS does nothing.

If you have ruled out fee and blockhash and want to test a different path, a free BoltTx key is one line.

What It Looks Like From Your Side

You cannot query your provider's stake weight, and no error message says "deprioritised." What you get instead is a pattern:

That specific shape — fine normally, worse under load, no code change — is the signature. Compare it against the other failure modes:

Cause When it fails
Blockhash expiry Consistently, any time of day
Priority fee too low Whenever network-wide fees rise
No retry loop At a steady background rate
Submission path / SWQoS Only under congestion

The first three are diagnosable and fixable in your own code. That is why they should be ruled out first — not because they are more likely, but because ruling them out is cheap and it makes the remaining diagnosis unambiguous.

Congestion Widens the Spread

Here is the part that is easy to get wrong. Congestion does not slow everything down proportionally. It stretches the distribution.

The important consequence: congestion does not shift every transaction equally. Most are unaffected while a minority take noticeably longer, and that minority is where a low-stake path shows up.

If you are monitoring averages, this looks like a mild degradation. If you are running a strategy where the opportunity closes in a slot or two, that minority is where you actually live.

This is also why average-latency comparisons between providers tell you so little. The averages converge. The spread does not.

Testing It Without Guessing

You cannot measure stake weight directly, but you can measure the thing you actually care about.

Split your landing rate by network condition. Bucket your submissions by how busy the network was, then compare landing rates across buckets:

// Cheap proxy for congestion: what recent priority fees look like.
const recent = await connection.getRecentPrioritizationFees();
const fees = recent.map((r) => r.prioritizationFee).sort((a, b) => a - b);
const medianFee = fees[Math.floor(fees.length / 2)] ?? 0;

metrics.record("submission", {
  landed: didItLand,
  congestionBucket: medianFee > 50_000 ? "busy" : "calm",
});

If your landing rate is similar in both buckets, SWQoS is not your problem. If it falls off in the busy bucket while your fee calculation is live and your blockhash is fresh, the submission path is what is left.

Run two endpoints side by side, during congestion. Send alternating transactions through each and compare landing rates. The important detail: do the comparison when the network is busy. A test run during a calm period measures the scenario where all paths behave the same, which is not the scenario you are trying to evaluate.

What You Can Do About It

Realistically there are three options.

Run a staked validator yourself. Complete control, real operational cost. This makes sense if you are already running validator infrastructure for other reasons. It rarely makes sense purely to improve your own landing rate.

Use an endpoint with meaningful stake behind it. You inherit its allocation. This is what most teams do, and it is a configuration change rather than an infrastructure project.

Do nothing and accept the loss. Legitimate if you are not latency-sensitive. A wallet showing balances, an indexer backfilling history, a batch job with no deadline — none of these care. SWQoS matters when transaction timing has money attached to it.

Whichever you choose, the important thing is knowing which situation you are in. Teams lose weeks tuning slippage tolerance and retry intervals for a problem those levers cannot touch.

Where BoltTx Fits

We do one thing: get signed transactions into blocks. Not indexing, not parsed history, not NFT metadata. Delivery.

Submissions route through our own nodes in four regions with stake-weighted routing, and there is no public mempool exposure, so a transaction is not observable before it lands. You keep your keys — we never hold funds, never sign, never modify transaction contents.

Pricing works the same way. You include a tip in the transaction itself, paid on chain from your own wallet. If the transaction reverts, the tip reverts with it, because that is how Solana handles atomic transactions. You pay only on transactions that reach the chain.

Get a free API key. No monthly fee, no subscription:

// Pick the region closest to where your bot runs
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");

Do not take our word for it — run the side-by-side test above during a congested period. That is the only comparison that means anything here.

FAQ

What is SWQoS on Solana? Stake-weighted quality of service. When a validator receives more forwarded transactions than it can process, it allocates capacity in proportion to the stake weight of each forwarding node. Transactions arriving through a heavily-staked path get accepted at a higher rate than those arriving through a low-stake path.

Why do my transactions land fine normally but fail during congestion? Because SWQoS only binds when validator capacity is contested. With spare capacity, everything forwarded is accepted regardless of stake weight. When block space is scarce, allocation starts mattering — and a low-stake submission path gets a smaller share exactly when you need a larger one.

Can I check my RPC provider's stake weight? Not directly through a public API. What you can measure is the outcome: split your landing rate by network condition and compare. A rate that holds steady when calm and falls under load, with a live fee calculation and fresh blockhashes, points at the submission path.

Does a higher priority fee compensate for a low-stake path? Only partly. Priority fee affects ordering once your transaction has been accepted by a validator. SWQoS affects whether it gets accepted for consideration in the first place. They act at different stages, so a high fee cannot fully substitute for path quality.

Is SWQoS the same as bundle-based submission? No. SWQoS is about how validators allocate acceptance capacity among forwarding nodes. Bundle-based submission is a separate mechanism for grouping transactions with atomic execution and tip-based inclusion. A transaction can be affected by SWQoS whether or not bundles are involved.

Why did my benchmark show two providers performing identically? Almost certainly because you benchmarked during a calm period. That measures the case where every path behaves the same, since validators have spare capacity and accept everything forwarded. Re-run the comparison during congestion — that is where the difference exists.

Does SWQoS affect read calls like getAccountInfo? No. It governs how validators accept forwarded transactions, so it applies only to sending. Read-heavy workloads such as indexing, balance lookups, and history queries are unaffected, which is why many teams use one provider for reads and another for sends.

How much stake does a node need for SWQoS to help? There is no published threshold, and the effect is proportional rather than a cliff — more stake means a larger share of validator capacity. What matters practically is comparing landing rates during congestion, not chasing a specific stake number.

Should every Solana project care about SWQoS? No. It matters when transaction timing has money attached: arbitrage, sniping, liquidations, timed mints. A wallet showing balances or a backfilling indexer will never notice it. Applying trading-grade infrastructure to a workload with no deadline is wasted effort.

If my transactions never land during launches, is SWQoS definitely the cause? Not definitely. Rule out the three cheaper causes first: blockhash expiry, a fee that is too low or hardcoded, and a missing retry loop. All three also get worse under load. SWQoS is the answer that remains once those are clean and the failures still cluster around congestion.

Is SWQoS something I configure? No. It is validator-side behaviour based on the stake weight of whoever forwards your transaction. You influence it only by choosing which path you submit through.

Does SWQoS apply to every transaction? It governs how validators accept forwarded transactions in general, but it only binds when capacity is contested. With spare capacity, everything forwarded is accepted regardless of stake.

Can I see stake weight in an RPC response? No. There is no field exposing it. Measure the outcome instead: landing rate split by network condition, compared across endpoints during the same congested window.

Does SWQoS affect how fast a transaction confirms? Indirectly. It affects whether the transaction is accepted for consideration, which determines whether it lands at all. Confirmation timing after inclusion is a separate matter.

Is SWQoS the same as priority fees? No, and they act at different stages. SWQoS affects whether a validator accepts your forwarded transaction. Priority fee affects ordering among transactions it has already accepted.

Back to all posts