Skip to content
Published on

QUIC은 왜 빠른 인터넷에서 느려지는가 — 수신 측 CPU와 아직 오지 않은 커널 QUIC

공유하기
Authors

들어가며 — 먼저, QUIC이 실제로 이긴 곳

QUIC 이야기는 대개 "TCP보다 빠르다"로 시작해서 "그래서 HTTP/3를 켜라"로 끝납니다. 이 글은 그 반대편, 그러니까 QUIC이 지는 조건과 그 이유를 다룹니다. 다만 공정하려면 이긴 곳부터 확인하고 시작해야 합니다. 그리고 이건 인상이 아니라 측정된 수치가 있습니다.

구글이 SIGCOMM 2017에 낸 The QUIC Transport Protocol: Design and Internet-Scale Deployment는 QUIC 실험군과 TLS/TCP 대조군을 같은 크기로 놓고 비교한 결과를 표로 싣고 있습니다. 논문 Table 1과 Table 2의 평균값을 옮기면 이렇습니다.

검색 지연(Search Latency) 감소율 — 평균
  데스크톱  8.0%      모바일  3.6%

영상 지연(Video Latency) 감소율 — 평균
  데스크톱  8.0%      모바일  5.3%

영상 리버퍼율(Video Rebuffer Rate) 감소율 — 평균
  데스크톱 18.0%      모바일 15.3%

이 이득이 어디서 왔는지도 논문이 짚습니다. QUIC 핸드셰이크의 약 88%가 0-RTT로 끝나고, 그 결과 핸드셰이크 지연이 RTT에 거의 무감각해집니다. TCP/TLS의 평균 핸드셰이크 지연이 RTT에 비례해 선형으로 올라가는 동안 QUIC은 거의 평평합니다. 여기에 손실 복구 개선이 얹혀서, 논문 표현으로는 손실에 대한 전반적 저항성이 높아지고 짧은 연결의 지연이 낮아집니다.

세 가지 단서를 함께 기억해 두는 게 좋습니다. 첫째, 이건 구글이 자기 트래픽을 자기가 측정한 값입니다(벤더 자체 측정). 측정 대상 모집단은 Chrome과 YouTube를 쓰는 구글 사용자이고, 서버는 구글 서버입니다. 당신의 트래픽 믹스가 아닙니다. 둘째, 이건 IETF QUIC이 아니라 그 전신인 gQUIC입니다. 셋째, 논문 스스로 이득의 한계를 인정합니다 — 핸드셰이크 지연이 검색 지연과 영상 지연에서 차지하는 비중은 20%에 한참 못 미치므로, 핸드셰이크 지연을 완전히 없애도 전체 지연 감소는 작은 비율에 그친다는 것입니다.

그리고 같은 Table 1에는 자주 인용되지 않는 칸이 있습니다. 모바일 검색의 1퍼센타일과 5퍼센타일 감소율이 각각 -0.6%, -0.3%입니다. 음수는 QUIC이 더 느렸다는 뜻입니다. 즉 이미 가장 빠른 조건에 있던 모바일 사용자에게는, 구글의 자체 측정에서조차 QUIC이 아주 약간 손해였습니다. 이득은 꼬리에 몰려 있습니다 — 데스크톱 검색 99퍼센타일에서는 16.7% 감소입니다. QUIC은 평균을 조금, 최악을 크게 개선하는 프로토콜입니다.

배포 수준도 이제 실험이 아닙니다. W3Techs의 2026년 7월 집계 기준 HTTP/3는 전체 웹사이트의 39.9%가 사용합니다(W3Techs 자체 서베이 모집단 기준).

그런데 링크가 빨라지면 뒤집힌다

문제는 이런 측정이 어떤 조건에서 이뤄졌느냐입니다. WWW 2024 논문은 기존 QUIC 측정 연구들을 훑은 뒤 이렇게 정리합니다 — 그 결과는 성능 향상과 (경우에 따라) 저하가 섞여 있고, 그중 다수가 낮은 처리량(low-throughput) 사례에 집중돼 있다고요. 링크가 빨라지면 어떻게 될까요.

