When a stack goes down under attack, it rarely goes down everywhere at once. One component runs out of capacity while every tier behind it still has headroom, and that component is the layer of first failure, the diagnostic result a thorough DDoS test is built to locate. It might be the network link, the kernel connection-tracking table, the load balancer, the TLS terminator, the application worker pool, or the database. Whichever it is sets the ceiling for the whole system.
Why the first failure is hard to see
The tier that reports errors is often not the tier that ran out. A slow database query holds an application worker for longer, the worker pool fills, and the load balancer starts returning 502s. The dashboards light up at the edge while the cause sits three hops behind it.
Little's law is the reason. The number of requests in flight at any tier equals the arrival rate multiplied by how long each one takes, so extra latency deep in the stack becomes extra concurrency everywhere above it. Every fixed-size pool on that path fills a little faster, and the smallest one gives out first.
Some tiers fail without saying so. When the Linux connection-tracking table is full, the kernel drops new packets and logs nf_conntrack: table full, dropping packet. When the accept queue overflows, the only trace is a counter (ListenOverflows in nstat or /proc/net/netstat). Neither produces an application error, so a team watching HTTP status codes sees traffic quietly fall away and calls it a network problem.
Why it matters under attack
The layer of first failure belongs to the stack and the vector, not to the stack alone. A SYN flood presses on the backlog and the state table. An HTTP flood of cheap requests may never touch either, and instead fills the worker pool or the database connection pool. One system can have three different first failures depending on what hits it. Combine vectors and the first failure can land on a tier neither breaks alone, such as TLS handshakes and an HTTP flood competing for the same cores.
It also moves. Raise the conntrack limit and the next tier in line becomes the first to fail, which is fine as long as it fails at a higher load. Hardening that ignores the order wastes money: doubling origin CPU does nothing if a 4,096-entry listen backlog (the Linux somaxconn default since kernel 5.4) or nginx's default of 512 connections per worker process caps the stack long before CPU matters.
That is why the answer is worth more than a pass or fail. "We went down at 40,000 requests per second" says nothing about what to change. "The worker pool pinned at 40,000 while the database sat at 30 percent" names the next ticket.
What a DDoS test measures
A test escalates load in steps and holds each step long enough for queues to settle, recording a saturation signal at every tier: link utilisation, conntrack entries against their maximum, accept-queue overflows, load-balancer queue depth, busy workers, database pool waits. For each tier it notes the step where the signal crossed its knee, the point at which latency starts climbing faster than load.
Where it runs matters. Many of these limits are sized from the host rather than set by hand (the conntrack maximum scales with memory, for example), and load balancers, instance types and pool settings often differ between staging and production. A staging run can therefore name a different first failure than production would, which is why the result is only trusted for the environment it was measured in.
The output is an ordering, not a single number. The first tier on the list is the binding constraint, the gap to the second says how much one fix will buy, and repeating the run per vector shows whether the order changes. Which vector reaches which tier first is one of several places where the attack class changes the answer, and Understanding DDoS Attack Vectors sets out the rest.