CGNAT Explained: Why One IP Address Is Not One User
Carrier-grade NAT puts thousands of subscribers behind a single address. Here is what that breaks in IP-based blocking, rate limiting and analytics — and what to do instead.
A surprising number of abuse rules are built on an assumption that stopped being true years ago: that an IP address identifies a user. Carrier-grade NAT (CGNAT) is the main reason it does not.
What CGNAT is
IPv4 addresses ran out. Rather than buy scarce address space for every subscriber, mobile carriers and many fixed-line ISPs place customers behind a shared pool of public addresses and translate ports on the way out. One public address can front hundreds or thousands of households or handsets at once.
From your server, all of that traffic looks like a single client.
What it breaks
Blocking. Ban the address after a brute-force attempt and you may have locked out an entire city block of a mobile network. The attacker reconnects, gets a new address from the pool in seconds, and continues.
Rate limiting. A limit of 10 requests per minute per IP is generous for one person and absurdly tight for 2,000 subscribers sharing an exit. You will throttle legitimate users during peak hours and never notice, because they simply leave.
Attribution. "Two accounts from the same IP" is weak evidence of multi-accounting on a carrier network. On a residential fibre line it means something. On CGNAT it means almost nothing.
Analytics. Unique-visitor counts based on address are compressed on mobile and inflated on networks that rotate addresses frequently. Both errors are invisible in the dashboard.
How to tell you are looking at CGNAT
Signals that should raise the flag:
- Connection type reported as mobile, or an ASN belonging to a mobile carrier.
- Very high request diversity from one address: many user agents, many accounts, many locales.
- Addresses in shared-transition space (100.64.0.0/10) appearing in forwarded headers.
An IP intelligence lookup gives you the first two directly, which is enough to change policy at request time.
What to do instead
- Scale limits by network class. Residential gets a tight per-IP limit. Mobile and business ranges get a much looser one, compensated by tighter per-account and per-device limits.
- Move the identity down a layer. Rate limit on account ID, session, or a device signal wherever you can. Use IP as a secondary key, not the primary one.
- Prefer challenges to blocks. A challenge inconveniences a shared network; a block punishes it collectively.
- Expire aggressively. If you must block a shared address, use minutes, not days. The attacker has moved on long before your ban does.
- Alert on collateral scale. If a single ban would affect more than a handful of active accounts, that is a signal the address is shared and the ban is the wrong tool.
The underlying principle
IP address is a property of the path, not the person. It is a strong risk signal and a terrible identifier. Systems that respect that distinction block far more abuse per false positive than systems that do not — and IPv6 adoption, which restores a degree of per-subscriber addressing, will not remove the problem while mobile traffic keeps growing.
