How failover works
What Proxlane does between your request and the page you get back.
Most of the time you do not need this page. Read it when a result surprises you, or before you tune anything.
The chain
Proxlane picks the providers that can serve your request, orders them, and tries them one at a time until one succeeds or the list runs out.
A provider only enters the chain if it can do what you asked. Request render=true and
providers without JavaScript rendering are excluded before anything is tried.
Order comes from configuration, not the alphabet. PROXLANE_PROVIDER_ORDER sets it.
Anything you leave out keeps a stable position behind the providers you name.
When Proxlane moves on
Each outcome decides whether the chain continues. The rules live in one table, never in an adapter, so every provider behaves the same way.
- Provider failed. 5xx, a timeout, a rate limit, a bad key. Try the next one.
- Blocked. The page came back but the detector recognised a block page. Try the next one.
- The target answered. A 404 or a 403 from the site itself is a real answer. Stop.
- Your request is wrong. A malformed URL or a denylisted host. Stop.
The third rule matters most. A 404 is not a failure to route around. Retrying it across three providers costs three times as much and returns the same 404.
Detection
A blocked request usually returns HTTP 200 with a challenge page in the body. Status codes alone cannot see it, which is why Proxlane reads the body.
When a rule matches a page the provider called a success, the outcome is SOFT_BLOCK and X-Detect-Rule names the rule. The same header appears on a HARD_BLOCK — there the provider already told us it was blocked, and the rule names which defence did it. You get
the reason, not just the verdict.
Rules currently come from vendor signatures. They have not yet been tuned against a corpus of real block pages, so treat detection as good but not finished.
The end of the chain
Failover is the retry. Moving to a different provider costs the same one request and is likelier to work, so Proxlane never asks the same provider twice while another one is left.
The last provider is different, because there is nothing after it. There Proxlane asks once
more, and only when the provider failed to answer at all: PROVIDER_ERROR or
PROVIDER_TIMEOUT. A block is still a block on the second ask, a 404 is still a 404, and a
bad key is still a bad key.
PROXLANE_TERMINAL_RETRIES=1 # the default. 0 turns it off, 10 is the ceiling
This matters most with a single provider key, where the first hop is also the last one and
there is no failover at all. npx proxlane doctor says which case you are in.
The retry is skipped when the deadline no longer has room for a full attempt, so it cannot
turn a clear PROVIDER_ERROR into a confusing BUDGET_EXCEEDED. It is a real request: it
appears in X-Attempts and it is counted in X-Cost-Estimate.
Cooldowns
A provider that just refused a domain is skipped for a short window rather than paid to refuse again.
Cooldowns are scoped, and the scope is the point:
- Domain cooldowns are shared. A block is a fact about the site, so it is worth knowing across the board.
- Account cooldowns are private to one deployment. An expired key is a fact about your account and must never affect anyone else.
GET /health/cooldowns shows what is cooling and what recently expired. Cooldowns are on by
default.
Deadlines
Your request gets one global deadline. Each attempt gets a slice of it, sized to leave room for the attempts that follow.
That is why a failover chain never outlives the client waiting on it. If the deadline runs
out, the outcome is BUDGET_EXCEEDED.
Provider health
Proxlane can also keep a running opinion of each provider and route around one that is degrading.
This is off by default. The statistic assumes failures arrive independently, and real providers have bad hours instead. In simulation, a provider with a perfectly ordinary 5% average failure rate spends over 90% of its time demoted, because the failures clump.
Turn it on with PROXLANE_HEALTH=on and watch GET /health/providers. Leave it off until
you have traffic you can check it against.
Cooldowns are separate and stay on. They react to something a provider just did, not to a prediction.
What you are charged for
Every attempt, including the ones that failed.
X-Cost-Estimate reports the total across the chain. A failover that burned two charged
hops reports two. Reporting only the successful hop would understate what a retry costs, and
the cost of retries is the thing worth watching.