HTTP/2 멀티플렉싱은 하나의 TCP 연결 위에서 여러 요청과 응답을 동시에 주고받는 기술이다. 요청마다 새 커넥션을 열던 HTTP/1.1과 달리, 한 연결을 여러 개의 논리적 스트림으로 쪼개 병렬로 흘려보낸다. 그 덕에 head-of-line 블로킹이라는 오래된 병목이 크게 줄었다.
말은 쉬운데, 처음 이 개념을 접했을 때 나는 "연결을 여러 개 쓰는 거랑 뭐가 다른데?"라고 생각했다. 결론부터 말하면 완전히 다르다. 그 차이가 왜 중요한지 순서대로 풀어보겠다.
HTTP/1.1의 병목: 줄 서기
HTTP/1.1에서 하나의 TCP 연결은 한 번에 한 요청만 처리한다. 요청을 보내면 응답이 올 때까지 그 연결은 묶여 있다. 파이프라이닝이라는 우회책이 있긴 했지만, 응답은 반드시 보낸 순서대로 와야 한다는 제약 때문에 앞 응답이 느리면 뒤가 전부 막혔다. 이게 애플리케이션 계층의 head-of-line 블로킹이다.
그래서 브라우저는 도메인당 커넥션을 6개쯤 열어 병렬성을 흉내 냈다. 이미지 50개짜리 페이지를 열면 6개씩 끊어 받는 식이다. 커넥션마다 TCP 슬로우 스타트를 새로 겪고, 메모리도 더 먹는다. 임시방편이었다.
스트림, 프레임, 그리고 병렬성
HTTP/2는 하나의 연결 안에 스트림(stream)이라는 독립 채널을 무수히 만든다. 각 요청/응답은 고유한 스트림 ID를 갖고, 데이터는 작은 프레임(frame) 단위로 쪼개져 뒤섞여 전송된다. 받는 쪽은 프레임 헤더의 스트림 ID를 보고 다시 조립한다. 그림으로 그리면 이렇다.
[1개 TCP 연결]
stream 1: HEADERS -> DATA -----> (index.html)
stream 3: HEADERS -> DATA -> (style.css)
stream 5: HEADERS -> DATA ----> (app.js)
전송 순서: [S1 HDR][S3 HDR][S1 DATA][S5 HDR][S3 DATA]...
프레임이 인터리빙되어 흐른다
덕분에 느린 응답 하나가 다른 응답을 막지 않는다. 애플리케이션 계층의 HOL 블로킹은 이걸로 사라졌다. 여기에 헤더 압축(HPACK)과 서버가 우선순위를 주는 기능까지 얹혔다.
| 항목 | HTTP/1.1 | HTTP/2 |
|---|---|---|
| 연결당 동시 요청 | 1개 | 수백 개 스트림 |
| 전송 단위 | 텍스트 메시지 | 바이너리 프레임 |
| 헤더 | 매번 반복 전송 | HPACK 압축 |
| HOL 블로킹 | 앱 계층에서 발생 | 앱 계층 해소 |
여기서 반전: TCP 계층의 HOL은 남는다
내가 실무에서 데인 지점이 바로 여기다. HTTP/2는 애플리케이션 계층의 HOL만 없앴다. 그 밑의 TCP는 여전히 바이트 스트림을 순서대로 보장한다. 그래서 패킷 하나가 유실되면, 그 패킷이 재전송될 때까지 TCP는 뒤따라온 모든 스트림의 데이터를 상위로 올려주지 않는다.
연결이 하나라서 생기는 역설이다. 손실 없는 깨끗한 회선에서는 HTTP/2가 압도적이지만, 패킷 손실이 잦은 모바일·불안정 네트워크에서는 오히려 커넥션 6개 쓰던 HTTP/1.1보다 느려지는 구간이 나온다.
이 TCP 계층 HOL을 근본적으로 없애려고 나온 게 HTTP/3다. QUIC(UDP 기반)로 전송 계층을 갈아끼워 스트림별로 독립적인 손실 복구를 한다. 즉 HTTP/2의 멀티플렉싱은 절반의 해결이었고, HTTP/3가 나머지 절반을 채운 셈이다.
실전에서 신경 쓸 점
- 도메인 샤딩을 걷어내라 — HTTP/1.1 시절 쓰던 img1.cdn, img2.cdn 같은 분산은 HTTP/2에선 오히려 연결을 늘려 손해다. 한 도메인으로 모으는 게 낫다.
- 번들 과도하게 쪼개지 마라 — 요청이 싸졌다고 파일 200개로 나누면 프레임 오버헤드와 우선순위 관리 비용이 커진다. 적당한 청킹이 여전히 유효하다.
- HTTPS가 사실상 전제 — 브라우저는 TLS(ALPN) 위에서만 HTTP/2를 켠다. h2c(평문)는 브라우저가 지원하지 않는다.
- 서버 푸시는 잊어라 — 실효가 없어 크롬에서 제거됐다. 대신
103 Early Hints를 쓴다.
자주 묻는 질문
HTTP/2를 쓰면 무조건 빨라지나요?
대체로 빨라지지만 항상은 아닙니다. 손실이 잦은 네트워크에서는 단일 TCP 연결의 head-of-line 블로킹 때문에 체감이 나빠질 수 있습니다. 안정적인 유선·데이터센터 환경일수록 이득이 큽니다.
멀티플렉싱과 파이프라이닝은 같은 건가요?
아닙니다. 파이프라이닝은 요청을 연달아 보내되 응답을 보낸 순서대로 받아야 해서 앞이 막히면 뒤가 막힙니다. 멀티플렉싱은 응답을 순서 무관하게 프레임으로 섞어 받으므로 서로를 막지 않습니다.
HTTP/2를 켜려면 코드를 고쳐야 하나요?
보통은 아닙니다. Nginx, Caddy 같은 리버스 프록시나 CDN에서 옵션 한 줄로 켜면 됩니다. 애플리케이션은 여전히 평범한 HTTP 요청·응답을 다루면 되고, 프레이밍은 프록시가 처리합니다.
그럼 이제 HTTP/3만 쓰면 되나요?
HTTP/3는 UDP 차단 환경에서 자동으로 HTTP/2로 폴백합니다. 둘 다 켜두고 브라우저가 협상하게 두는 게 현실적입니다. HTTP/2는 앞으로도 오래 기본값으로 남을 겁니다.

댓글 0