미시간대 등 연구진의 QUIC is not Quick Enough over Fast Internet(Zhang 등, WWW 2024)이 이 질문을 정면으로 팠습니다. 결론은 제목 그대로입니다. 논문 초록의 문장을 옮기면, 빠른 인터넷에서 UDP+QUIC+HTTP/3 스택은 TCP+TLS+HTTP/2 대비 최대 45.2%의 데이터 전송률 저하를 겪고, 그 격차는 기저 대역폭이 커질수록 벌어집니다.

숫자를 조건과 함께 정확히 붙여야 합니다.

  • 커맨드라인 클라이언트(cURL, quic_client)로 비교하면, 대역폭이 낮을 때(대략 600 Mbps 미만)는 QUIC과 HTTP/2가 비슷한 성능을 냅니다. 그 위로 올라가면 QUIC이 처지기 시작해 최대 15.7%까지 벌어집니다.
  • 브라우저에서는 격차가 더 큽니다. Chrome 기준으로 대역폭이 약 500 Mbps를 넘으면 QUIC이 뒤처지기 시작하고, 1 Gbps에 이르면 45.2% 느려집니다.
  • 약한 클라이언트일수록 더 벌어집니다.

논문 Table 1의 1 GB 파일 다운로드 예비 실험이 그림을 잘 보여 줍니다(10회 평균).

                       다운로드 시간(s)        CPU 사용률(%)
테스트베드            HTTP/2   HTTP/3        HTTP/2   HTTP/3
데스크톱, 이더넷        9.32    18.60(+99%)    77.5     96.9
Pixel 5, low-band 5G   37.11    78.65(+112%)  121.55   161.77
Pixel 5, mmWave 5G     30.10    63.20(+110%)  128.43   165.20

주의할 점 — 데스크톱 CPU 수치는 브라우저의 네트워크 서비스에서 잰 값이고, 스마트폰 수치는 브라우저 프로세스 전체입니다. 100%를 넘는 건 멀티코어를 썼다는 뜻입니다. 즉 두 행을 직접 비교하면 안 됩니다.

영향은 벌크 전송에만 머물지 않습니다. DASH 영상 전달에서 최대 9.8%의 비트레이트 저하가 나타났고, 100개 대표 사이트 평균 페이지 로드 시간은 3.0% 길어졌습니다(다만 꼬리에서는 50%를 넘는 격차가 있습니다). 여기서 논문의 관찰이 날카롭습니다 — 이 저하는 4G에서는 숨어 있다가 5G에서 드러납니다. 링크가 느리면 병목이 링크라서 QUIC의 비용이 보이지 않는 것뿐입니다.

범인 찾기 — 후보를 하나씩 지운다

여기서부터가 이 논문의 진짜 기여입니다. 연구진은 통제 실험으로 유력한 용의자들을 하나씩 지웁니다.

UDP 자체가 느린가? 아닙니다. 같은 네트워크 설정에서 iPerf로 재 보니 UDP와 TCP 모두 1 Gbps 링크를 꽉 채웁니다 — UDP 958 Mbps, TCP 944 Mbps. 오히려 UDP가 약간 높습니다. 커널 UDP 데이터 경로는 무죄입니다.

서버 소프트웨어 탓인가? 아닙니다. Nginx-quic으로 바꿔도 HTTP/2는 비슷했고 QUIC은 오히려 18% 더 느렸습니다.

HTTP 문법? 암호화? 파라미터 튜닝? 클라이언트 OS? 전부 아닙니다. HTTP/3는 HTTP/2와 사실상 동일한 문법 구조이고, 두 스택 모두 같은 TLS_AES_128_GCM_SHA256 사이퍼를 썼으며, 페이싱과 PMTU 튜닝은 눈에 띄는 개선을 주지 못했고, macOS와 Windows 수신자에서도 같은 결과가 나왔습니다.

