RPC rate limits and why campaigns stall
A rate-limited endpoint does not announce itself. It drops requests, delays responses and turns a working script into one that fails in ways that look like market problems. This is the most misdiagnosed infrastructure issue in scripted trading.
What an endpoint is actually doing for you
It is easy to think of an RPC endpoint as a connection, something that either works or does not. In a trading script it is closer to a dependency that sits inside every single operation.
Sending one swap typically means: fetch a recent blockhash, read the accounts involved, possibly simulate the transaction, submit it, then poll for confirmation. That is several round trips for one trade. A campaign sending hundreds of swaps is making thousands of calls, in bursts, with timing that matters because Solana transactions expire on a short clock.
The consequence is that endpoint performance is not a background concern. It is in the critical path of everything, and when it degrades, the failures surface as trading problems rather than as infrastructure problems.
How rate limiting actually presents
Almost nobody sees a message saying they have been rate limited. What they see is a list of symptoms that point somewhere else entirely.
- Transactions that never confirm. The submission call was dropped, so nothing was ever sent, but the script logged an attempt.
- Expired blockhash errors. The fetch took so long that the validity window was mostly consumed before the transaction existed.
- A run that degrades over time. Fine for the first minutes, then increasingly broken as the request rate accumulates against a window.
- Inconsistent results on identical settings. The same configuration works at one hour and fails at another.
- Confirmation checks that time out on transactions that actually landed.
Every one of those has an obvious alternative explanation involving fees, slippage or congestion, which is exactly why this gets misdiagnosed. Teams spend an afternoon tuning priority fees for a problem that was never on the chain.
Why one slow call breaks the next thing
The reason rate limiting is disproportionately damaging on Solana rather than merely annoying is the expiry clock.
A transaction references a recent blockhash and is only valid for a bounded window afterwards. That window is short. If your blockhash fetch is delayed by a rate limiter, you have spent part of the window before the transaction is built, more of it signing, and whatever remains on submission. The transaction can arrive after it stopped being valid, and it is rejected without ever being considered.
So a throughput problem becomes an expiry problem, and the error you read describes the second one. The expiry guide covers the other causes of that same error, and slow infrastructure is the one people rule out last because it does not feel like a timing issue.
There is a second cascade worth knowing. When confirmation checks are dropped, a script cannot tell whether a transaction landed. Naive implementations resubmit, which doubles the request load at exactly the moment the endpoint is already refusing work, and in the worst case both submissions land.
What a campaign actually demands
The load is higher than intuition suggests, and the reason is that people count swaps rather than calls.
Multiply your intended swap rate by the number of calls each swap makes in your implementation. Then add retries, which are not exceptional but routine, and which arrive in bursts precisely when things are going badly. Then remember that the traffic is not smooth: a campaign concentrated into a window is deliberately bursty, and burst traffic is what rate limiters exist to stop.
Public endpoints are provisioned for occasional queries from many users, not sustained bursts from one. Using one for a campaign is not a cost-saving decision with a small quality penalty; it is a decision to have a meaningful share of the run fail for reasons unrelated to the market. The self-hosting guide covers this as one of the costs that never appears in anyone's estimate.
There is a subtler version of the same problem that survives an endpoint upgrade. Some calls are far more expensive to serve than others, and a script that polls aggressively for confirmations can generate more load than the swaps themselves. Providers rate limit on cost rather than on a simple request count, so an implementation that submits sparingly but polls in a tight loop can be throttled while appearing, by its own logs, to be doing very little. Counting requests is not the same as counting load, and the second is what the limiter measures.
What to change
- Use an endpoint provisioned for your throughput. This is the fix; everything below is mitigation.
- Fetch the blockhash immediately before signing. Minimise the window you are spending on infrastructure.
- Back off rather than retrying immediately. Hammering a rate limiter extends the problem.
- Check status before resubmitting. A timed-out confirmation is not evidence of failure.
- Pace the campaign to your real capacity. A schedule that exceeds what the endpoint can serve will fail regardless of settings.
- Log the calls, not just the swaps. Without call-level logging this problem is close to invisible.
One architectural note that removes most of the pressure at the source. A campaign does not need to send its swaps as fast as possible; it needs to spread them across a window on purpose, because uneven pacing is what makes the activity look ordinary rather than scripted. That requirement happens to align perfectly with staying inside a reasonable request rate. Implementations that fight their endpoint are usually implementations that were trying to finish quickly, which is both an infrastructure problem and a pattern problem wearing the same clothes.
Telling it apart from market problems
The distinguishing question is what the failures correlate with.
Rate limiting correlates with your own request rate. It worsens as throughput climbs, eases when it drops, and affects every venue equally because the problem is on your side of the connection.
Slippage failures correlate with venue and size. They cluster in specific pools, on specific order sizes, and are unaffected by how fast you are going.
Congestion correlates with the clock. Everyone experiences it at once, and it shows up in network-wide figures rather than only in your logs.
The cleanest test is to slow down. Halve the rate and rerun. If the failure share collapses, the problem was throughput and no amount of fee tuning would have found it. If it stays flat, the problem is on the chain and the failure guide covers how to read which of the market causes you are hitting. That one experiment takes ten minutes and it separates two categories of problem that otherwise look identical from the outside.
Frequently asked questions
01What does an RPC endpoint do in a trading script?
Everything that touches the chain. Fetching a recent blockhash, reading account state, simulating a transaction, submitting it, and checking whether it confirmed. A single swap involves several round trips, so the endpoint sits in the critical path of every operation rather than being a background service.
02Why do public RPC endpoints cause failures?
They rate limit, and a rate-limited request either returns an error or takes far longer than normal. Because Solana transactions expire on a short clock, a delayed blockhash fetch can consume most of the validity window before the transaction is even built, so it fails on arrival for reasons that have nothing to do with the trade.
03How do I know if rate limiting is my problem?
Look for failures that cluster in time rather than by venue or size, and for a pattern where a run works for a while and then degrades. Rate limiting is throughput-dependent, so it appears as the request rate climbs and eases when it drops, which is a distinctive signature.
04Does a paid endpoint fix everything?
It removes the throughput ceiling, which is the main cause. It does not fix slippage failures, expired blockhashes caused by pre-signing, or a pool too thin for the order size. Those are separate problems that a faster endpoint leaves exactly as they were.
05How much request capacity does a campaign need?
More than people estimate, because each swap is several calls rather than one, and retries multiply it further. The useful way to size it is to count the calls per swap in your own implementation and multiply by the swap rate you intend, then leave substantial headroom for retries.
06Can rate limiting cause duplicate transactions?
It can produce the conditions for it. If a confirmation check times out, a naive script may resubmit while the original is still in flight, and both can land. Handling that correctly means checking status before retrying rather than assuming a timeout means failure.
Keep reading
No endpoint to provision
Infrastructure sits inside the flat fee, and campaigns are paced against real capacity rather than a free tier.
Open the volume console