knowledgebase

HTTP vs HTTPS vs SOCKS5 proxies: what actually differs

Your scraper works fine. You swap the proxy URL from http:// to socks5:// because a forum thread said SOCKS5 is faster, the request still returns 200, and you ship it. A week later the target starts serving you prices for the wrong country, and your local resolver logs are full of the domains you thought you were proxying.

Protocol choice decides which machine resolves your hostnames, which credentials cross the wire in cleartext, and whether Chrome quietly ignores the proxy and connects direct. None of that shows up in a smoke test that only checks for a 200.

I'll go through what each of these three protocols does on the wire, what each hop can actually read, where the DNS lookup lands, and how to pick without overthinking it.

How do HTTP, HTTPS, and SOCKS5 proxies work?

HTTP, HTTPS, and SOCKS5 proxies differ in what the proxy hop can read. An HTTP proxy parses your web requests and can cache or rewrite them. An HTTPS proxy is that same proxy with TLS wrapped around the client-to-proxy hop. SOCKS5 relays raw TCP or UDP and parses nothing at all. Choose by traffic type.

An HTTP proxy sits at the application layer. It reads your request line and headers, which is why it can cache a response, strip a header, or add X-Forwarded-For and give you away.

SOCKS5 sits below that, between the application and the transport. It takes a host and a port, opens a socket, and shovels bytes in both directions. It has no idea whether those bytes are HTTP, IMAP, or a game client's custom binary format.

The reason both exist is age and scope. SOCKS was written for firewall traversal for any TCP protocol; HTTP proxies grew out of web caching, back when caching a shared university connection was worth real money.

HTTP vs HTTPS vs SOCKS5 proxies: what each term means

These get lumped together in vendor docs, and one of the three names is doing double duty, which is where most of the confusion comes from.

Term What it actually is What the proxy can read Where you meet it
HTTP proxy Application-layer proxy for web traffic; you send it an absolute URL Full request and response for http:// targets Standard -x http://gate:8080 setup
CONNECT tunnel The same HTTP proxy carrying an https:// target as a blind TCP relay Hostname and port only; the TLS body stays sealed Every time you use an "HTTP proxy" on an HTTPS site
HTTPS proxy A proxy you reach over TLS, so the first hop is encrypted Same as above; the encryption is on the client-to-proxy leg -x https://gate:8443, corporate egress
TLS-terminating proxy A proxy that decrypts by installing its own CA in your trust store Everything, including your HTTPS bodies mitmproxy, Charles, corporate inspection
SOCKS5 Session-layer relay for TCP and UDP, defined in RFC 1928 Host, port, byte counts. No protocol parsing socks5h://gate:1080

"HTTPS proxy" is the overloaded one. Most vendor pages use it to mean "an HTTP proxy that works on HTTPS sites," which describes the CONNECT tunnel in row two, and every HTTP proxy already does that.

One scenario, all five terms

Suppose you're pulling 10,000 product pages from an https:// retailer through a rotating residential pool.

Your client opens a TCP connection to the gateway. If you configured an HTTPS proxy, that connection gets a TLS handshake of its own before anything else happens, which hides your proxy credentials and the target hostname from anyone sniffing your local network.

Your client then sends CONNECT shop.example.com:443. The proxy dials the retailer, replies 200 Connection established, and stops thinking. Your TLS handshake with the retailer runs through it end to end.

At this point the proxy is doing exactly the job a SOCKS5 proxy would do: moving bytes it cannot read. The difference between the two setups has shrunk to the handshake that got you there, plus DNS, which I'll come back to.

What happens on the wire

Three exchanges, and you can watch all of them with curl -v or tcpdump in about five minutes.

1. The plain HTTP proxy request

For an http:// target, your client sends the whole URL on the request line instead of just the path. This is the absolute-form request target, and it's the reason the proxy knows where to forward.

# -v prints the request line curl actually sends to the proxy
curl -v -x http://user:[email protected]:8080 http://httpbin.org/ip

In the verbose output you'll see GET http://httpbin.org/ip HTTP/1.1 rather than GET /ip HTTP/1.1. You'll also see Proxy-Authorization: Basic ..., which is base64, not encryption, and readable by anyone on the path.

How it works in practice: this mode is the only one where the proxy can cache, filter, or rewrite. It also means every header you send is visible at the hop, so a badly configured proxy can add Via or X-Forwarded-For and hand the target your real address.

2. The CONNECT tunnel

Point the same proxy at an https:// URL and your client switches methods. It asks for a tunnel first, then runs TLS through it.

curl -v -x http://user:[email protected]:8080 https://httpbin.org/ip