남은 곳은 수신 측 처리입니다. 두 가지 관찰이 이를 가리킵니다. 첫째, QUIC을 쓰는 클라이언트가 받는 패킷 수가 HTTP/2 때보다 훨씬 많습니다. 둘째, QUIC이 고속으로 받을 때 데이터 패킷과 그에 대응하는 ACK 사이 지연이 큽니다. 평균 패킷 RTT를 재 보면 HTTP/2가 1.9ms인데 QUIC은 16.2ms로 치솟습니다. 두 머신 사이 ping RTT는 0.23ms에 불과하니, 지연의 대부분은 회선이 아니라 엔드포인트의 패킷 처리에서 나온 것입니다.

논문은 이 지점을 자기 기여로 명시합니다 — 유저스페이스 구현이 일반적으로 성능을 깎는다는 건 알려져 있었고 송신 측 최적화 노력도 있었지만, 수신 측이 더 유력한 병목임을 짚은 건 자기들이 처음이라고요. 이유도 답니다. 서버는 보통 데스크톱·노트북·휴대폰보다 강하니까요. 우리가 습관적으로 "QUIC은 서버 CPU를 먹는다"고 말할 때, 정작 아픈 쪽은 사용자 손에 있는 기기라는 뜻입니다.

왜 수신이 비싼가 — GRO와 유저스페이스 ACK

perf로 커널과 Chromium을 프로파일링한 결과, 두 가지 근본 원인이 나옵니다.

첫째, 커널이 패킷을 너무 많이 만진다. 1 GB 파일 한 번 받는 동안 netif_receive_skb 호출이 QUIC에서 231K회, HTTP/2에서는 15K회였습니다. 15배 차이입니다. do_syscall_64도 17K 대 4K로 벌어집니다. 이유는 단순합니다 — TCP는 GRO(Generic Receive Offload)로 여러 세그먼트를 뭉쳐서 위로 올리는데, 논문이 조사한 QUIC 구현 중 UDP GRO를 쓰는 게 하나도 없었습니다.

논문 Table 3이 이걸 못 박습니다.

설정            보낸 패킷   받은 패킷   시간(s)
QUIC (offload on)    743K       743K     18.60
QUIC (offload off)   744K       744K     18.82
HTTP/2 (offload on)   19K        53K      9.36
HTTP/2 (offload off) 744K       744K     10.84

읽는 법: HTTP/2는 오프로드를 켜면 커널이 만지는 패킷이 744K에서 53K로 줄고 시간도 10.84초에서 9.36초로 떨어집니다. QUIC은 켜나 끄나 743K/744K로 똑같고 시간도 18.60초 대 18.82초로 차이가 없습니다. QUIC은 GRO/GSO의 혜택을 전혀 못 받고 있습니다.

그런데 왜 그냥 켜면 안 될까요. 논문이 구조적 이유를 셋 듭니다. TCP는 바이트 스트림 모델이라 페이로드를 자유롭게 재패킷화할 수 있지만, UDP의 오프로드 로직은 패킷 경계를 보존해야 합니다. 그래서 기존 UDP GSO/GRO는 길이가 동일한 UDP 패킷 열만 오프로드할 수 있습니다. 그런데 QUIC은 태생이 멀티플렉싱이라 서로 다른 스트림의 프레임 크기가 제각각이고 암호화 후에 다중화됩니다. 길이가 들쭉날쭉한 데이터그램 열은 기존 GSO/GRO로 처리가 안 됩니다. 게다가 UDP 데이터그램을 무작정 뭉쳐 한 버스트로 쏘면 혼잡 손실과 공정성 문제가 생기고, QUIC 변종이 다양해서 NIC 하드웨어에 오프로드 로직을 넣기도 복잡합니다.

