Trading through a congested period without compounding the damage

You cannot fix the network and you can decide how much a bad hour costs you. Every technique here reduces the cost of being wrong rather than trying to force an outcome the chain is not offering.

The Network Conditions Desk 2031 words 10 min read Updated 4 September 2026
first lever size Smaller units contend for less of the per-account allowance
second lever deadline State it explicitly and keep it inside the blockhash lifetime
budget per hour A per-attempt fee figure hides what a retry loop actually spends
stopping rule pre-written Decided before the session, not during the worst part of it

The correct posture during a congested period is not a clever technique. It is a set of adjustments that lower the cost of every wrong outcome: smaller units, explicit deadlines, a fee budget expressed as a rate, retries that cannot duplicate your intent, and a rule that tells you when to stop. None of it makes the network include you. All of it makes losing cheaper.

That framing matters because congestion invites the opposite instinct. When attempts fail, the reflex is to send more of them, faster, at a higher price, which is exactly the behaviour that converts an unlucky hour into an expensive one.

The posture in one paragraph

Halve the size, measure the compute, price from your own accounts, state a deadline shorter than the blockhash lifetime, resolve every signature before replacing it, and stop at a threshold you wrote down earlier. Six adjustments, all available in advance, none of which requires you to predict anything about the chain.

Everything that follows is the reasoning behind those six, and the order matters. Size before price is the one most people get backwards, and it is the one that costs the most.

Reduce size before raising price

Contention on Solana is per account. Transactions writing a popular pool are serialised against each other and charged against the same per-account compute allowance, so the resource you are competing for is narrower than the block. A smaller transaction asks for less of that allowance and is easier for a leader's scheduler to place into a block that is already partly full.

Raising the price does something different. It improves your ranking among competing transactions without changing how much room you need. Both levers are real, but price is the expensive one and it is the one that keeps working badly if the constraint is space rather than ranking.

Splitting also improves the shape of a bad outcome. A single large attempt either lands or does not. Six smaller units can land partially, and a partial position with a known cost is a better place to make the next decision from than a total miss.

There is a floor. Every transaction pays a base fee per signature regardless of size, so splitting indefinitely converts a contention problem into a fee problem. Split until the units are comfortably placeable and stop there.

State your deadline explicitly

Every transaction carries a recent blockhash and is only accepted while that hash is within a bounded window of blocks. The published limit is one hundred and fifty blocks, and at the four hundred millisecond target slot duration that is sixty seconds of arithmetic before any skipped slots are counted.

Your submission window should be shorter than that ceiling, and it should be a number you chose rather than whatever your client library does by default. An attempt that is still being tracked after its blockhash has expired is consuming attention and log space for something that cannot succeed.

The corollary is that a retry should be a new transaction, built from a fresh blockhash, rather than a resend of a dead one. Transaction structure and blockhash handling are documented in the Solana protocol documentation, and the behaviour is worth confirming there rather than inferring from a library's defaults.

A fee budget is a rate

The per-attempt fee is a number people quote and it is not the number that hurts. What hurts is the product of that fee and the number of attempts your logic is capable of making in an hour, because during congestion the attempt count is exactly what rises.

Write the budget as a rate. Attempts per minute multiplied by the fee per attempt multiplied by sixty gives you a per-hour ceiling, and that ceiling is what you should be comparing against the expected value of the trade. A routine that quietly makes four attempts a minute is making two hundred and forty an hour, and at any meaningful priority price that is a real amount of SOL spent on nothing in particular.

The same arithmetic is how you should compare tools rather than campaigns. Anyone sizing a programme should work out how much volume a token needs first and then price the attempt rate required to produce it under bad conditions, not under good ones. Budgets built from calm-day assumptions are the ones that fail on the day they matter.

Retries that cannot double-fill

The most expensive failure in congested conditions is not a missed trade. It is two fills you only wanted one of, and it happens because a client gave up waiting on a transaction that had not actually failed.

