← Back to library
Protocols Theory

Hysteria2 and QUIC: upsides and gotchas

Hysteria2 is the second transport I keep on almost every node. It's about something different from Reality: not about camouflage, but about keeping the channel alive on packet loss and on mobile, where TCP suffocates. I break down what makes it fast and where the gotchas are. Standing it up and wiring it to the panel — in the paired practice piece.

Go to practice

This material is about engineering your own infrastructure and is educational in nature. Complying with the laws of your own jurisdiction is your responsibility.

Why have a second transport on UDP at all

Reality over TCP is an excellent primary channel, but TCP has an innate weakness: it degrades on bad networks. As soon as packet loss shows up (mobile internet, a congested channel at prime time, weak Wi-Fi), TCP starts to throttle — its algorithm treats loss as a congestion signal and drops the speed. On top of that, in some networks it's specifically the TCP profile that gets choked, while UDP still flies.

Hysteria2 is the answer to both problems. It's a protocol over QUIC (a UDP-based transport), tuned precisely to hold speed where TCP gives up. I keep it as a second transport on the node exactly as a "last-resort button": evening, mobile, TCP has stalled — you switch to Hysteria, and it often still moves.

What makes it fast

The key phrase is aggressive congestion control (BBR). Ordinary TCP panics on packet loss and cuts speed, assuming the channel is saturated. BBR works differently: it measures the channel's actual throughput and latency and holds speed based on them, rather than getting scared by every loss. On lossy channels this makes a huge difference — where TCP would sag by half, Hysteria keeps pulling at nearly full rate.

Plus, QUIC over UDP itself doesn't suffer from "head-of-line blocking," which plagues TCP: losing a single packet doesn't stall the whole stream. Altogether you get a protocol that noticeably beats TCP on bad networks and runs even with it on good ones. Hence its niche: mobile networks, packet loss, congested channels, prime time.

On camouflage it's middling: from the outside it's TLS-over-QUIC (ALPN h3), meaning it looks like HTTP/3 traffic. It's not Reality-level stealth, but it's not a bare proxy either — it gets through most networks.

Gotcha one: UDP gets cut

The main trap you need to know about upfront. Hysteria is UDP, and in some networks UDP is cut entirely or partially. A provider can choke UDP on port 443, a firewall may not let it through, a mobile carrier can rate-limit it. So Hysteria isn't a replacement for TCP-Reality but a supplement: where UDP passes, it saves the day; where UDP is closed, the primary TCP channel works. You need to keep both, and hand the client a subscription that has both, so there's auto-failover.

A practical point: for Hysteria you need to explicitly open UDP/443 in the firewall and make sure the node's provider doesn't cut it. Forget to open UDP and the protocol simply won't come up, and you'll be looking for the cause in the wrong place.

Gotcha two: the panel may not count traffic

This is a trap that can easily cost you a day if you don't know it. In the pairing with the Remnawave panel there's a subtlety with the Xray core version. On older core builds the panel doesn't see the Hysteria user online and doesn't count their traffic — that is, the protocol works, the client is connected and downloading, but in the panel it reads zero: no online status, no consumption. For a paid service this is critical — you don't see usage and can't apply limits.

The cause is a bug in specific core versions, fixed in fresher ones. It's cured by swapping the Xray core on the node for a new enough version. This isn't "Hysteria configuration" but a mandatory accompanying step, without which Hysteria accounting doesn't work. In the practice piece I show exactly how to swap the core.

Gotcha three: the client has to get the config right

Another delivery subtlety. Hysteria isn't an Xray protocol in the usual sense, and some clients show it in the subscription only if the subscription is served in JSON format rather than a base64 list of links. If you don't do this, the client sees VLESS hosts but Hysteria won't be in the list — even though everything is correctly up on the server. That is, the protocol can be configured perfectly but fail to reach the client because of the subscription format. This is also in the practice piece — there's a specific toggle in the panel settings.

How to make the decision

Let me boil it down to an operator's checklist:

  • Put Hysteria2 as a second transport on almost every node — it's cheap insurance against bad networks and TCP choking.
  • Don't make it the only one — UDP gets cut, you need TCP-Reality as the foundation.
  • Check the core version on the node, or traffic won't get counted.
  • Serve the subscription as JSON, or the client won't see Hysteria.

Reality keeps the node alive against blocks, Hysteria keeps the channel fast on bad networks — these are different jobs, and together they cover far more scenarios than each does alone. How to stand up Hysteria2, issue a cert, mount it into the node container, and wire it to the panel — in the paired practice piece "Hysteria2: standing it up and wiring it to the panel."

Next guide Hysteria2: standing it up and wiring it to the panel → Article unclear or something off? Message me and I will help or fix it. @notrealvpn →
This material is educational and covers network-infrastructure engineering. You are responsible for complying with the laws of your jurisdiction.