둘째, ACK를 유저스페이스에서 만든다. Chromium 네트워킹 스택의 시간 분해가 Table 4입니다.

Chromium 네트워킹 스택 단계          QUIC(8.5s)   HTTP/2(4.1s)
소켓에서 UDP/TCP 패킷 읽기             0.248s        0.037s
UDP/TCP 패킷에서 페이로드 추출         0.310s        0.084s
QUIC/TLS 암호화 패킷 복호화            0.660s        0.814s
복호화된 QUIC/HTTP2 프레임 파싱        3.468s        3.182s
QUIC 응답(ACK 등) 생성                 2.972s          --
기타                                   0.859s        0.001s

이 표에서 두 가지를 읽어야 합니다.

하나는 ACK 생성에만 2.972초가 통째로 들어간다는 것입니다. HTTP/2 열에는 이 항목이 아예 없습니다 — TCP의 ACK는 커널이 만들고, 지연 ACK(delayed ACK)와 수신 오프로드 같은 최적화 덕에 훨씬 드물고 효율적으로 나갑니다. QUIC은 이 일을 유저스페이스에서, 패킷마다, 그것도 지연 ACK 같은 최적화 없이 합니다. 전체 다운로드 20.6초 중 QuicChromiumPacketReader가 8.7초를 먹고, 그중 3.0초가 응답 생성입니다.

놀라운 부분 — 암호화는 범인이 아니다

위 표를 다시 보십시오. 복호화 단계에서 QUIC은 0.660초, HTTP/2는 0.814초입니다. QUIC이 오히려 빠릅니다.

"QUIC이 느린 건 암호화 때문"이라는 흔한 설명은, 적어도 이 측정에서는 사실이 아닙니다. QUIC은 TLS 1.3을, HTTP/2는 TLS 1.2를 썼고 사이퍼는 동일했으며, 연구진은 다른 사이퍼 스위트로도 벤치마크했지만 성능에 유의미한 영향이 없었다고 적었습니다. 비용은 암호 연산이 아니라 패킷을 너무 많이, 너무 자주, 유저·커널 경계를 넘나들며 만지는 데 있습니다.

이 오해는 꽤 널리 퍼져 있어서 짚어 둘 가치가 있습니다. 커널 우회니 하드웨어 암호 가속이니를 검토하기 전에, 당신의 병목이 정말 AES인지부터 프로파일링해야 합니다.

다만 대칭 암호가 영원히 무죄인 건 아닙니다 — 뒤에 나오지만, 송신 경로를 충분히 최적화하고 나면 그때는 암호가 올라옵니다. 순서의 문제입니다.

송신 측 이야기 — 구글이 2배를 깎아 온 과정

수신 측이 새 발견이라면, 송신 측은 오래된 전쟁터입니다. 구글의 Ian Swett이 SIGCOMM EPIQ 2020에서 발표한 QUIC CPU Performance 슬라이드는 이 싸움의 실측 기록입니다. 부제가 정직합니다 — "HTTP/3가 HTTP/2와 HTTP 1.1만큼 효율적일 수 있는가?"

출발점: 2017년 1월 기준 QUIC의 CPU는 HTTPS 1.1의 2배였습니다. 초기 구현은 3.5배였고, 뻔한 수정(비싼 함수 중복 호출 제거, 데이터 경로에서 할당 제거, 복사 최소화, 워크로드 특화 자료구조)으로 2배까지 내려온 상태였습니다.

병목의 위치도 명확합니다. 슬라이드에 따르면 UDP 전송이 이 워크로드 CPU의 25%를 차지하고, 일부 환경과 벤치마크에서는 50%를 넘습니다. 리눅스에서 UDP sendmsg는 TCP 대비 최대 3.5배의 cycle/byte를 씁니다.

그 뒤 적용한 최적화와 각각의 실측 효과입니다(모두 구글 자체 측정).