The trace shows CONNECT httpbin.org:443 HTTP/1.1, then HTTP/1.1 200 Connection established, and only after that does the TLS handshake start. The proxy sees the hostname in the CONNECT line and the byte counts, and nothing else.

How it works in practice: caching and header rewriting stop working here, because the proxy can't read what it's forwarding. If someone offers you an "HTTPS proxy" that filters page content, they're terminating TLS, and you should want to know that before you send credentials through it.

3. The SOCKS5 handshake

SOCKS5 is binary and short. The client greets with a version byte and a list of auth methods, the server picks one, then the client sends a connect request naming the destination.

client -> 05 01 00              # version 5, 1 method, "no auth"
server -> 05 00                 # method accepted
client -> 05 01 00 03 0e ...    # CONNECT, address type 3 (domain name)
server -> 05 00 00 01 ...       # success, bound address follows

Address type 0x03 is the interesting byte: it means the client passed a hostname rather than a resolved IP, so the proxy does the DNS lookup. Type 0x01 means the client already resolved and is sending four octets of IPv4.

How it works in practice: in Python, that one byte is the difference between the two scheme names.

import requests

# socks5h = the "h" ships the hostname to the proxy for resolution
proxy = "socks5h://user:[email protected]:1080"

r = requests.get(
    "https://httpbin.org/ip",
    proxies={"http": proxy, "https": proxy},
    timeout=30,
)
print(r.json())

You need pip install "requests[socks]" for the scheme to register. Drop the h and PySocks resolves locally instead, which changes your exit behavior without changing a single line of visible output.

Where your DNS lookup actually goes

This table is the part I'd tape to the wall. It cuts across all three protocols and it's where silent leaks live.

Setup Who resolves the hostname Leak risk
HTTP proxy, http:// target The proxy (you sent it a full URL) None from DNS
HTTP proxy, https:// target The proxy (hostname rides in CONNECT) None from DNS
socks5:// Your machine Your resolver sees every target
socks5h:// The proxy None from DNS
Browser SOCKS5, remote DNS off Your machine Same leak, invisible in the browser

The asymmetry surprises people: an HTTP proxy always resolves remotely, because the protocol gives it a name rather than an address. SOCKS5 lets you do it either way, and the default in some clients is the wrong way.

Two consequences follow. Your ISP or corporate resolver builds a list of everything you scrape, and geo-sensitive sites resolve to a CDN edge near you rather than near your exit IP, so your results drift from what a real visitor in that country sees.

In Firefox, the toggle is network.proxy.socks_remote_dns, exposed in the connection settings as "Proxy DNS when using SOCKS v5." Verify it rather than assuming. In curl, use socks5h:// or --socks5-hostname; the curl proxy documentation spells out both forms.

How to choose, in four steps

1. Start with the HTTP endpoint

For anything that speaks HTTP, use the HTTP endpoint. Support is universal, authentication works everywhere, and the CONNECT tunnel already gives you end-to-end TLS to the target.

I only reach for SOCKS5 when something forces me to: a client library with no HTTP proxy support, non-web traffic, or a provider whose SOCKS pool behaves differently from its HTTP pool.

2. Match the scheme to your client, then verify

Read your library's proxy semantics before writing config. In requests, the dict key is the destination scheme and the value is the proxy URL, which trips up nearly everyone the first time.

# key = scheme of the site you're fetching
# value = how you reach the proxy
proxies = {
    "http":  "http://user:[email protected]:8080",
    "https": "http://user:[email protected]:8080",  # yes, http://
}

Writing "https": "https://gate:8080" tells urllib3 to run TLS to the proxy itself. If the gateway doesn't speak TLS on that port, you get an SSLError with WRONG_VERSION_NUMBER, and people spend hours blaming their certificates. For a fuller walkthrough of the config, see our guide to using proxies with Python requests.

3. Add encryption yourself where it matters

SOCKS5 has no encryption of its own, and its username/password scheme sends both in cleartext. If your payload is already HTTPS you're fine, because TLS negotiates past the proxy either way. For anything cleartext, wrap it: an SSH tunnel, WireGuard, or a TLS-enabled endpoint on the provider side.

4. Stop before you build a protocol abstraction layer

Two IPs and a retry loop will teach you more than a rotation framework. Get one request working through one endpoint, print the exit IP, then scale the pool. Our curl proxy guide covers the one-liners for all three schemes, and rotating proxies explained covers what to build once a single request is solid.

The three protocols in practice

High-volume HTML scraping

The HTTP endpoint wins here on ergonomics rather than speed. Every scraping library supports it, credentials work, and remote DNS is automatic.

