A NAPT gives 5,000 clients one public IPv4 address; how many concurrent flows can it carry, and what makes it run out of ports?
answer
- ports per address per protocol
- divide by the number of clients
- closed is not yet free
- same port, different destination
basics
~20 sUsing ports 1024-65535, one address offers 64,512 external ports per transport protocol, about 13 concurrent bindings per client across 5,000. Churn exhausts it: closed sessions keep their port for minutes, so short-lived connections drain the pool.
solid answer
~40 sWith endpoint-independent mapping (RFC 4787 REQ-1), each active internal address-and-port holds a single external port, reused for every destination it talks to. A pool of 1024-65535 is 64,512 ports per protocol, so 5,000 clients average about 12.9 concurrent bindings each. Ports are not freed at close: a TCP session lingers for its transitory idle-timeout (4 minutes recommended), so at 240 seconds the address sustains only about 269 new connections per second in total. RFC 7857 section 3 lets a NAT reuse one external port for different internal hosts when their destinations differ, which turns the limit into roughly 64,512 concurrent flows per destination address and port, so a single busy endpoint still exhausts it. When no port is free the new flow is refused while existing flows carry on.
code
pseudocode · 11 linesfunction allocate(proto, intAddr, intPort):
key = (proto, intAddr, intPort)
if key in bindings: # endpoint-independent: reuse for any destination
return bindings[key]
for extPort in shuffled(1024..65535):
if not held(proto, extPort): # in use, or still inside its hold time
bindings[key] = (PUBLIC_ADDR, extPort)
return bindings[key]
drop(packet) # pool empty: existing bindings are untouched
sendIcmpDestUnreachable(sender) # code 13, or code 1 on a carrier-grade NAT
return nonego deeper
Know that one public address has a finite number of ports per protocol, roughly 64,000, and that every active flow through a NAPT needs one.
Do the arithmetic: pool size, per-client share, and how hold time after close turns a concurrent limit into a connections-per-second limit.
Recognize exhaustion from its signature, new flows failing at low throughput while old ones survive, and know which fixes help one heavy client versus the whole pool.
Decide how many clients may share an address from measured peak port use rather than the average, and where connection reuse belongs so the translator is not the bottleneck.
## The pool one address gives you A NAPT identifies each flow on the outside by its **5-tuple**: protocol, source address, source port, destination address, destination port. Behind one public address the source address is fixed, so the external **source port** carries the distinction. Port spaces are separate per transport protocol, so TCP and UDP each have their own pool, and RFC 7857 section 5 says endpoint-independent mappings SHOULD be protocol-dependent by default. RFC 4787 notes that mapping a source port onto a registered port is unlikely to cause problems, and RFC 6269 concludes there is no reason to use less than **1024-65535** for outgoing source ports. That range holds 65,535 - 1,024 + 1 = **64,512** ports. ## How the mapping rule spends ports **Endpoint-Independent Mapping** (EIM) is a MUST in RFC 4787 REQ-1 for UDP and RFC 5382 REQ-1 for TCP: the translator reuses the same external address and port for every packet from one internal address and port, whatever the destination. In the classic design that external port then belongs to that internal endpoint for as long as the binding lives. **Port overlapping** (RFC 7857 section 3, a MAY) relaxes the ownership: the translator stores the full 5-tuple and gives the same external port to different internal endpoints as long as their destinations differ. Capacity then becomes per destination rather than per address. | Design | What one external port can serve | Ceiling per public address, per protocol | |---|---|---| | EIM, no overlapping | one internal address and port, all destinations | 64,512 concurrent bindings in total | | EIM with port overlapping | several internal endpoints, each to a different destination | about 64,512 concurrent flows to each destination address and port | ## The arithmetic for 5,000 clients 1. Concurrent ceiling without overlapping: 64,512 / 5,000 = **12.9 bindings per client** on average. A browser that opens a few dozen connections, or a service with a large connection pool, blows through that. 2. Ports are not free the moment a connection closes. In RFC 7857's session state machine, a TCP session that has seen FINs in both directions stays until its **transitory idle-timeout** expires (RFC 5382: no less than 4 minutes; RFC 7857 allows less but recommends 4 minutes as the minimum default), and RFC 6888 REQ-8 asks a carrier-grade NAT not to reallocate a released port for **120 seconds**. 3. Sustained rate with a 240-second hold: 64,512 / 240 = **about 269 new connections per second** for the whole address. 4. Per client: 5,000 / 268.8 = one new connection every **18.6 seconds** each. Short-lived connections without reuse, such as one HTTP request per TCP connection, exhaust that long before bandwidth is high. 5. With overlapping, the same numbers apply **per destination**: 5,000 clients all calling one popular endpoint still share 64,512 ports toward it. ## What the translator does when the pool is empty - RFC 5508 REQ-8: a NAT that cannot create a session SHOULD send ICMP Destination Unreachable with **code 13** (Communication Administratively Prohibited) and drop the packet. - RFC 6888 REQ-11, for a carrier-grade NAT: it MUST drop the packet, SHOULD send Destination Unreachable with **code 1** (Host Unreachable), which RFC 1122 treats as a soft error so TCP does not abort the attempt, and MUST NOT delete existing mappings to make room. The symptom is therefore **new** connections failing or stalling while established ones keep working, at modest throughput. ## Adding addresses, and why it may not help one client More public addresses multiply the pool, but RFC 4787 REQ-2 recommends, and RFC 6888 REQ-2 requires as a carrier-grade NAT's default, **"Paired"** address pooling: all of one internal host's sessions use the same external address. RFC 7857 section 4 says that if that anchor address runs out of ports, new sessions from that host SHOULD be dropped, unless the operator enables spilling to another address. A single heavy client can hit its own limit while the pool as a whole has room. Remedies, roughly in order of preference: reuse connections at the client, add public addresses, enable port overlapping, and only then shorten hold timers, which trades port supply for the risk of a late packet hitting a recycled port. A client host running out of its own ephemeral ports is a separate limit, enforced by the host's operating system rather than by the translator.
- Why do established connections keep working while new ones fail when a NAPT runs out of ports?Exhaustion only blocks allocation. Existing bindings already hold their ports and keep translating; RFC 6888 REQ-11 explicitly says a carrier-grade NAT MUST NOT delete existing mappings to make room. Only the packet that would need a new binding is dropped, so the failure shows up as new connections stalling or being refused.
- Why might adding a second public address not help one heavy client?Paired address pooling, recommended by RFC 4787 and the default required of a carrier-grade NAT by RFC 6888, keeps all of a host's sessions on one external address. RFC 7857 says that if that address runs out of ports, the host's new sessions SHOULD be dropped unless the operator allows spilling to another address.
saying these in an interview costs you the question
- One public IPv4 address supports 65,535 connections in total, across every protocol and destination.
- Closing a TCP connection frees its external port on the NAT immediately.
- NAT port exhaustion shows up as the translator's bandwidth running at its limit.
- A compliant carrier-grade NAT evicts the oldest mappings to make room for new flows.
- Adding a second public address always doubles the ports available to every client.