The first 50 jobs finish so smoothly that the script feels production-ready.
At 200, responses slow down. Around 400, 429 Too Many Requests starts appearing. Keep pushing and the same network may receive 403 Forbidden, challenges, or a temporary block. What looked like a download loop has become an operations problem.
That moment is frustrating because the code still works. The parser is fine. The IDs are valid. The failure lives between requests: pacing, shared state, retries, identity, storage, cost, and the target service’s right to protect itself.
This case study follows the path from a naive one-machine collector to a reliable distributed pipeline. It uses video and transcript collection as a concrete example, but the architecture applies to any authorized workload that calls a rate-limited upstream service.
Scope and ethics: Only collect data you are authorized to access. Prefer official APIs, honor terms, access controls,
robots.txt, quotas, copyright, and privacy requirements. A proxy is a routing component, not permission to bypass a refusal.
Chapter 1: Hitting the Wall
Imagine an AI dataset job that needs metadata or transcripts for 10,000 videos. A single loop begins from one machine and one public IP.
The exact thresholds vary by service, account, geography, request cost, and history, but the failure pattern is familiar:
- The first batch looks healthy because the request rate is low.
- Latency rises as throttling or queueing begins upstream.
429responses indicate that the client should slow down.- Repeated forbidden responses or challenges show that access policy, reputation, or behavior needs review.
- Continuing blindly can affect the whole network, including ordinary browser traffic from the same IP. On a home connection such as Jio Wi-Fi, that can mean challenges appearing later during normal Chrome browsing too.
The wall is not evidence that the server is broken. It is feedback. A production client must treat upstream capacity and policy as constraints, not obstacles to brute-force through.
Chapter 2: Engineering, Not System Hacks
Scraping at scale is not a bag of header tricks. It is distributed data engineering.
The useful comparison is a ticketing system during a demand spike, such as an IRCTC Tatkal rush: requests arrive faster than they can safely be processed, so the system needs admission control, queues, workers, retries, durable state, and honest limits. Proxies may become one network-routing layer, but they do not replace architecture.
Reliable pipelines come from network design, error handling, state management, observability, and legal clarity. The goal is not to make a client invisible. The goal is to make its behavior controlled, explainable, and recoverable.
Chapter 3: Version Zero, the Naive Scraper
Version zero usually looks harmless:
for item_id in item_ids:
try:
collect(item_id)
except Exception:
pass
It runs sequentially, one request at a time. Low traffic may hide its weaknesses, but the design has no durable job state, no error taxonomy, and no distinction between a network dropout and a permanent refusal.
It is also mechanically predictable: the same network origin, the same client stack, the same sequence, and often the same interval between calls. Adding more threads only makes that predictability arrive faster.
Worst of all, except: pass destroys the evidence needed to recover. The pipeline cannot answer which jobs failed, why they failed, whether they are safe to retry, or whether an output is complete.
A script that cannot explain failure is not ready to scale. Before adding workers, make one job observable and resumable.
Chapter 4: The Four Missing Pieces
Four controls turn a loop into a client that can cooperate with an upstream system:
- Exponential backoff: wait progressively longer after retryable failures.
- Error taxonomy: separate temporary transport failures, throttling, permanent absence, and authorization refusal.
- Pacing and jitter: prevent synchronized workers from retrying at the same instant.
- Identity and session state: keep legitimate sessions internally consistent and avoid routing every job through one overloaded path.
These controls belong together. Backoff without classification retries permanent failures. Jitter without a global limit still permits the fleet to exceed its budget. Multiple egress paths without session ownership can break continuity.
Chapter 5: What the Server Can See
A proxy changes the source network address seen by the destination. It does not erase the rest of the connection.
Defensive systems can combine several signal families:
Layer 1: Network reputation
IP reputation can include the network owner, ASN, region, previous abuse, request velocity, and how many identities appear behind one address. Datacenter ranges such as major cloud providers are easy to classify. Consumer ISP space such as Jio or Airtel may carry different baseline reputation, but no provider or address type is automatically authorized or trustworthy.
Layer 2: TLS fingerprints
JA3 hashes selected fields from a TLS ClientHello. JA4 was designed to remain more stable when modern browsers randomize extension order and adds useful dimensions such as ALPN. The broader JA4+ family includes fingerprints for other protocols, including HTTP.
The operational lesson is not “copy a browser fingerprint.” It is that inconsistent layers are visible. A request claiming one client identity while its transport and behavior tell a different story can be treated as higher risk.
Layer 3: Application headers
Browsers and SDKs differ in header sets, ordering behavior, cookies, compression support, and protocol use. Randomly changing a User-Agent string does not transform one client implementation into another.
Layer 4: Behavior
Machines often traverse sequential IDs, hit exact periodic intervals, and create sharp concurrency spikes. Human traffic tends to follow relationships and contains natural variance. Platforms can evaluate those patterns across sessions, not only one request.
Chapter 6: JA3, JA4, and JA4+ Without the Hype
The screenshot’s core idea is right: transport fingerprinting is one detection layer, and behavior adds more context. The naming deserves precision:
- JA3 focuses on ordered TLS ClientHello properties and can become unstable when extension order changes.
- JA4 is a newer TLS client fingerprint designed to handle modern protocol behavior more consistently, including extension randomization and QUIC-related identification.
- JA4+ is a family of fingerprints for multiple protocols. It is not one magic score for every behavior.
- Inter-request signals are separate behavioral features computed across traffic over time.
This matters to DevOps teams on both sides. Defenders should avoid blocking a fingerprint with no context because browser and OS updates change legitimate traffic. Client teams should stop assuming that one header or one IP defines an identity.
Chapter 7: The Proxy Fallacy
Buying a larger proxy pool only changes Layer 1. If the transport, HTTP client, session behavior, or request rate is inconsistent, the remaining signals still exist.
A proxy is a tool, not a magic switch. If a service says no, changing the route does not turn that refusal into permission.
Chapter 8: Proxy Types and Their Trade-Offs
When a workload is authorized to use proxies, selection is an infrastructure decision:
Datacenter proxies
They are fast, inexpensive, and operationally simple. Their address ranges are also easy to classify. They fit high-volume, low-sensitivity services where the provider explicitly permits automated access and cost matters most.
Static ISP proxies
They use ISP-assigned address space with a stable endpoint. Stability can support long-lived sessions, but the product is usually more expensive and provider quality matters.
Rotating residential proxies
They route through changing consumer-network addresses and are commonly billed per transferred gigabyte. They can be costly for media workloads and create serious sourcing, consent, privacy, and compliance questions. Use only reputable providers that can document how endpoints are obtained and permitted.
The practical selection framework is:
- High volume, low sensitivity, explicit automation support: favor datacenter capacity.
- Session continuity and stable network identity: consider a dedicated static endpoint.
- Geo-specific authorized testing: use the narrowest compliant regional product available.
- Large media transfer: dedicated capacity may avoid shared-IP reputation and per-GB surprises.
Price is only one axis. Add trust requirements, session duration, geography, provider ethics, failure rate, and bandwidth billing before choosing.
Chapter 9: Rotation Is Not Capacity
Round-robin rotation spreads requests, but it does not create unlimited safe throughput. An address that is selected every few seconds never gets a chance to cool down.
A useful planning model is:
effective capacity = pool size x busy_time / (busy_time + cooldown_time)
This is not a promise of allowed throughput. The upstream quota remains the real ceiling. The formula only shows why a pool of 100 endpoints does not behave like 100 continuously available workers.
Chapter 10: The Sticky Session Rule
Do not change network identity halfway through one logical session unless the upstream protocol explicitly supports it.
For segmented media, one playback or download session suddenly arriving from several cities can look broken or risky. It can also invalidate cookies, signed URLs, affinity, and audit trails.
The rule is simple: rotate between independent jobs, not between segments of the same job. A worker should acquire a lease, preserve session state, finish or fail clearly, then release the lease.
Chapter 11: Architecture V1, One Machine Done Properly
Do not jump to Kubernetes before one machine is reliable.
Version one can run on a single host with four durable components:
The job table is the source of truth. A crash leaves enough state to resume. Fixed concurrency prevents accidental overload. Large artifacts stream directly to object storage instead of filling the server disk.
This design may be enough for many workloads. Distribution should solve a measured capacity or availability problem, not satisfy an architecture diagram.
Chapter 12: Smart Error Classification
Every failure needs a policy, not a generic retry:
429 Too Many Requests: honorRetry-Afterwhen present, apply capped exponential backoff with jitter, and reduce admission rate.403 Forbidden: do not automatically repeat through another route. Pause the job, verify authorization and credentials, and quarantine the workflow if policy is unclear.404 Not Foundor410 Gone: mark terminal with a reason unless the domain guarantees eventual creation.- Network timeout or reset: retry a bounded number of times with backoff because the outcome may be transient.
5xx: retry cautiously within a budget; the dependency may already be overloaded.- Parser or schema error: preserve the raw input, alert on version drift, and avoid re-downloading until processing code is fixed.
Jitter matters because identical workers otherwise wake together and create a retry storm. Retries must also have a maximum attempt count, a time budget, and a dead-letter path.
Chapter 13: Architecture V2, a Distributed Fleet
When one host is genuinely the bottleneck, split scheduling from execution.
Use separate delayed-retry and active-work paths so a retry storm cannot starve fresh jobs. Workers remain stateless and scale horizontally from queue depth, but autoscaling must stay behind the global governor. Otherwise, adding pods only multiplies the upstream burst.
Postgres stores operational metadata; object storage holds heavy files. Redis coordinates ephemeral queue and rate state, not irreplaceable artifacts.
Chapter 14: Idempotency and Global Rate Limits
Distributed queues can deliver a job more than once, especially when a worker loses its lock after completing external work but before acknowledging the message. Design for at-least-once execution.
Before processing, derive a stable idempotency key from the source item, requested format, and pipeline version. Check whether a valid artifact and completion record already exist. If they do, acknowledge the duplicate instead of downloading again.
A shared Redis token bucket can govern the entire fleet:
worker may start only when:
global token available
AND tenant budget available
AND endpoint lease available
AND circuit breaker closed
This prevents 20 workers from each believing they own the full request allowance. Managed proxy services can own address lifecycle and routing, but application-level admission control still belongs to the pipeline.
Chapter 15: Build the Proxy Manager as a State Machine
Treat each endpoint as a stateful resource governed by a circuit breaker.
Health checks should reflect the authorized target and actual protocol, not merely prove that a generic website is reachable. A proxy that can reach a test endpoint may still fail DNS, TLS, geography, authentication, or policy checks for the real dependency.
Expose Prometheus-style metrics for success rate, latency, bytes, active leases, cooldowns, response classes, and state transitions. Logs should connect job_id, attempt_id, worker_id, and endpoint_id without recording secrets.
Chapter 16: A Self-Healing Pool
A healthy pool adapts without hiding failure.
- Track rolling success rate and latency per endpoint, such as the last 50 authorized calls.
- Prefer healthy endpoints while still sending a small amount of probe traffic to marginal ones.
- A sample policy might route 80% to proven endpoints and 20% to recovery candidates, but tune it from evidence.
- Open a pool-level circuit breaker when aggregate success drops below a threshold, such as 50%.
- Pause the whole pipeline when the failure is likely application-wide rather than sacrificing every endpoint to the same bug.
The pool-level breaker is crucial. If a bad release sends malformed requests, rotating faster burns the entire fleet. Stopping is often the most reliable action a system can take.
Chapter 17: Bandwidth Is an Architecture Decision
For speech or NLP work, downloading full video is usually the most expensive way to obtain audio or text.
Illustrative sizes from the case study are:
- A 10-minute 1080p video may be around 300 MB.
- An audio-only Opus stream may be around 8 MB.
- A transcript may be around 50 KB.
Actual sizes vary by codec, bitrate, duration, and caption availability, but the order-of-magnitude difference is the point. Selecting audio or text instead of video can reduce transfer by well over 95% for the right workload.
The intuition is similar to listening to music on Wynk instead of streaming a 4K video on Hotstar when all you need is audio. Format selection is therefore the strongest cost-control lever. Do not optimize proxy pricing while moving 30 times more data than the model needs.
Chapter 18: Budget the Pipeline Before Running It
Suppose planning uses a conservative average of 12 MB of audio per item:
10,000 items x 12 MB = about 120 GB
120 GB x 1.15 retry factor = about 138 GB transferred
That 15% retry allowance covers transient failures and partial attempts; it is a budget, not permission to retry forever.
Compare the complete cost model:
- Per-GB proxy plans scale linearly and work well for low or uncertain volume.
- Dedicated per-endpoint plans can become cheaper at sustained high transfer.
- Shared endpoints may carry reputation risk outside your control.
- Object storage charges include operations, retention, and sometimes retrieval or egress.
- Cloudflare R2 currently does not charge direct egress, though storage, operations, retrieval classes, and connected services can still cost money.
Track bytes by source, format, attempt, and final artifact. Without that telemetry, retry overhead and accidental video downloads remain invisible until the bill arrives.
Chapter 19: The AI Dataset Processing Pipeline
Downloading is only the first stage. Keep acquisition separate from transformation so processing bugs do not trigger expensive network work again.
Stage 1 keeps original downloaded files immutable. Stage 2 converts approved audio to a standard format such as 16 kHz mono WAV. Stage 3 uses existing captions where permitted or runs an approved speech-recognition model. Every stage writes its own status and artifact checksum.
Decoupling means a normalization or transcription bug can be fixed and replayed from raw storage without paying to reacquire data. It also creates lineage: every dataset row can point back to its authorized source, processing version, and quality checks.
Chapter 20: The Production Checklist
Before scaling, verify the following:
- Written authorization, terms, privacy, copyright, and retention requirements are clear.
- Official APIs and bulk export paths were evaluated first.
- The job model has durable states, attempt history, and terminal reasons.
- Every retryable operation is idempotent and bounded.
429,403,404,410, timeouts,5xx, and parser failures have different policies.- Global and tenant-level rate limits exist outside individual workers.
- Concurrency and autoscaling cannot exceed the admission budget.
- Session-scoped work keeps one leased network identity until completion.
- Proxy providers can document endpoint sourcing, consent, and acceptable use.
- Raw artifacts are immutable; transformations are replayable and versioned.
- Metrics cover latency, success, response classes, retries, bytes, cost, queue age, and circuit state.
- Pool-level breakers stop fleet-wide damage during upstream incidents or bad releases.
- Operators have a dead-letter queue, runbook, alerts, and a safe kill switch.
Conclusion
The most important lesson is not which proxy to buy. It is recognizing when a script has become a distributed system.
At small scale, one loop can hide missing state, missing budgets, and missing failure semantics. At larger scale, every omission becomes visible at once. More workers and more IPs amplify the architecture you already have; they do not repair it.
The production path is less dramatic and far more effective: obtain permission, minimize the data, admit work through a global budget, preserve sessions, classify errors, make jobs idempotent, store artifacts durably, observe everything, and stop safely when the system loses confidence.
The goal is not to “beat” the upstream service. The goal is to build a pipeline both teams could inspect without surprises.
Sources and Further Reading
- Video source: proxy and scraping architecture case study
- RFC 9110: HTTP Semantics
- RFC 6585: HTTP 429 Too Many Requests
- RFC 9309: Robots Exclusion Protocol
- AWS: Timeouts, retries, and backoff with jitter
- AWS Well-Architected: Control and limit retry calls
- Cloudflare: JA4 fingerprints and inter-request signals
- FoxIO: JA4+ technical documentation
- BullMQ: Idempotent jobs
- BullMQ: Queue and worker documentation
- Redis: Token bucket rate limiting
- Cloudflare R2 pricing and egress