Every connection a server accepts occupies a slot in a table with a finite number of rows. A TCP connection flood fills those rows with real, completed connections that then sit there doing nothing, and because each handshake genuinely completed, none of the defences that catch forged traffic apply. Finding where that table ends is a core measurement in a DDoS test. As a protocol attack it fills a finite state table rather than a link, but unlike a SYN flood it does so with fully completed, entirely valid connections.
How a TCP connection flood works
The attack finishes the three-way handshake. It sends SYN, receives SYN-ACK, and returns the ACK, so a real, established connection now exists on the server and on every stateful device in the path. Then it does almost nothing: the connection sits idle, or the attacker trickles a byte or a keepalive every so often to keep it from timing out.
Each of those live connections costs a socket, an entry in the connection-tracking table, and a small amount of kernel memory. None of that is large on its own, but the counts are what matter. A server that can move gigabits happily may only track a few hundred thousand simultaneous connections before the table that indexes them is full, and a firewall or load balancer in front of it often tracks far fewer. The measure of this attack is concurrent connections held open, not packets or bits per second.
There is an important consequence of using complete handshakes: the source addresses have to be real. A spoofed source can never return the ACK that finishes the handshake, so a TCP connection flood cannot be spoofed and instead needs a botnet of genuine hosts. That is a cost to the attacker, but it also defeats the defense a SYN flood invites. You cannot drop this traffic for looking forged, because it is not forged, and you cannot cheaply validate it with SYN cookies, because these handshakes are already complete. This is the low-and-slow relative of the flood family: the 2008 sockstress work by Outpost24 researchers showed a handful of hosts could wedge a server by holding connections open with a tiny advertised window, no volume required.
Why it matters under attack
The failure is invisible on a bandwidth graph. Utilization looks calm while the connection table quietly fills, and then new connections simply stop being accepted. Legitimate users see timeouts and resets, not a slow page, and the dashboards most teams watch show nothing wrong on the pipe.
Where the flood lands first is rarely the origin. A stateful firewall, an inline appliance, or a load balancer usually has a smaller connection-tracking limit than the fleet behind it, so it exhausts before the servers do and takes everything downstream with it. That is the real lesson of the vector: the weakest connection-tracking limit anywhere in the path is the ceiling for the whole system.
What a DDoS test measures
A TCP connection flood test characterizes the concurrent-connection ceiling: how many established, idle connections the system holds before a new legitimate one is refused. That number is the resilience result for this vector, and it belongs to whichever device in the path has the smallest limit.
It then confirms the controls that are meant to reclaim slots actually fire in time. Do idle-timeout and per-source connection caps engage before the table fills? Does the connection-tracking limit on the firewall match the reality of the traffic, or was it left at a default sized for a quieter service? And does the accept queue drain fast enough that completed connections are handed to the application rather than piling up? Separating this state-bound failure from a bandwidth-bound one is exactly what DDoS resilience testing is built to isolate.