UDP GSO                      TCP GSO보다 7% 빠름
UDP GSO + 하드웨어 오프로드   추가로 2-3배
  누적 가속                  이상적으로 ~10배, 통상 5배
  => 최악 50% CPU가 5%로, 전체적으로 2배 개선
UDP GRO (패치)               수신 CPU 35% 개선
패킷당 STREAM 프레임 1개 최적화   단독으로 5% 절감
ACK 적게 보내기              25% 절감
  - Quicly 벤치마크에서 TCP와 동등해지는 데 결정적
FDO + ThinLTO                15% CPU 절감

여기서 두 가지가 눈에 띕니다.

첫째, ACK를 줄이는 것만으로 25% 절감이고, 슬라이드는 이게 Quicly 벤치마크에서 TCP와 동등해지는 데 결정적이었다고 적습니다. WWW 2024 논문이 수신 측에서 발견한 ACK 병목과 정확히 같은 곳을 가리킵니다. 송신자든 수신자든 QUIC의 ACK는 비쌉니다.

둘째, 송신을 충분히 빠르게 만들고 나면 대칭 암호가 CPU의 약 30%를 차지하게 됩니다. 그리고 IETF QUIC은 헤더 보호(header protection) 때문에 2패스 암호화가 필요한데, 슬라이드 표현으로는 작은 암호 연산이 벌크 암호화보다 훨씬 비쌉니다. 프라이버시를 위해 CPU를 지불하는 설계상의 거래입니다.

슬라이드의 전망도 조건부입니다 — 대칭 암호 오프로드가 있으면 QUIC이 kTLS만큼 빨라져야 한다고 하면서, 동시에 열린 질문을 남깁니다. "QUIC 오프로드가 그만한 가치가 있는가? TSO는 특히 낮은 대역폭에서 효과가 엇갈린다." 2020년 발표라는 점도 감안해서 읽어야 합니다.

2026년의 시도 — QUIC을 커널로

여기까지 오면 자연스러운 질문이 나옵니다. 문제가 유저스페이스에서 패킷을 하나씩 만지는 것이라면, 그냥 커널에 넣으면 되지 않나?

그게 지금 진행 중인 일입니다. Xin Long이 리눅스 커널에 QUIC을 구현하는 패치 시리즈를 올리고 있습니다. LWN이 2025년 7월 22일에 QUIC for the kernel로 정리했고, 이후 net: introduce QUIC infrastructure and core subcomponents로 v2가 올라왔습니다 — 15개 패치, 9,081줄 추가, 5부작 중 1~2부에 해당하며 EXPERIMENTAL로 표시돼 있습니다.

설계는 lxin/quic 저장소에 정리돼 있습니다. 핵심은 핸드셰이크만 유저스페이스에 남기고 나머지 전부를 커널에 넣는 것입니다.

  • 유저스페이스: 원시 TLS 핸드셰이크 메시지의 처리와 생성만. GnuTLS 같은 TLS 라이브러리가 담당하고, 커널과는 sendmsg/recvmsg로 메시지를 주고받으며 암호 정보는 cmsg로 전달합니다.
  • 커널: 그 외 QUIC 프로토콜 전체. ULP 계층을 쓰는 대신 IPPROTO_QUIC 타입 소켓을 만들고(IPPROTO_MPTCP와 비슷한 방식), UDP 터널 위에서 동작합니다.
  • 커널 소비자: 기존 net/handshake 넷링크로 커널에서 유저스페이스로 핸드셰이크를 요청합니다.

동기는 성능만이 아닙니다. LWN이 짚은 두 가지가 있습니다. 하나는 하드웨어 프로토콜 오프로드를 쓸 수 있게 하는 것 — 앞서 본 GSO/GRO와 암호 오프로드 이야기가 여기서 이어집니다. 다른 하나는 커널 소비자입니다. Samba 서버·클라이언트에 QUIC 지원을 추가하는 풀 리퀘스트가 열려 있고, 커널 내 SMB와 NFS 파일시스템에도 그 지원을 넣으려는 관심이 있습니다. 브라우저는 유저스페이스 QUIC 라이브러리를 링크하면 그만이지만, 커널 NFS 클라이언트는 그럴 수가 없습니다.

