Introduction
Client ⇄ ServerThe connection starts over the selected transport: plain uses bare X25519, while the other modes use TLS-shaped or real TLS with a hybrid key share.
The full breakdown: the handshake, all six transport modes, cryptography, measured benchmarks and the comparison matrix. For those who want to verify the details.
With a pinned key, the server proves its authenticity before the client sends a password. The order matters; a first TOFU connection must be verified separately.
The connection starts over the selected transport: plain uses bare X25519, while the other modes use TLS-shaped or real TLS with a hybrid key share.
Authenticity is bound to a hash of the whole handshake — any tampering breaks the connection.
The server proves it owns the key; the client checks it against the pinned one — before sending the password.
Over the secure channel — login and password; Argon2id verification and per-profile access.
Every packet is encrypted and sent over the chosen transport — HTTPS, WebSocket or QUIC-shaped UDP.
The mode determines the traffic shape and is configured by a matching pair of profile and client settings. The installer deploys reality-tls by default; the built-in config default is fake-tls. Other modes suit trusted networks, compatibility and fallback channels.
Qeli's flagship mode: the client sends a browser TLS 1.3 handshake (JA4 fingerprint t13d1516h2_8daaf6152771), and the server terminates real TLS 1.3 (realtls), carrying the tunnel inside. On the wire this is genuine TLS 1.3, not a mimicry; inside it carries the qeli tunnel, while trust rests on the pinned server key. It works on Linux, Android, iOS, Windows and macOS through the shared realtls engine.
ClientHello (Chrome JA4) → TLS 1.3 (realtls)
encrypted flight → tunnel inside real TLS
A raw X25519 exchange and bare [len][nonce][ct] records — no TLS wrapper, no extra layers. The fastest and cheapest on CPU mode (≈ as fast as fake-tls). For places where an extra transport layer isn't needed: a trusted network, an internal channel. TCP only.
X25519 exchange → [len][nonce][ct] · no TLS wrapper
The connection opens with a TLS 1.3-shaped handshake: the client sends a ClientHello with a site name (SNI), a hybrid X25519MLKEM768 key share and GREASE values. The TLS extension order is randomized. Data then travels in Application Data records; this is TLS-shaped framing, not real TLS.
ClientHello · SNI · X25519MLKEM768 · GREASE
extension order randomized
data → TLS record 0x17 (application_data)
The entire stream is additionally encrypted with a ChaCha20 stream key over a shared secret (PSK). The start is shaped as a WebSocket Upgrade handshake: the client sends GET … Upgrade: websocket, the server replies 101 Switching Protocols with Sec-WebSocket-Accept. Path, Host, User-Agent and key are randomized.
GET /<rand> HTTP/1.1 · Host/UA/key random
Upgrade: websocket → 101 Switching Protocols
then: ChaCha20 XOR stream
The server cryptographically identifies its own client by a token in the ClientHello session_id. Unrecognised connections are forwarded to the configured host. The token is an AEAD ciphertext (short_id, timestamp) bound to the DH exchange. In reality-tls mode, real TLS 1.3 termination (realtls) is added on top of the proxy layer.
token in session_id → recognized → tunnel
no token → redirect to the target host
Qeli masks a UDP datagram as one strict QUIC v1 Initial shape: byte 0xC3, version 1, a four-byte DCID, empty SCID and token, declared length and a four-byte packet number. This is QUIC-shaped masking, not a full QUIC implementation: there is no QUIC Initial AEAD, header protection, CRYPTO frames or mandatory 1200-byte padding.
[0xC3][version=1][DCID:4][SCID:0][token:0]
[length][packet number:4][qeli payload]
A modern crypto stack: hybrid X25519 + ML-KEM-768 in every mode except plain, ephemeral keys, authenticated encryption and real TLS in reality-tls. Here is what a data-plane packet contains.
This is a data-plane packet. In every mode except plain, keys are derived from hybrid X25519 + ML-KEM-768 through HKDF-SHA256; plain uses classic X25519. ChaCha20-Poly1305 protects the data and Argon2id protects passwords. In reality-tls, the packet also travels inside TLS 1.3 with AES-GCM 128/256.
Server-key protection, access separation, brute-force protection and fault tolerance — all built into the protocol.
Linux and Android group already-ready UDP datagrams into bounded batches of up to 32 through recvmmsg/sendmmsg. No coalescing timer is added; ordering, roaming, pacing, fragmentation and PMTU fallback are preserved.
Median in alternating same-window A/B runs on the two-core lab: +116.5%.
On the same lab and measurement window: +93.9%.
−13.2% on the upload client and −7.9% on the server download worker.
This narrow test validates one optimisation. The full 0.8.0 comparative benchmark with 34 modes remains below with unchanged figures.
The result belongs to the specific two-core lab and is not a promise of identical speed on every VPS, phone or network path. Method and full 0.8.1 release context →
The full run covers 34 modes on one testbed: two Debian VMs with 2 vCPU and 2 GiB RAM, iperf3 3.18, MTU 1400, IPv4 and IPv6. The sections below separate Qeli profile results from comparisons between transports with the same masking level.
Two Debian VMs with 2 vCPU and 2 GiB RAM each, the same network path, iperf3 3.18 and MTU 1400.
Four parallel streams and three repeats. The table uses the median, so one lucky run does not determine the result.
Every mode was measured for upload and download over both address families. The comparison result is the mean of those four directions.
Fully masked modes are compared with each other. Partial and absent masking are shown separately as controls.
Every displayed Qeli 0.8.0 profile ran with mandatory PACKET_MUX_V1. These are medians of three IPv4 TCP P=4 runs; IPv6 results and all 12 profiles are listed in the detailed table.
UDP ceiling is the highest offered rate found with a successful window at no more than 1% loss. This is the four-direction rep1 mean; per-profile pass/n and median loss are available in the full report.
All values are Mbps, with upload / download order in each cell. TCP P=4 is the three-run median; UDP is the observed rep1 ceiling.
| Profile | TCP P=4 · IPv4 | TCP P=4 · IPv6 | UDP ceiling · IPv4 | UDP ceiling · IPv6 |
|---|---|---|---|---|
| tcp-plain-raw + Recordizer | 1705 / 1689 | 1825 / 1807 | 1300 / 1450 | 1350 / 1425 |
| tcp-faketls + Recordizer | 1752 / 1695 | 1823 / 1820 | 1225 / 1400 | 1300 / 1475 |
| tcp-padding + Recordizer | 1751 / 1683 | 1841 / 1799 | 1175 / 1450 | 1325 / 1500 |
| tcp-frag + Recordizer | 1774 / 1684 | 1834 / 1800 | 1350 / 1425 | 1250 / 1500 |
| tcp-obfs + Recordizer | 1256 / 1293 | 1371 / 1386 | 925 / 1200 | 925 / 1200 |
| tcp-reality + Recordizer | 1741 / 1705 | 1834 / 1786 | 1275 / 1400 | 1275 / 1450 |
| tcp-reality-tls + Recordizer | 1212 / 1066 | 1219 / 1074 | 925 / 1125 | 975 / 1200 |
| udp-faketls + Recordizer | 484 / 528 | 458 / 507 | 350 / 450 | 325 / 450 |
| udp-padding + Recordizer | 499 / 513 | 468 / 512 | 375 / 450 | 375 / 500 |
| udp-quic + Recordizer | 491 / 520 | 473 / 506 | 350 / 475 | 325 / 475 |
| tcp-obfs-awg + Recordizer | 1312 / 1300 | 1407 / 1389 | 875 / 1175 | 875 / 1175 |
| udp-faketls-awg + Recordizer | 479 / 509 | 479 / 515 | 375 / 450 | 350 / 475 |
All 12 Qeli profiles used mandatory PACKET_MUX_V1, with runtime confirming PACKET_MUX_V1 active ... policy=required. They therefore belong to the fully masked group. The TCP test was repeated three times; the full report includes pass/n, median loss, CV, CPU, RSS and kernel drops.
How masking is assessed: handshake shape, record sizes and boundaries, timing and batching, plus the response to an active probe. This describes working mechanisms; it is not a promise of being invisible to DPI.
The product aggregate across all 12 Qeli profiles is 1220 Mbps TCP P=4. The dual-stack gate passed in 19 of 19 cases, and the mandatory recordizer runtime marker appeared for all 12 Qeli profiles. Direct-baseline drift after the matrix was +1.48% upload and −1.71% download. CPU and RSS were measured separately for each VM and process set; full tables are in the report.
The primary ranking contains transports that fully reshape recognizable VPN traffic characteristics. Grey bars show two fast unmasked controls, while Hysteria 2 QUIC TLS is labelled as partially masked. Each result is the mean IPv4/IPv6 upload and download throughput from a TCP test with four parallel streams.
Grey bars are unmasked reference controls: WireGuard plain at 3161 Mbps and OpenVPN UDP + DCO at 1900 Mbps. Hysteria 2 QUIC TLS at 1134 Mbps provides partial masking. Among fully masked modes, AmneziaWG full 3.1 reached 2820 Mbps, Qeli fast TCP + Recordizer 1767 Mbps, and the 12-profile Qeli aggregate 1220 Mbps.
| Feature | WireGuard | AmneziaWG | OpenVPN | Shadowsocks | Xray/VLESS | Hysteria 2 | Qeli |
|---|---|---|---|---|---|---|---|
| Real VPN (not a proxy) | yes | yes | yes | proxy | proxy | proxy | yes |
| TCP P=4, Mbps | 3161 plain · no masking 510 wg-obfuscator STUN | 2820 full 3.1 | 1900 UDP + DCO · no masking 453 TCP + Cloak | not measured | 997 REALITY Vision | 1134 QUIC TLS · partial 760 Salamander · masked | 1767 fast TCP 1220 12 profiles |
| Private transport | no | ★★★ | no | ★★★ | ★★★★ | ★★★★ | ★★★★ |
| Multiple transport modes | no | one | no | plugins | ★★★★ | partial | ★★★★ plain / fake-tls / obfs / reality / reality-tls / quic |
| Real TLS | no | no | real TLS | via plugin | TLS + REALITY | under HTTP/3 | yes reality-tls · Chrome JA4 |
| Built-in control panel | no | app | no | no | no | no | yes |
| Brute-force protection | no | no | plugin | no | no | no | yes |
| Server-key pinning | peer key | peer key | certificate | password | yes | certificate | yes |
| Per-profile access separation | no | no | no | no | partial | no | yes |
| Multiple profiles in one service | no | no | no | no | yes | no | yes |
| Runs in the kernel | yes | yes | no | no | no | no | no |
| Independent security audit | ★★★ | ★★ | ★★★ | ★★ | ★★★ | ★★ | no |
| Post-quantum cryptography | no | no | no | no | no | no | yes in every mode except plain |
One settings format for the server, the client and the user list. The client settings are the same connection link and QR code.
# minimal set of settings
[qeli]
server = vpn.example.com:443
proto = tcp
mode = obfs
front = websocket
obfs_key = SHARED-SECRET-KEY
user = alice
pass = ••••••••
# pinned server key
key = 33f399e6…d532450
# one link → QR code → import into the client
qeli://alice:pass@vpn.example.com:443
?proto=tcp
&mode=obfs
&front=websocket
&obfs=SHARED-SECRET-KEY
&sni=www.google.com
&key=33f399e6…d532450
# created in the control panel or with the command:
$ qeli add-client alice --link --host vpn.example.com:443