Order Flow
Execution tools

Third-party console, opens in a new tab.

Sandwich Protection in Practice: Layers, Costs and Limits

There is no switch that turns sandwiching off. There are four layers, each of which closes part of the exposure, each of which costs something, and none of which composes cleanly with the others. This page treats protection as an engineering problem rather than a product category.

Exposure Layer choice Composition Controlled test Decision

Sandwich protection on Solana is a stack of four partial measures: narrowing who sees the transaction before inclusion, constraining what a profitable attack would need in order to work, shaping the order so it is not worth targeting, and choosing a fill type where the attack has no place to sit. No single layer closes the exposure. Composed carelessly, they can also cancel each other out.

This page assumes you know what the pattern is and why tolerance settings matter. The question here is narrower and more useful: given the layers available, which combination is worth running, what does the combination cost, and how would you know whether the change you made helped.

Four layers and what each one closes

The four available layers, described by the specific exposure each one addresses. None is a substitute for another; they act on different parts of the problem.
LayerClosesLeaves openCost to you
Path narrowingObservation by parties not on your chosen pathObservation by the party you choseTips or subscription, plus dependence
Constraint tighteningThe room an attacker needs between your quote and your floorNothing, if the pair is moving on its ownHigher revert rate and repeated fee spend
Order shapingThe economic attractiveness of the order itselfExposure of the shape you chose, once repeatedMore attempts, more fees, longer exposure window
Fill-type choiceThe pool position an attack needs to occupyCounterparty discretion and quote-time leakageAn embedded spread you cannot decompose

Read the third row carefully. Splitting a large order into smaller pieces reduces the prize on any individual piece, which is genuinely useful. But a sequence of identical small orders at regular intervals is itself a pattern, and a pattern is information. Shaping trades one kind of visibility for another rather than removing visibility, and the trade is only favourable if the sequence is irregular enough not to be predictable.

Why stacking is not additive

The intuitive model is that each layer removes some percentage of the risk and the remainder multiplies down. That model is wrong in three specific ways, and each of them shows up in practice.

Three interactions that break the additive model

Tight constraints plus a slow path
A narrowed path can add latency. A tighter floor is more likely to be breached when more time passes. Applied together, the second layer makes the first layer's cost worse, and the visible symptom is a rising revert rate that looks like a tolerance problem.
Shaping plus a fixed-cost path
Splitting one order into six multiplies the per-attempt costs by six. If your path charges a tip per attempt, shaping just made protection roughly six times more expensive while reducing the prize on each piece.
Fill-type choice plus path narrowing
Choosing a quoted counterparty already moves the trade off the pool where a sandwich would sit. Adding a narrowed submission path on top mostly protects a leg that no longer has the exposure, while still charging you for it.

The practical implication is that a stack should be assembled in a deliberate order rather than accumulated. Start with the layer that closes the largest part of your specific exposure, measure, and only add a second layer if the first left something identifiable open. Most desks do the reverse: they turn on everything at once, cannot attribute the result, and keep paying for all of it forever.

The cost of running the whole stack

Illustrative arithmetic with stated assumptions. Take a desk sending one hundred orders in a session. Assume protection layers as follows: a tip of 0.001 SOL per submission attempt, a constraint tightening that raises the revert rate from 3% to 9%, and shaping that turns each order into three pieces.

Illustrative per-session cost of composing three layers, using the assumptions stated above. Base fee is the protocol constant of 5,000 lamports per signature; every other input is assumed.
LineNo layersPath onlyAll three layers
Submission attempts103103330
Tips paid0.000 SOL0.103 SOL0.330 SOL
Base fees0.000515 SOL0.000515 SOL0.00165 SOL
Attempts wasted on reverts3330
Total direct cost0.000515 SOL0.1035 SOL0.3317 SOL

The full stack costs roughly three times the single-layer configuration in this illustration, and the additional protection it buys is not three times greater; it is whatever residual exposure the first layer left, which may be small. That is the whole argument for deliberate composition. Protection spending has diminishing returns in a way that is easy to demonstrate arithmetically and very easy to ignore in practice.

There is a second cost that does not appear in the table: thirty reverted attempts is thirty moments when you did not have the position you wanted. On a moving pair, the opportunity cost of not being filled can exceed every fee line above it. Any honest cost model has to carry that term even when it cannot be measured precisely.

What no layer closes

  • State inference. Your trade changes pool reserves, and that change is public the instant it lands. Anyone reacting to the new state is not front-running you; they are trading after you.
  • Wallet-level patterns. If the same address behaves the same way at the same times, the behaviour is legible from history alone, with no pre-inclusion observation required.
  • Your chosen counterparty. Every layer narrows the set of observers to include at least one party you selected. That party's conduct is a trust assumption, not a protected variable.
  • Ordinary competing flow. Someone else trading the same pair in the same slot for their own reasons will move your fill and is unaffected by anything you configure.
  • Correlated events. Listings, unlocks and announcements move prices in the window you are trading. No submission path changes that.

The distinction between the last two and adversarial behaviour is worth holding firmly, because conflating them produces bad decisions. A desk that attributes every disappointing fill to an attacker will keep buying protection that cannot help, and will not investigate the causes that could actually be addressed, such as size relative to depth or the time of day it chooses to trade.

Attributing a bad fill before buying anything