A timeout is a statement about your patience. It tells you that you stopped watching, not that the transaction is dead, and a transaction you stopped watching can still be included. Sending a replacement at that moment means two live transactions with the same intent, in a market that is moving, at a moment when confirmations are slow.

The rule is unconditional: resolve the original signature before sending a replacement. Look it up on chain, and act on what you find rather than on what you assume. The public Solana explorer is sufficient for a manual check, and any automated flow needs the programmatic equivalent built in before it is allowed to retry anything.

Three outcomes, three actions

The signature is present and succeeded: your position has changed, read your balances before deciding anything. It is present and failed: you have an on-chain reason, address that parameter. It is absent: it was never included, and once its blockhash expires it never will be, so build a fresh transaction if you still want the trade.

A worked sizing example

The numbers below are assumptions chosen to demonstrate the arithmetic. They are not observations of any market, and nothing here should be read as a claim about what any figure typically is.

Suppose you intend to trade sixty SOL into a contended pool. You split it into twelve units of five SOL. You allow up to three attempts per unit, and you have set a priority price that produces a fee of roughly 0.0002 SOL per attempt, plus the base fee per signature.

QuantityValueWhere it comes from
Intended position60 SOLYour decision
Unit size5 SOLChosen so a partial fill is still useful
Units1260 divided by 5
Maximum attempts3612 units at 3 attempts each
Fee ceiling0.0072 SOL36 attempts at 0.0002 SOL, illustrative price
Illustrative slippage at 1.2%0.72 SOL1.2% of 60 SOL, an assumed rate
Fee share of total costAbout 1%0.0072 against 0.7272 SOL combined

The last row is the point of the exercise. Under these assumptions the priority fees are a rounding error next to the price you pay for execution, which means an argument about fee settings is the wrong argument. The lever that matters is the one that changes the 0.72, and that lever is size, venue and timing rather than price per compute unit.

Change one assumption and the conclusion changes with it. If the retry ceiling were removed and the routine attempted continuously for an hour at four attempts per minute, the fee line would be 240 attempts at 0.0002 SOL, or 0.048 SOL. Still smaller than the illustrative slippage, and now spent with no cap and no relationship to whether anything landed. Unbounded retries are how a small line item becomes an unpleasant one.

Venue choice under contention

Because contention attaches to accounts, a different pool for the same asset may be entirely uncontested. Moving there is a legitimate response and it has an obvious trap: the alternative venue has to have the depth you need.

Trading a size into a thin pool to escape a contended one swaps an inclusion problem for a price problem, and the price problem is usually larger. The worked example above shows why. Execution cost dominates fee cost by two orders of magnitude under those assumptions, so a route that improves inclusion while worsening execution is a bad trade dressed as a solution.

The honest version of this decision compares the expected execution cost at each venue at your intended size, and only then considers which is easier to land in. Operators running a SOL volume bot across several venues face this constantly, and the correct default is to prefer the venue with depth and manage inclusion with sizing, rather than to chase whichever pool is quietest.

The stopping rule

Write it before the session. A rule decided in advance is a rule; the same decision made while losing is a mood, and moods consistently stop later than intended because each additional attempt feels cheaper than admitting the session is over.

A usable rule has three parts: a threshold, a unit and an action. For example, three consecutive units failing to land within their deadline, at which point you stop sending for a fixed period and run the two-minute network check. The specific numbers are yours. The structure is what makes it enforceable.

Pair it with a resumption rule, because the harder decision is when to start again. Requiring one clean check plus one small successful trade before resuming at full size is a low bar that still prevents you from walking straight back into the same conditions.

The reason a written rule outperforms judgement here is not that judgement is bad. It is that the information available in the moment is the worst information you will have all day. You know your recent attempts failed, you do not know whether the condition is ending, and the cost of continuing is invisible while the cost of stopping is immediate and obvious. Every incentive in that moment points at one more attempt, which is precisely why the decision should not be made there.