Speed claims about SOCKS5 come from the fact that it parses fewer bytes per connection. On a residential pool where a single request takes 400ms to two seconds, the parsing difference is lost in the noise of the exit node's home broadband. Measure it on your own pool before letting it drive a decision.

Browser automation

Chromium has never supported SOCKS5 username/password authentication. The issue has been open since 2013 and still sits unresolved as Chromium issue 40323993.

What makes it expensive is the failure mode. Chrome strips the credentials, connects unauthenticated, gets rejected, and falls back to a direct connection, so your automation runs happily from your own IP. Playwright inherits the same gap, and its SOCKS5 auth request has been open since 2021.

Use the HTTP endpoint for browser work, or run a local unauthenticated SOCKS5 forwarder that holds the credentials and point Chrome at 127.0.0.1. Our Playwright proxy setup guide has the working configuration.

Traffic that isn't the web

Mail clients, database connections, game protocols, and anything doing UDP fall outside what an HTTP proxy can carry. SOCKS5 handles them because it never looks at the payload.

UDP comes with a caveat: RFC 1928 defines UDP ASSOCIATE, but plenty of commercial gateways implement CONNECT only. Test with your actual traffic rather than trusting a feature table.

Pitfalls worth avoiding

Read the proxies dict as destination-to-proxy

The requests mapping goes destination scheme first, proxy URL second. Getting it backwards produces TLS errors that look like certificate problems and aren't. urllib3 has supported real HTTPS proxies since 1.26, which is why the wrong config now fails loudly instead of silently ignoring you.

Treat SOCKS5 as transport, never as privacy

It moves bytes; it doesn't protect them. Per RFC 1928 and its companion auth spec, the username and password travel in the clear, so anyone on the path between you and the gateway can lift them. Rotate credentials that have crossed an untrusted network.

Check the exit IP, don't assume it

Every silent failure in this article ends the same way: your traffic leaving from your own address. One assertion catches all of them.

import requests

expected_country = "DE"
r = requests.get("https://ipinfo.io/json",
                 proxies={"https": "http://user:[email protected]:8080"},
                 timeout=15)
data = r.json()
assert data["country"] == expected_country, f"leaked via {data['ip']}"

Run it at the start of every job rather than once during setup. A leak that appears on hour six of a crawl is still a leak.

Watch the ports

SOCKS conventionally listens on 1080, HTTP proxies on 8080 or 3128, and TLS proxy endpoints on whatever the provider chose. Pointing a SOCKS client at an HTTP port gives you a hung connection or a garbled reply, because the HTTP server is waiting for text and you sent it 05 01 00.

Where the protocol choice doesn't help at all

Switching from HTTP to SOCKS5 will not fix a block. Anti-bot systems fingerprint your TLS handshake and HTTP/2 settings, and both of those are properties of your client, which the proxy hop doesn't touch.

If you're getting 403s, the protocol is the wrong variable to change. Look at your TLS fingerprint and your header order first.

FAQ

Is SOCKS5 faster than an HTTP proxy?

Marginally, in the sense that it does less parsing per connection. On residential or mobile exits, network latency dominates by an order of magnitude, so the difference rarely shows up in end-to-end timing. Benchmark your own pool before rewriting anything.

Does a SOCKS5 proxy encrypt my traffic?

No. It relays whatever you hand it. If you're requesting an https:// URL, TLS still protects the payload end to end, because that handshake happens between your client and the origin regardless of the hop.

Is an HTTPS proxy more secure than an HTTP proxy?

For the first hop, yes: TLS to the proxy hides your credentials, the CONNECT line, and any cleartext requests from your local network. For the destination it changes nothing, since an https:// target is already encrypted end to end either way.

Can I use SOCKS5 with Chrome or Playwright?

Only without authentication. Chromium ignores credentials in a socks5://user:pass@host:port URL and falls back to a direct connection, which looks like success until you check the exit IP. Use the HTTP endpoint, or front the proxy with a local forwarder that authenticates for you.

Which one do proxy providers actually give me?

Most sell access to a pool and expose it on both an HTTP port and a SOCKS5 port, so the protocol is your choice rather than a product tier. Test both against your target; occasionally the two paths behave differently enough to matter.

Wrapping up

The mental model that survives all of this: an HTTP proxy reads your web traffic, a CONNECT tunnel stops reading it, an HTTPS proxy encrypts the hop that gets you there, and SOCKS5 never read anything to begin with. DNS is the variable that changes underneath all four.

Go run curl -v through your own gateway on both an http:// and an https:// URL and read the request lines. Ten minutes of verbose output will teach you more than any comparison table, including this one.