커널에 넣으면 빨라지는가 — 자체 벤치마크를 정직하게 읽기

그래서 실제로 빨라졌을까요. lxin/quic 저장소의 README는 100G 물리 NIC에서 잰 iperf 수치를 공개합니다. 이건 프로젝트 자체 측정이고, 합성 벤치마크이며, 실제 워크로드가 아닙니다.

먼저 커널 QUIC 대 kTLS입니다.

UNIT        size:1024      size:4096      size:16384     size:65536
Gbits/sec   QUIC | kTLS    QUIC | kTLS    QUIC | kTLS    QUIC | kTLS
--------------------------------------------------------------------
mtu:1500    1.67 | 2.16    3.04 | 5.04    3.49 | 7.84    3.83 | 7.95
no GSO           | 1.73         | 3.12         | 4.05         | 4.28
--------------------------------------------------------------------
mtu:9000    2.17 | 2.41    5.47 | 6.19    6.45 | 8.66    7.48 | 8.90
no GSO           | 2.30         | 5.69         | 8.66         | 8.82

표면적으로는 참담합니다. MTU 1500, 64KB 메시지에서 커널 QUIC은 3.83 Gbps인데 kTLS는 7.95 Gbps — 두 배 넘게 집니다. 커널에 넣었는데도 집니다.

그런데 no GSO 행을 보십시오. TCP GSO를 끈 kTLS는 같은 조건에서 4.28 Gbps로 떨어집니다. 커널 QUIC의 3.83과 거의 붙습니다. MTU 9000에서는 더 선명합니다 — kTLS가 8.90에서 GSO를 끄면 8.82로 별로 안 떨어지고, QUIC은 7.48로 이미 근접해 있습니다.

커널 QUIC과 kTLS의 격차는 대부분 GSO입니다. README도 이걸 명시합니다 — TCP GSO는 MTU 1500과 큰 메시지에서 TCP와 kTLS 성능에 크게 기여하며, TCP GSO를 끄고 나면 남는 작은 격차의 원인은 셋이라고요.

  • QUIC은 TX 경로에 복사가 하나 더 있다.
  • QUIC은 헤더 보호를 위한 암호화가 하나 더 있다.
  • QUIC은 스트림 DATA의 헤더가 더 길다.

암호화를 끄고 TCP와 붙인 표도 같은 이야기를 합니다.

UNIT        size:1024      size:4096      size:16384     size:65536
Gbits/sec   QUIC | TCP     QUIC | TCP     QUIC | TCP     QUIC | TCP
--------------------------------------------------------------------
mtu:1500    2.17 | 2.49    3.59 | 8.36    6.09 | 15.1    6.92 | 16.2
no GSO           | 2.50         | 4.12         | 4.86         | 5.04
--------------------------------------------------------------------
mtu:9000    2.47 | 2.54    7.66 | 7.97    14.7 | 20.3    19.1 | 31.3
no GSO           | 2.51         | 8.34         | 18.3         | 22.3

MTU 1500, 64KB에서 TCP는 16.2 Gbps로 압도하지만, GSO를 끄면 5.04로 주저앉습니다. 같은 칸의 QUIC은 6.92입니다 — GSO 없는 TCP보다 커널 QUIC이 빠릅니다.

여기서 얻을 결론은 "커널이 답이다"가 아닙니다. 오프로드가 답이고, 커널에 들어가는 건 오프로드를 쓸 자격을 얻는 일이라는 것입니다. TCP가 빠른 건 커널에 있어서가 아니라 30년치 오프로드 생태계(TSO/GSO/GRO, NIC 하드웨어 지원)를 등에 업고 있어서입니다. QUIC을 커널에 넣는 건 그 생태계에 줄을 서는 첫걸음이지, 도착이 아닙니다.