There is also an attention argument. Sending into a condition consumes the capacity you need for the diagnosis, and the diagnosis is what tells you whether the fee lever is even connected. Operators who stop early usually end the session knowing what happened. Operators who keep sending usually end it with a spent budget and a story.

If a broader condition is suspected, the operator-published cluster status at status.solana.com is where a declaration would appear. Record what you see there, including a clean result, because it is part of the timeline you will want afterwards.

Weak responses and better ones

SituationCommon responseBetter responseReason
Attempts not landing on one pairRaise the priority price repeatedlyHalve the unit and re-measure computeThe constraint is space on a contended account, not ranking alone
Client timed outSend a replacement immediatelyResolve the original signature firstA live original plus a replacement is a double fill
Everything failing, all venuesRewrite routing logic mid-sessionStop, run the isolation sequence, check statusChain-wide conditions are not fixed by your code
Fees climbing with no resultIncrease the retry rateCap attempts and convert the budget to a rateUnbounded retries spend without bound
Contended pool, thin alternativeMove the whole size to the quiet venueCompare execution cost at your size firstSlippage typically dominates fees by a wide margin
Session going badlyDecide when to stop in the momentApply the threshold written earlierIn-the-moment decisions stop later than intended

Rehearsing the posture

The posture is only useful if it is available under pressure, which means it has to exist as configuration rather than as intention. Everything below can be set up on a quiet day.

  • Have a reduced-size profile ready to apply, rather than editing numbers while a session is going badly.
  • Set an explicit submission deadline in your client and confirm it is shorter than the blockhash lifetime.
  • Cap attempts per unit and per hour, and make the cap a hard limit rather than a guideline.
  • Make signature resolution a precondition of any retry path, tested at least once deliberately.
  • Write the stopping rule and the resumption rule in the same place you keep your parameters.
  • Keep a small trivial transaction ready as your end-to-end path test.
  • Record the session as it happens: times, endpoints, signatures, and what you changed.

The last item is what connects this report to the next one. A congested session with notes is raw material for a review that produces one justified change. The same session without notes is an anecdote, and anecdotes are what fill trading systems with settings nobody can explain a month later.

Questions the desk keeps being asked

Should I raise priority fees when transactions keep failing?

Only after establishing that the fee lever is connected. Send a small transaction on a quiet, unrelated account. If it lands promptly you are contending for a specific resource and price is meaningful. If it also struggles, the condition is broader than your pair and raising price buys a more expensive version of the same outcome.

Is it better to send one large trade or several small ones?

Under contention, several smaller units usually behave better. Each one asks for less of the per-account allowance, is easier for a scheduler to place, and leaves you with a useful partial position if only some land. The trade-off is more transactions, more base fees and more opportunities for an ambiguous outcome, so the split has a sensible floor.

How long should I keep retrying a transaction?

Less time than the blockhash remains valid. The published validity window combined with the target slot duration puts an arithmetic ceiling of about a minute on any single attempt, and retrying past that point is spending attention on something that can no longer be included. Build a fresh transaction instead of resending a dead one.

What is the danger with automatic retries?

A replacement sent while the original is still live can execute alongside it, producing a position you did not intend at a moment when prices are moving. Any retry logic must resolve the original signature before sending a replacement. This is the single most expensive failure mode in congested conditions and it is entirely preventable.

Does switching venue help during congestion?

Sometimes, because contention is per account rather than chain-wide, so an alternative pool may be uncontested. It helps only if the alternative genuinely has the depth you need. Moving a trade to a thin venue to avoid a queue swaps an inclusion problem for a price problem, which is usually the worse of the two.

When should I stop trading entirely?

At whatever threshold you wrote down before the session. The value of the rule comes from having decided calmly, not from the specific number. Operators who leave the decision to the moment consistently stop later than they intended, because each additional attempt feels cheaper than admitting the session is over.

Filed in Response by The Network Conditions Desk. Every mechanism on this page is described from public protocol and client documentation; every number is either a published constant or arithmetic labelled as illustrative. How the desk sources and corrects its pages is set out in about the desk.