Before any layer is worth paying for, you need a rough sense of how much of your shortfall is adversarial at all. Attribution here does not require sophisticated analysis; it requires three questions asked in order, each of which eliminates a large share of cases.

  1. Was the order large relative to available depth? If so, the majority of the gap is the curve doing what the curve does, and no protection layer touches it. The remedy is sizing, not submission.
  2. Did the pair move in the same direction for everyone during that window? Broad movement affects every participant and is not directed at you. Compare the pair's behaviour either side of your slot before concluding anything.
  3. Is the pattern repeatable? A single bad outcome is not interpretable. If the same shape appears across many attempts under similar conditions, you have something worth investigating; if it appears once, you have variance.

Only the residue that survives all three questions is a candidate for the layers described above. In practice that residue is smaller than most traders assume, and it concentrates in a recognisable place: larger orders, thinner pairs, wider constraints, busier moments. Knowing where your own residue sits tells you which layer to buy and, just as importantly, when to buy nothing at all.

Designing a controlled test on your own flow

Protection changes are testable, and almost nobody tests them. The obstacle is not sophistication; it is that a proper test requires you to keep sending some orders the old way, which feels wrong. Here is a design that is realistic to run at a desk.

  1. Fix everything except the layer under test. Same pair, same size distribution, same time window, same interface. One variable.
  2. Alternate rather than switch. Send alternate orders through configuration A and configuration B in the same session. Comparing this week to last week compares market conditions, not configurations.
  3. Record attempts, not fills. Log every submission, its outcome, its fee lines, its timestamp and its signature. A log of successes is a biased sample.
  4. Define the metric before you look. Realised cost against a fixed benchmark, computed per attempt, is a defensible choice. Choose it in advance so the data cannot choose it for you.
  5. Collect enough attempts to see a distribution. Twenty attempts tells you almost nothing when the effect you are looking for is a few basis points inside ordinary variance.
  6. Compare distributions, not averages. A configuration with a slightly worse mean and a much thinner tail is often the better one, and an average hides exactly that.
  7. Write down the conclusion and the date. Market structure changes by announcement. A conclusion without a date will be applied long after it stopped being true.

The reference material you need for step three is on chain. Transaction fee composition and the account changes that let you reconstruct a fill are documented at solana.com/docs, and any routing service you use will expose its own quote parameters, in the way the developer documentation at docs.jup.ag does, so you can hold the routing variable constant while you change the protection variable.

If a test is too much work for the size you trade, that is a finding. It means the effect you are trying to detect is smaller than the effort required to detect it, which is a good reason to choose a simple configuration and stop optimising it.

Reading a protected claim

Products describe themselves as MEV-protected with very little consistency about what the phrase covers. Four questions convert the claim into something assessable.

  1. Which layer is this? Path narrowing, constraint enforcement, shaping, or fill-type selection. If the answer is all of them, ask again more specifically.
  2. Who is the residual observer? Every design leaves someone. Name them.
  3. What happens on failure? If the protected path cannot deliver, does the order fall back to an ordinary path, silently.
  4. What is measured, and against what benchmark? A claim of improvement requires a stated comparison; without one it is a description of a feeling.

A product that answers all four clearly is not necessarily better than one that does not, but it is assessable, and assessable is the precondition for everything else. Note also that the honest answer to question three is frequently the most expensive detail in the whole arrangement, because a silent fallback means your protection has a hole exactly at peak load.

Composition by trader profile

Suggested starting composition by profile. These are defaults to test against, not recommendations, and every one of them should be replaced by a measured conclusion.
ProfileStart withAdd only if measuredUsually not worth it
Occasional trader, small sizeSensible constraints and nothing elsePath narrowing above a size thresholdTips per attempt, shaping
Active trader, moderate sizePath narrowingConstraint tightening on thin pairsFull stack on every order
Desk running schedulesPath narrowing plus consistent shapingFill-type choice for the largest clipsAd hoc per-order changes
Large single ordersFill-type choicePath narrowing for the settlement legAggressive splitting into a moving market

The row for desks running schedules is the one where consistency does the heavy lifting. When the same policy applies to every order in a sequence, the resulting data is comparable and the test described above becomes possible. This is the unglamorous case for multi-venue volume automation in a protection context: not that software trades better than a person, but that it applies the same settings the four-hundredth time as the first, which is the only condition under which measurement means anything.

The operating discipline

Three habits separate desks that manage this well from desks that spend money on it indefinitely without learning anything.

First, attribute before you spend. Establish which part of your gap between expectation and outcome is adversarial at all. On most pairs, for most sizes, the majority of it is ordinary movement and competing flow, and no protection layer addresses either.

Second, add layers one at a time, with a measurement between each. The stack you end up with should be the smallest one that closes the exposure you actually identified, not the largest one your tooling supports.

Third, review on a calendar rather than after a bad trade. This landscape changes through business announcements rather than protocol upgrades, and a configuration that was correct six months ago may now be protecting against something that no longer exists while ignoring something that does.

None of this promises a clean outcome. Protection on a public chain is a matter of degree, and the residual is permanent. What the discipline buys is not safety but knowledge of your own position: which exposures you have closed, what you paid to close them, and which ones you have consciously decided to live with.

Filed under Protection by The Order Flow Desk. Any figure used here is either a protocol constant or arithmetic labelled as illustrative; the desk publishes no measured fill data of its own. Scope and method are set out on the desk page.

Read next