A proxy you run, not a proxy you call
I like local-first apps. The things I reach for first — Tailscale, Linear’s CLI, anything you can brew install and have running in a minute — feel different from products you have to hand your data to and configure through someone else’s dashboard. They tend to be more fun to build, too.
I’m also a P2P obsessive. Networks where the routing layer isn’t owned by a single vendor are my favourite kind of work. Bitping is years of that — a network of tens of thousands of real residential and mobile devices that anyone can borrow bandwidth from.
p2proxy is what those two things look like together. A small Rust binary you run on your machine, exposing a SOCKS5 endpoint on localhost:1080, talking to the Bitping peer network directly. Every routing knob — peer filters, pool sizes, country selection, failover thresholds — lives in your Config.yaml, not behind a vendor’s API. Edit, reload, your next request uses it.
How you run it is up to you:
- Tinkering locally.
brew install, point your scraper atlocalhost:1080, iterate. The turnaround on a routing change is the time it takes to save the YAML. - Deploying it. Docker images,
.deb,.rpm,.apk, tarball,cargo install— pick the shape that fits your existing infrastructure. - Don’t want to run anything? The hosted version is coming. We’ll give you a hostname like
you.bitping.com:1080and a Bitping dashboard to configure it from. Get notified →
The peer network’s the same in all three. We’re shipping the local version first because it’s what we kept reaching for ourselves, and because if you’re reading an engineering blog you probably want to be able to read the code.
What it looks like
Install on macOS or Linux:
brew install --cask BitpingApp/tap/p2proxy
A minimal config:
port: 45445
servers:
- protocol: Socks5
port: 1080
min_bandwidth: 50Mbps
Run it:
export BITPING_API_KEY=<your-key>
p2proxy --config Config.yaml
The TUI comes up, peer connections start appearing in the right panel, and within a second or two you can:
curl --socks5-hostname localhost:1080 https://ifconfig.me
The IP you get back is the peer’s, not yours. That’s it — the whole product, end to end.
Why peer-to-peer
The Bitping network is tens of thousands of consumer machines running our node software. p2proxy uses libp2p to open direct streams to the ones that match your filter. Where direct connectivity isn’t possible — a peer behind symmetric NAT, a corporate firewall, the usual suspects — libp2p falls back to relays.
A few properties the daemon shape gives you specifically:
- Sub-100ms request setup. A connection pool of warm libp2p streams sits between your SOCKS5 listener and the peer. When
requests.get()fires, there’s no fresh TCP handshake to the peer — only the SOCKS5 + libp2p stream allocation, both of which are cheap. - Real peer filtering, not just country tags. You can pin to a specific peer ID, require a minimum bandwidth, or run multiple SOCKS5 listeners in the same daemon — one for US traffic, one for high-bandwidth, one for JP — each with its own filter.
- Observability you can read. The same metrics we use to debug the daemon —
p2proxy_peer_connections,p2proxy_stream_pool_size{state=...},p2proxy_socks5_requests_total{outcome=...}— are exposed on/metricsfor you to scrape.
What it doesn’t do
A short, important section because we don’t want anyone to install this expecting things it doesn’t deliver.
- Windows isn’t shipped. Use WSL2 in the meantime — the Linux binary works fine inside it. A native Windows build is on the roadmap.
- It isn’t a VPN. p2proxy routes traffic through peers. That’s a property; it isn’t a privacy guarantee. The peer can see the (encrypted, TLS) traffic going through it, exactly like any proxy. If your threat model is “an adversary watches one of these peers,” this product won’t save you.
- Pro features are a Bitping-account thing. Volume discounts, dedicated peer pools, enterprise SLAs — those are part of your Bitping plan, not part of the daemon. The daemon itself is the whole open-source package.
Want the hosted version? Bitping Hosted Proxy is coming soon — same peer network, no daemon, managed from the Bitping dashboard alongside your other tools. Get notified →
How it works under the hood
The big-picture flow per SOCKS5 request:
- Your client connects to
localhost:1080with a standard SOCKS5 handshake. - p2proxy authenticates with the Bitping network using your API key and pulls a peer from the pool that matches the listener’s filter (country, min bandwidth, peer ID, …).
- A libp2p stream — usually a warm one from the connection pool — carries the request to the peer.
- The peer forwards the request to its destination from its own IP, and the response flows back through the same stream.
The connection pool is the bit worth singling out. SOCKS5 is a per-connection protocol; without pooling, every HTTPS request your scraper makes would dial a fresh libp2p stream, which is exactly the latency tax that makes consumer-grade proxies sluggish. We keep a configurable number of warm streams per server (min_idle, defaulting to 5) so the per-request cost is the SOCKS5 handshake and nothing else.
If you want to dig further, the source is at github.com/BitpingApp/p2proxy. The Rust code is small enough to read in an afternoon.
Pricing
p2proxy is free, open source, and the binary doesn’t gate anything behind a paywall. Usage is authenticated against your Bitping account — that’s where consumption and any plan limits are tracked. Current pricing lives on bitping.com; we keep it deliberately off this post so it doesn’t go stale every time we tweak the plans.
Install it
brew install --cask BitpingApp/tap/p2proxy
If Homebrew isn’t your stack: .deb, .rpm, .apk, tarball, Docker image, and cargo install paths are all on the releases page. Quickstart and full docs live at help.bitping.com.
If something’s broken, file an issue. If something’s missing, tell us — the next release is always about a week away.