A side-by-side comparison of VMess, VLESS, Trojan and Shadowsocks across handshake round trips, encryption overhead and mobile battery use, plus a repeatable order for picking one. It is aimed at users who already import subscriptions in v2rayNG or v2rayN and need to choose between several protocol ports on the same server; by the end you can tell which protocol to keep for your current network.
Handshake paths: how many extra round trips each protocol adds
The gap between protocols comes half from the handshake and half from the encryption layer. The handshake decides how many round trips it takes to connect; the encryption layer decides how much CPU and how many bytes each packet costs. VMess and VLESS come from the same Project V family: VMess carries its own authentication and encryption layer, while VLESS hands encryption entirely to outer TLS or REALITY and keeps only a minimal request header of its own.
Trojan takes the camouflage route: authentication data rides in the first chunk of data after the TLS handshake, so the handshake cost is roughly that of an ordinary HTTPS handshake. Shadowsocks works differently: no TLS wrapper, the whole stream is encrypted with AEAD, and the client can send data as soon as it connects.
Put the four protocols in one table and the differences cluster in two columns: round trips and header bytes.
| Protocol | Handshake composition | Extra round trips | Header overhead (order of magnitude) |
|---|---|---|---|
| VMess(AEAD,alterId=0) | TCP + VMess auth header | 0 | about 40–50 bytes |
| VLESS | TCP + minimal request header | 0 | about 20–40 bytes |
| Trojan | TCP + TLS handshake + password check | 1(TLS 1.3)/ 2(TLS 1.2) | about 60 bytes |
| Shadowsocks(AEAD) | TCP + AEAD-encrypted payload | 0 | about 30 bytes |
The extra round trips in the table assume plain TCP, and header overhead excludes the TLS record layer; actual byte counts vary with the address type (domain, IPv4, IPv6). Once VMess or VLESS is wrapped in WebSocket + TLS, add one or two more TLS round trips — which is why, on the same line, VLESS over plain TCP often delivers a first byte before VMess over WebSocket + TLS.
How handshake overhead turns into first-byte latency
The total latency of a request is roughly the link RTT multiplied by the number of round trips, plus server processing time. On a cross-border line with 80 ms one way, a single round trip is about 160 ms; a TLS 1.2 handshake takes one more round trip than TLS 1.3, adding roughly 160 ms to first byte on that same line.
Opening a page is usually not one connection but a dozen or more. Browser connection reuse saves some of them, but every new domain, every subscription update and every request from a separate app can run the handshake again. That is where the differences between protocols get amplified.
VLESS TCP 1 trip → request header sent with the first packet, 1 round trip total
VMess TCP 1 trip → auth header sent with the first packet, 1 round trip total
Trojan TCP 1 trip → TLS 1.3 handshake 1 trip, 2 round trips total
Shadowsocks TCP 1 trip → AEAD payload sent directly, 1 round trip total
Apply that ladder back to the four protocols: VLESS and Shadowsocks pay only the TCP round trip; VMess AEAD also adds just an auth header without an extra round trip; Trojan, and VMess or VLESS wrapped in TLS, pay one or two more. When choosing a protocol, count round trips first and argue about the rest later.
Conclusion: check the TLS version before the protocol name
On the same server, the first-byte gap between VLESS over plain TCP and Trojan comes mainly from the choice of TLS 1.2 versus 1.3; upgrading the server to TLS 1.3 with session resumption pays off more than switching protocols.
Mobile battery: encryption method and connection count
On Android the battery drain is not about the protocol name but about two things: whether the cipher has hardware acceleration, and how many connections are opened per unit of time. Phone SoCs from ARMv8 onward generally include AES instructions, so VMess and Shadowsocks stay light on CPU with aes-128-gcm; only on older ARMv7 devices is the pure-software chacha20-ietf-poly1305 implementation faster.
Connection count ties into Mux multiplexing. The node edit screen in v2rayNG has an "Enable Mux" toggle; with it on, multiple requests share one connection and handshakes drop, which suits messaging apps with frequent small requests. For large file downloads it is better turned off so a single connection does not become the bottleneck.
The trade-offs for these local settings differ with link quality.
Recommended setup: two sets of local settings by link quality
Mobile networks (4G / 5G)
- Prefer VLESS + REALITY or Trojan + TLS nodes
- For VMess and Shadowsocks nodes, set the encryption method to aes-128-gcm
- Turn on Mux to cut handshake count
Fixed broadband (Wi-Fi / wired)
- VLESS over plain TCP and Shadowsocks AEAD can both saturate the bandwidth
- Turn Mux off for heavy downloads
- If you need UDP, confirm UDP forwarding is enabled on the server
The protocol is decided by the server; on the client you can adjust three things: encryption method, Mux and routing mode.
Choosing by scenario: where each of the four combinations fits
A protocol only becomes a usable node in a subscription when paired with a transport. The four combinations below cover most node types you will see.
VLESS + REALITY
RecommendedThe handshake is a single TLS 1.3 exchange, no self-signed certificate is needed, and it resists active probing best; the Xray core supports it natively, with flow set to xtls-rprx-vision.
Best for: daily primary use, high-latency cross-border lines
Trojan + TLS
Traffic looks like ordinary HTTPS, and node parameters are just address, port and password; the prerequisite is a valid certificate on the server.
Best for: self-hosted nodes that already have a domain and certificate
VMess + WebSocket + TLS
Best compatibility, and it can be fronted by a CDN; the cost is an extra WebSocket and TLS layer, and the highest number of handshake round trips.
Best for: older nodes, lines that need CDN relay
Shadowsocks AEAD
Lightest handshake and lowest CPU use, with connection setup costing almost only the TCP round trip; without a TLS shell, the traffic pattern is more visible.
Best for: internal jump hosts, stable dedicated lines
None of the four combinations wins outright: VLESS + REALITY pushes the handshake to a minimum and needs no self-signed certificate; Trojan has the fewest fields to configure; VMess + WebSocket is often the only option when a CDN relay is required; Shadowsocks has the lowest overhead when the line itself is clean.
Conclusion: rule out link problems before choosing a protocol
Once the handshake count is fixed, throughput differences between the four protocols on the same server come mainly from encryption overhead and stay within about 10%; moving to a line with lower packet loss, by contrast, often improves first-byte latency by more than 40%.
Client checklist: protocol fields reference table
Protocol choice comes down to checking a few fields in the client. In v2rayNG, long-press a node and open Edit to see alias, address, port, user ID, alterId, encryption method, flow, transport and camouflage domain; in v2rayN, select a node under the Server menu and click Edit, where the fields map one to one with Android.
Different protocols use different fields; the table below works as a checklist.
| Field | VMess | VLESS | Trojan | Shadowsocks |
|---|---|---|---|---|
| User ID / password | UUID | UUID | Password | Password |
| alterId | Set to 0 in AEAD mode | Not applicable | Not applicable | Not applicable |
| Encryption method | auto / aes-128-gcm | Fixed at none | Not applicable | aes-128-gcm / chacha20-ietf-poly1305 |
| Flow control (flow) | Not applicable | xtls-rprx-vision | Not applicable | Not applicable |
| Transport | tcp / ws / grpc | tcp / ws / grpc | tcp | tcp |
Changing the encryption method of a VLESS node to aes-128-gcm. The VLESS protocol requires this field to be none; any other value is rejected by the server during the handshake. If you want stronger encryption, choose TLS or REALITY on the outer layer instead.
On ports: v2rayN opens 10808 (SOCKS) and 10809 (HTTP) locally by default, and v2rayNG uses the same 10808 for its local SOCKS port. These two ports only serve apps on the same machine and are unrelated to port 443 or 8443 on the node server — do not mix them up when troubleshooting.
After changing parameters, go back to the node list, run a real connection latency test first, then open a page to confirm the proxy is working; if the test looks fine but pages will not load, check whether the routing mode or per-app proxy is excluding the target app.
Common questions
The same node is much slower after switching protocols — is that the protocol's fault?
Check two things first: whether the server uses TLS 1.2 or 1.3, and whether the node is wrapped in WebSocket. A protocol header is only a few dozen bytes and cannot account for a multiple-fold gap; the difference usually comes from those two items and from the line between the server and its exit.
Which protocol uses less battery on an Android phone?
The encryption method matters more than the protocol name. With aes-128-gcm on VMess or Shadowsocks, ARMv8 devices use AES hardware acceleration and stay light on CPU; turning on Mux further reduces handshakes. On the same phone, the battery difference between protocols is usually smaller than the effect of screen brightness.
Shadowsocks has no TLS — is it still usable?
It depends on the link. On an internal jump host or a stable dedicated line, Shadowsocks has the lightest handshake and the lowest latency; over a direct public-internet connection, the absence of a TLS shell makes the traffic pattern more visible and throttling more likely, so VLESS or Trojan is the better choice there.
A subscription offers several protocol ports on the same server — which one should I keep?
Run a real connection latency test on every port first and keep the one with the fastest first byte as your primary. Different protocol ports on the same server run on the same machine, so the gap usually comes from the handshake; prefer the VLESS or Trojan port with TLS 1.3, and leave the rest in place for quick switching.