Open any residential proxy provider’s landing page and you’ll see the same thing: a photo of an iPhone, some copy about “real mobile IPs from real user devices.” So when I fingerprinted 1.93 million residential proxy exit nodes, that’s what I expected to find. Phones. Lots of iPhones.
There were almost none. And the reason turned out to be more interesting than “someone’s lying in the marketing.”
The number that didn’t add up
In the US, iOS is somewhere around 57% of the mobile market. Roughly one in every two phones. If a proxy pool were genuinely built from opt-in users letting an app share their bandwidth, iPhones should be all over the data — you couldn’t avoid them.
Here’s what I actually saw:
| Country | iOS market share | Proxy-pool iOS | Under-representation |
|---|---|---|---|
| United States | 57% | 0.1% | 570× |
| United Kingdom | 51% | 2.0% | 25× |
| France | 30% | 0.2% | 150× |
| Brazil | 15% | 0.1% | 150× |
Read that right-hand column again. In the US, iPhones show up in these pools 570 times less often than they show up in the real world. Globally, iOS is under 0.2% of residential exit nodes. That’s not a dip in the numbers. An entire platform is basically missing.
My first instinct was the flattering one: maybe iPhone owners are just more principled, less likely to install some sketchy “get paid for your unused bandwidth” app. That’s a nice story. It’s also wrong.
The wall Apple built by accident
iPhones aren’t missing because their owners have better ethics. They’re missing because the operating system makes running a proxy exit node borderline impossible, and it does this without ever trying to. Three things stack up:
- Background execution limits. iOS aggressively suspends any background process that keeps chewing CPU or network. A proxy exit node has to be the opposite of that — always on, always relaying traffic. iOS looks at that behavior and kills it within minutes. The whole business model requires the one thing the OS won’t allow.
- The sandbox. Every app lives in its own isolated box. Opening a listening socket that pulls third-party WAN traffic in and shoves it back out through your LAN — which is literally what an exit node does — is exactly the kind of thing the sandbox exists to prevent.
- App Store review. Even if you somehow engineered around the first two, a bundled bandwidth-sharing SDK trips the performance and privacy guidelines. Apps caught carrying one get pulled.
So it’s not one lock. It’s three, and you’d have to pick all of them. Android, by contrast, is far more permissive — which is why the pool is full of it. That asymmetry is the entire chart above.
Then what am I actually buying when I buy “mobile”?
This is the part that reframed things for me. If a provider sells you “US Mobile” and the fingerprints come back 99% Linux and Android, 0.1% iOS — the word “mobile” barely means anything at that point. What you’re really getting is some blend of:
- Cheap Android phones with the background restrictions turned off or the bootloader unlocked;
- Rooted devices where an SDK just walks past the OS restrictions it was told to respect;
- Compromised Android TV boxes — mobile-class chips sitting on fixed-line ISPs, which from a distance look like phones;
- Wholesale tunnels, where the traffic gets routed through a carrier via a plain Linux gateway and quietly borrows the “mobile” reputation on the way through.
None of that is an iPhone in someone’s pocket. The iPhone in the ad is the one device that essentially can’t be there.
The ghost is the signal
The empty column turns out to be useful, though, not just a letdown.
Because real iOS is so vanishingly rare in these pools, finding a genuine iOS TCP fingerprint on a residential IP becomes one of the more trustworthy “there is an actual human here” signals you can get. If a request says it’s an iPhone by user-agent and the TCP stack backs that up — the telltale IP ID = 0, Apple’s particular option layout — the odds that it’s a proxy are tiny. The rarity works in your favor.
The inverse is where it gets fun. An “iPhone” user-agent riding on a Linux or Android TCP fingerprint is a flare going up. The top layer is telling you one story and the layer underneath is telling you a different one, and the lower layer is the honest one. Somebody dressed up their traffic and forgot the kernel doesn’t play along.
That gap — what a connection claims to be versus what its stack actually is — is the thing you actually check. An attacker owns the user-agent string; they can type anything they want in there. What they don’t own is the kernel that shook hands with you. The kernel just answers straight — it has no idea the user-agent is lying for it.