You add a client-side CPU puzzle to price out a botnet flood — who ends up paying more, you or the attacker?
answer
- difficulty is capped by your weakest client
- the attacker's CPU is somebody else's
- parallel on their side, serial on yours
- a capability filter, not an economic one
- nothing runs once the link is full
basics
~20 sUsually you. Puzzle difficulty is capped by your weakest legitimate device, so the toll stays small, and a botnet pays it in parallel on hardware and electricity that are not the attacker's. You add latency for every real user and barely dent a funded flood.
solid answer
~50 sThe pitch is that a puzzle makes each request cost the attacker CPU, so a flood becomes uneconomic. The arithmetic does not hold. The difficulty you can set is bounded by the slowest legitimate client you are willing to serve — an old phone on a poor link — so the per-request cost lands somewhere in the tens of milliseconds. An attacker with a hundred thousand compromised hosts pays that in parallel, on someone else's silicon and someone else's power bill, so their marginal cost is close to zero while yours is a visible latency tax on every genuine visitor plus battery, an interstitial page, and every non-browser client broken. What the puzzle does buy is narrower and real: it removes cheap tooling that does not execute the challenge at all, and it forces surviving attackers into holding real, attributable, stateful sessions. If a funded flood simply pays the toll, the honest answer is capacity or upstream absorption, not a harder puzzle.
go deeper
Know what a client-side puzzle is asking for — deliberate work by the client before the server commits anything — and that the client doing it is a real person's device.
Be able to explain why difficulty cannot be raised freely: the ceiling is the slowest legitimate client, and everything above that ceiling is user abandonment.
Show the cost comparison honestly — parallel and free on the attacker's side, serial and visible on yours — and name the case where the puzzle genuinely works, which is tooling that cannot execute it at all.
Be able to say when the answer stops being a control at the front door and becomes capacity or upstream absorption, and to defend that conclusion to people who wanted a cheaper fix.
## The proposition A client-side puzzle asks the client to burn CPU — solve something deliberately slow to compute and trivially fast to check — before the front door will spend anything on it. The appeal is economic: if every request costs the sender real work, a flood of a million requests costs a million units of work, and floods become unaffordable. It is a genuinely attractive idea and it is asked about in interviews precisely because the wrong answer is confident and common: *proof of work makes DDoS economically infeasible*. It does not, and the reason is worth being able to explain without hand-waving. ## Where the ceiling comes from The difficulty is not yours to choose freely. It is set by the weakest legitimate client you are still willing to serve. If your users include a five-year-old phone on a congested mobile link, then a puzzle taking a second on that device is a second of dead time added to a page load, on top of the network round trips the challenge already costs. In practice that pins the work at tens of milliseconds of modern-CPU equivalent — small. Now look at who pays that on the other side. ## The attacker's cost structure - The work is **embarrassingly parallel**. A hundred thousand hosts each solving a small puzzle produce a hundred thousand admitted requests in the time one host produces one. - The hardware is **not the attacker's**. Compromised devices, rented capacity billed to somebody else's account, or capacity bought by the hour — in none of these cases does a CPU-second come out of the attacker's own budget in the way the model assumes. - The electricity is **not the attacker's** either, which is the half of the argument people skip. So the toll that is painful for one legitimate laptop is noise across a distributed flood. The asymmetry the design depends on runs the wrong way: you have imposed a fixed per-request cost on a population that experiences it serially and individually, and on an adversary that experiences it in parallel and for free. ## What you are actually paying | What it costs you | Who feels it | | --- | --- | | Added latency before anything renders | every genuine visitor, worst on slow devices | | Battery and heat | mobile users | | An interstitial page in the flow | conversion on sign-up and checkout paths | | Total breakage | clients that cannot execute the challenge at all | | A path that skips the puzzle | whoever you had to exempt | And the puzzle only ever engages for traffic that reaches you. If the flood is filling the transit link, nothing at the front door is running. ## What the puzzle does buy This is the part a purely dismissive answer gets wrong. A puzzle is effective against **cheap, non-executing tooling** — scripted request generators that speak just enough of the protocol to make a request and nothing more. Against that, the challenge is not an economic argument at all, it is a capability filter, and it works completely. It also forces any attacker who does pay it into a real, stateful, return-routable session, which converts an anonymous packet flood into a countable set of sources you can attribute and block, and raises the attacker's unit cost from a packet to a browser. ## How to decide Ask what the flood is made of. If it is unsophisticated tooling and your users are overwhelmingly on capable interactive clients, the puzzle is a good trade. If it is driving real browsers, or if the surface you are protecting is an API, a server-to-server integration or a callback path, the puzzle costs you far more than the attacker and you should not reach for it. And when the challenge holds, the flood pays the toll, and volume is unchanged, the diagnosis is not that the puzzle was tuned too softly. It is that you are now facing an adversary whose supply is real hosts, and the remaining levers are capacity, upstream absorption, and narrowing what the flood is allowed to reach — not a harder sum.
- The challenge holds, the flood pays the toll, volume is unchanged. What did the challenge buy you?The surviving traffic is return-routable and stateful, so every source is now a real address you can count, group and block, and the attacker's unit cost rose from a packet to a held session. Sometimes that alone shrinks the flood. When it does not, the remaining levers are capacity and upstream absorption, not more difficulty.
- When is a CPU puzzle clearly the right control?When the flood is cheap tooling that never executes the challenge, and when your legitimate population is overwhelmingly capable interactive clients on a path where an extra second is tolerable. It is the wrong control in front of an API, a machine-to-machine integration, or a user base on low-end devices.
- Why not just raise the difficulty until the flood stops?Because the difficulty is bounded by legitimate clients, not by the attacker. Every increase falls hardest on the slowest genuine device, and the attacker absorbs it in parallel. You reach the point where real users abandon the site long before the flood does.
A coin-operated turnstile priced so a pensioner can still afford it. It keeps out people with no coins at all; it does not slow down someone spending a stolen wallet.
saying these in an interview costs you the question
- Claims proof of work makes floods economically infeasible
- Sets difficulty from attacker cost rather than the weakest real client
- Assumes attacker CPU and power come out of the attacker's budget
- Thinks a puzzle helps once the uplink is saturated
- Ignores that the work is parallel across the flood and serial for a user