Find Proxy Throughput Before Retries Find You
Doubling workers does not guarantee twice as many useful pages. A proxy-backed pipeline can saturate its own connection pool, gateway, browser fleet, authorized destination allowance, parser, or downstream queue. Retries then create more work while the useful output curve goes flat.
I work with 98IP. This is the compact ramp model I would use before buying more capacity—including from us.
Define the output before the load
type StageResult = {
concurrency: number;
originalJobs: number;
totalAttempts: number;
validResults: number;
elapsedMs: number;
queueP95Ms: number;
latencyP95Ms: number;
rateLimited: number;
proxyAndComputeCost: number;
};
function score(s: StageResult) {
return {
usefulPerMinute: s.validResults / (s.elapsedMs / 60_000),
retryAmplification: s.totalAttempts / s.originalJobs,
costPerValid: s.validResults
? s.proxyAndComputeCost / s.validResults
: Infinity,
};
}
Raw requests per second is a transport metric. usefulPerMinute is closer to a business capacity metric because it requires validated output.
Ramp one variable set at a time
Hold the client build, proxy product, region, protocol, address family, session policy, target set, timeouts, retry rules, and parser contract constant.
Then run safe stages such as 1, 2, 4, 8, 12, and 16 workers—only inside the limits of systems you own or are authorized to test. Warm each stage, observe long enough to include normal latency, and repeat before promotion.
Stop when any gate fails. Do not jump straight to the contractual maximum.
Keep first attempts visible
Measure content-valid first attempts before retries. A status 200 can still be a login shell, empty table, regional variant, stale page, or block response.
Classify connection, proxy authentication, DNS, TLS, header timeout, 429/503, content contract, region/session, parser, and storage failures separately.
If the service sends Retry-After, respect it as a minimum delay for that scope. Do not rotate identities to defeat a rate limit. Eligible transient retries need exponential backoff with jitter, an attempt ceiling, and a batch-level budget.
Watch queue age
One slow target can occupy a shared worker pool while dashboards report high utilization. Track queue depth and p95 age by target class. Add per-target concurrency caps or isolated queues so one domain cannot starve unrelated authorized work.
Select the point before the knee
Promote a stage only while:
- useful throughput rises materially;
- first-attempt validity remains inside the gate;
- p95 latency and queue age stay bounded;
- retry amplification stays near baseline;
- 429/503 does not trend upward;
- region and session accuracy stay valid;
- cost per valid output stays flat or improves.
The next stage after these relationships break is the knee. Set production below it and retain headroom.
Normalize providers with one question: What will this exact authorized workload cost per validated result inside its freshness window? Per-GB, per-request, and per-thread prices are otherwise difficult to compare.
Use proxies only for systems and data you are authorized to access. Respect contracts, access policies, rate limits, privacy obligations, and applicable law. Concurrency and rotation must never be used to evade controls or misrepresent identity.
Disclosure: I work with 98IP. More proxy engineering guidance: https://en.98ip.com/?k=dev
Top comments (0)