그런데 아직 메인라인에 없다

가장 중요한 사실을 분명히 해 둡니다. LWN은 2025년 7월 기사에서 "메인라인에서 보게 되리라 기대하기는 아무리 빨라도 2026년 중 어느 시점 이전에는 어렵다"고 적었습니다.

오늘(2026년 7월 16일) 기준으로 직접 확인해 봤습니다. 커널 트리에 net/quic 디렉터리가 있는지 보면 됩니다.

# 메인라인 (torvalds/linux)
curl -s -o /dev/null -w "%{http_code}\n" \
  "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/quic"
# => 404

# net-next (다음 머지 윈도우 대상 브랜치)
curl -s -o /dev/null -w "%{http_code}\n" \
  "https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/quic"
# => 404

# 대조군: 이미 머지된 net/mptcp
curl -s -o /dev/null -w "%{http_code}\n" \
  "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/mptcp"
# => 200

메인라인에도, net-next에도 없습니다. 대조군인 net/mptcp가 200을 돌려주니 URL 패턴이 틀린 것도 아닙니다. 리눅스 7.0이 2026년 4월에 나온 지금까지도 커널 QUIC은 밖에 있습니다. 쓰고 싶으면 out-of-tree 모듈을 직접 빌드해야 하고, 저장소는 여전히 EXPERIMENTAL을 달고 있으며, 5부작 중 1~2부만 올라간 상태입니다.

LWN이 비교 대상으로 든 사례가 시사적입니다 — Homa 프로토콜은 9개월간 11번 리비전을 돌고도 머지되지 않았습니다. 커널 네트워킹 서브시스템에 새 프로토콜을 넣는 일은 원래 이렇게 느립니다. "곧 커널 QUIC이 나오니 기다리자"는 계획이 될 수 없습니다.

그 45.2%는 아직 유효한가

정직하게 짚을 게 하나 더 있습니다. WWW 2024 논문은 Chromium v102로 측정했습니다. 2022년 빌드입니다. 구현은 그동안 움직였습니다.

논문의 권고 목록 중 하나가 "Chromium이 지금은 recvmsg로 UDP 패킷을 하나씩 읽는데, recvmmsg로 여러 개를 한 시스템 콜에 읽으면 수신 성능이 개선될 수 있다"였습니다. 오늘 Chromium 소스를 열어 보면 net/socket/udp_socket_posix.h에 recvmmsg를 지원하는 플랫폼(Linux, ChromeOS, Android)에서는 그걸 쓴다는 주석이 있습니다. 권고 중 일부는 반영된 셈입니다.

반면 같은 파일과 net/socket/udp_socket_posix.cc를 훑어보면 UDP_GRO를 켜는 코드는 눈에 띄지 않았습니다. 이건 제가 특정 시점에 특정 파일 두 개를 확인한 결과일 뿐이고, Chromium에는 소켓 경로가 여럿이므로 단정할 근거로는 약합니다 — 다만 직접 확인해 볼 수 있는 지점이라 남겨 둡니다.

그러니 45.2%라는 숫자를 오늘의 Chrome에 그대로 붙이지 마십시오. 그 숫자가 말해 주는 건 정확한 배율이 아니라 메커니즘입니다. 유저스페이스 트랜스포트는 커널이 대신 해 주던 일(패킷 병합, ACK 생성, 지연 ACK)을 스스로 해야 하고, 링크가 빨라져 병목이 회선에서 CPU로 옮겨가는 순간 그 비용이 드러난다는 것 — 이 메커니즘은 구현이 바뀌어도 남습니다. 배율은 당신이 당신 환경에서 다시 재야 합니다.

그래서 언제 쓰고, 언제 쓰지 말아야 하나

지금까지의 1차 자료를 종합하면 판단 기준이 꽤 선명하게 나옵니다.

QUIC/HTTP3가 값을 하는 경우

  • 클라이언트가 손실이 있고 RTT가 긴 네트워크에 있다. 모바일, 원거리, 불안정한 무선. 구글 측정에서 이득이 꼬리(99퍼센타일)에 몰려 있던 이유가 이것입니다.
  • 연결이 짧고 많다. 0-RTT/1-RTT 핸드셰이크 이득이 상대적으로 커집니다.
  • 커넥션 마이그레이션이 실제로 필요하다. 셀룰러와 와이파이를 오가는 클라이언트.
  • 리버퍼처럼 최악 구간이 사용자 경험을 지배하는 지표를 개선하고 싶다.

과잉이거나 손해인 경우

  • 링크가 빠르고 손실이 없다. 데이터센터 내부, 기가비트 유선. WWW 2024 논문의 조건이 정확히 여기입니다. 회선이 병목이 아니게 되는 순간 QUIC의 CPU 비용만 남습니다.
  • 대용량 벌크 전송이 주 워크로드다. 파일 다운로드, 백업, 대형 아티팩트.
  • 클라이언트가 약하다. 임베디드, 저가 안드로이드. 논문 Table 1에서 격차가 가장 컸던 곳입니다.
  • 커널 소비자가 필요하다. 커널 NFS/SMB는 유저스페이스 QUIC 라이브러리를 링크할 수 없고, 커널 QUIC은 아직 메인라인에 없습니다.

이미 QUIC을 쓰고 있고 느리다면 이 순서로 보십시오. 암호 가속이나 커널 우회는 마지막입니다.

  1. 병목이 정말 CPU인지 확인한다. 회선이 병목이면 QUIC의 CPU 비용은 보이지 않습니다.
  2. 송신 측이면 UDP GSO부터. 구글 측정에서 하드웨어 오프로드까지 붙이면 통상 5배입니다.
  3. ACK 빈도를 본다. 송신·수신 양쪽에서 25% 내외가 걸려 있습니다.
  4. 그 다음에 암호를 의심한다. WWW 2024 측정에서 복호화는 QUIC이 HTTP/2보다 오히려 빨랐습니다.

마치며

정리하면 이렇습니다. QUIC은 핸드셰이크와 손실 복구에서 실제로 이겼고, 그 이득은 평균보다 꼬리에서 큽니다. 그리고 링크가 빨라지면 집니다 — 병목이 회선에서 CPU로 옮겨가는 500~600 Mbps 언저리가 분기점이고, 그 위로는 유저스페이스 트랜스포트가 치르는 비용이 그대로 드러납니다.

비용의 정체는 암호가 아니라 패킷을 만지는 횟수입니다. 커널이 GRO로 뭉쳐 주지 않으니 15배 많은 패킷이 유저스페이스로 올라오고, 커널이 만들어 주던 ACK를 직접, 지연 ACK 최적화도 없이 만듭니다. 그래서 2026년의 답안이 "커널에 넣자"인 것이고, 그 답안은 아직 리뷰 중입니다 — 메인라인에도 net-next에도 없습니다.

그 패치의 자체 벤치마크가 마지막 교훈을 줍니다. 커널에 넣어도 kTLS에 두 배 가까이 집니다. 그런데 TCP의 GSO를 꺼 보면 격차가 거의 사라집니다. 결국 이건 커널이냐 유저스페이스냐의 문제가 아니라, 오프로드를 쓸 수 있느냐의 문제였습니다. TCP가 빠른 건 오래돼서가 아니라 오래된 만큼 하드웨어가 도와줘서입니다.

QUIC에 그 도움이 붙는 데는 시간이 더 걸릴 겁니다. 그때까지는, 프로토콜을 고르기 전에 당신의 병목이 회선인지 CPU인지부터 재십시오. 그 답에 따라 정답이 뒤집힙니다.

참고 자료