HTTP 버전 이야기가 나오면 보통 이런 생각 들죠.
“어차피 웹은 다 HTTP 아닌가? 1.1이랑 2는 뭐가 그렇게 다른데?”
“새 버전인 HTTP/2만 쓰면 되는 거 아니야?”
정리해 보면:
-
HTTP/1.1 vs HTTP/2는 “완전 다른 프로토콜”이라기보다, 같은 HTTP 의미(메서드/헤더/상태코드 등)를 더 효율적으로 보내는 방식의 차이입니다.
-
실제 서비스에서는 “둘 중 하나를 고르는 것”이 아니라, 서버가 둘 다 지원하고 클라이언트가 가능한 쪽을 선택하는 구조가 일반적입니다.
아래에서 개발자 관점에서 핵심만 정리해볼게요.
1. HTTP/1.1 간단 정리
1) 텍스트 기반 프로토콜
HTTP/1.1은 우리가 흔히 보는 이런 요청/응답 형식입니다.
GET /index.html HTTP/1.1
Host: example.com
Connection: keep-alive
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<html>...</html>
-
사람이 읽을 수 있는 텍스트 기반이라 디버깅이 쉽고,
-
curl,telnet,nc같은 도구로 대충 찍어봐도 구조를 파악할 수 있습니다.
2) Persistent Connection + Pipelining
HTTP/1.0의 큰 문제는 요청마다 TCP 연결을 새로 여는 것이었는데,
HTTP/1.1에서 기본이 persistent connection(keep-alive) 이 되어,
하나의 연결 위에서 여러 요청을 순차적으로 보낼 수 있게 했습니다.
추가로, HTTP pipelining이라는 기능도 있었는데:
-
응답을 기다리지 않고 요청을 연속해서 쏘고
-
순서대로 응답을 받는 방식입니다.
하지만 실제 브라우저에서는 거의 사용되지 않았고,
여전히 “순서대로 처리해야 하는 구조”라서 성능 문제가 남습니다.
3) HOL(Head-of-Line) Blocking 문제
HTTP/1.1의 대표적인 병목이 바로 HOL(Head-of-Line) Blocking입니다.
-
하나의 연결에서 요청을 순차적으로 처리해야 하다 보니
-
맨 앞 요청이 느려지면 뒤에 있는 요청들도 같이 기다려야 합니다.
-
그래서 브라우저는 하나의 도메인(origin)당 TCP 연결을 여러 개(예: 최대 6개) 열어서 이 문제를 완화해 왔습니다.
요약하면:
HTTP/1.1은 “여러 개의 파이프를 만들어서 병목을 줄이는 방식”입니다.
(여러 TCP 연결)
2. HTTP/2는 뭐가 다른가?
HTTP/2의 목표는 명확합니다.
-
지연 시간(latency)을 줄이고
-
네트워크 자원을 더 효율적으로 쓰는 것
핵심 키워드만 뽑으면:
-
바이너리 프레이밍(Binary Framing)
-
스트림(Stream) 기반 멀티플렉싱(Multiplexing)
-
헤더 압축(HPACK)
-
(원래는) 서버 푸시(Server Push) – 사실상 브라우저에서 사망
2-1. 텍스트 → 바이너리 프레이밍
HTTP/1.1은 줄 단위 텍스트 파싱이지만, HTTP/2에서는 모든 걸 프레임(frame) 이라는 바이너리 조각으로 쪼개서 보냅니다.
-
헤더는 HEADERS 프레임
-
본문은 DATA 프레임
-
이 프레임들이 특정 스트림 ID에 속합니다.
개발자가 직접 프레임을 만질 일은 거의 없지만,
이 덕분에 멀티플렉싱, 헤더 압축, 우선순위 같은 기능을 구현할 수 있습니다.
2-2. 멀티플렉싱(Multiplexing)
가장 체감되는 차이입니다.
-
HTTP/1.1: 한 TCP 연결에서 요청-응답을 순차적으로 처리
-
HTTP/2: 한 TCP 연결에서 여러 스트림을 동시에 흘려보냄
즉,
“여러 개의 TCP 연결을 열 필요 없이,
하나의 연결 안에서 요청과 응답을 짜깁기해서 동시에 보내는 것”
이렇게 하면:
-
하나의 HTML 페이지가 수십~수백 개 리소스를 가져와야 할 때도
-
연결 하나만 유지하면서 동시에 가져올 수 있어
-
모바일 환경, 고 RTT 환경에서 특히 이득이 큽니다.
단, 여전히 TCP 레벨에서는 HOL Blocking이 남아 있어서, 이 부분은 HTTP/3(QUIC)이 더 개선한 영역입니다.
2-3. 헤더 압축(HPACK)
HTTP 요청/응답 헤더는 상당히 중복이 많습니다.
-
Cookie,User-Agent,Accept-*등 -
매 요청마다 수백~수 KB씩 실릴 수도 있음
HTTP/2는 HPACK이라는 헤더 압축 방식을 사용해서
이 헤더들 사이의 중복을 줄입니다.
-
자주 쓰는 헤더는 테이블에 등록해 짧은 인덱스로 전송
-
이전 요청과 달라진 부분만 효율적으로 인코딩
이 덕분에 특히 요청 수가 많은 SPA / 리소스 많은 페이지에서 이득이 큽니다.
2-4. 서버 푸시(Server Push)는 사실상 사망
HTTP/2 초기에 “서버가 클라이언트가 요청하기 전에 CSS/JS 등을 먼저 밀어주는 기능”인 서버 푸시(Server Push) 도 큰 장점으로 받아들여졌지만, 실전에서:
-
구현 난이도가 높고
-
캐시/중복 리소스 문제
-
실제 성능 개선이 미미하거나 오히려 악화되는 사례
등으로, 크롬/크로미움 계열은 2022년 이후 기본 비활성화 되었고(Chrome for Developers)
파이어폭스도 2024년대에 지원을 제거하는 등, 브라우저 생태계에서는 사실상 끝난 기능입니다.
그래서 요즘 HTTP/2 이야기할 때 서버 푸시는 “역사적인 기능” 정도로만 보면 됩니다.
3. HTTPS, ALPN, 그리고 “h2 vs http/1.1 선택”
실제 서비스에서 “HTTP/1.1 쓸까, HTTP/2 쓸까?”는
클라이언트-서버가 TLS Handshake 과정에서 자동으로 협상합니다.
이를 담당하는 게 ALPN(Application-Layer Protocol Negotiation) 이라는 TLS 확장입니다.
-
클라이언트: “나
h2,http/1.1둘 다 할 줄 알아” -
서버: “그럼
h2로 하자” (또는 “난http/1.1만 돼”)
Apache 예시 설정:
Protocols h2 http/1.1
이렇게 설정해 두면:
-
HTTP/2를 지원하는 최신 브라우저는 자동으로 HTTP/2(h2) 사용
-
구형 클라이언트는 자동으로 HTTP/1.1로 통신
대부분의 메이저 브라우저는 이미 HTTP/2를 잘 지원하고 있고,
상당수 웹사이트가 HTTP/2를 활성화하고 있습니다.
4. “어떤 경우에 나누어서 쓰나?” – 개발 관점 정리
질문의 핵심인 이 부분을 케이스별로 보겠습니다.
4-1. 일반적인 웹 서비스(브라우저 대상)
정답에 가까운 전략:
“HTTPS + HTTP/2를 기본으로 켜고,
HTTP/1.1은 Fallback으로 그냥 두면 된다.”
-
대부분의 웹서버(Nginx, Apache, Envoy 등)와 CDN은
HTTP/2 지원 옵션을 켜는 것만으로 자동 협상합니다. -
애플리케이션 레벨에서 “이 요청은 1.1, 저건 2로 보내자” 를 직접 나눌 일이 거의 없습니다.
즉, 서비스를 새로 만든다면 ‘HTTP/2를 켠 HTTPS’를 기본값으로 생각하면 됩니다.
4-2. 내부 API / 마이크로서비스 통신
여기는 조금 더 선택지가 있습니다.
-
이미 REST + HTTP/1.1로 잘 굴러가고 있다면
굳이 HTTP/2로 재작성할 필요까지는 없음 -
다만,
-
동일 서비스 간에 짧은 요청을 매우 많이 주고받거나
-
gRPC 같은 HTTP/2 기반 프로토콜을 사용한다면
→ HTTP/2를 쓰는 게 자연스럽습니다.
-
즉,
-
“기존 레거시 REST API” → 1.1 유지 + 필요 시 프록시/로드밸런서에서 HTTP/2 Termination
-
“새로 gRPC 도입, 고빈도 마이크로서비스 호출” → HTTP/2 적극 활용
4-3. 디버깅, 로깅, 레거시 환경
HTTP/1.1이 여전히 유용한 상황도 있습니다.
-
텍스트 기반이라 tcpdump, Wireshark에서 내용 보기 쉬움
-
오래된 프록시/방화벽/클라이언트는 HTTP/2를 지원하지 않을 수 있음
-
단순한 사내용 툴, 테스트 서버 등에서는 굳이 HTTP/2까지 안 써도 충분
실제로 많은 환경에서:
-
외부(브라우저) ↔ 프론트 프록시(CDN/Load Balancer) : HTTP/2
-
프록시 ↔ 백엔드 서비스 : HTTP/1.1
구조가 섞여 있는 경우가 많습니다.
5. “HTTP/2만 쓰면 안 되나?”에 대한 현실적인 답
이론적으로는:
“새로 만드는 공개 웹 서비스라면 HTTP/2를 기본으로 생각해도 된다.”
가 맞습니다.
하지만 실무적으로는:
-
HTTP/1.1을 완전히 없애기는 어렵다
-
오래된 클라이언트나 특수 환경은 여전히 1.1만 가능
-
디버깅/툴/내부 시스템 등에서 1.1이 편한 경우 많음
-
-
서버 입장에서는 ‘둘 다 지원’이 일반적
-
웹 서버 설정에서
h2 http/1.1같이 켜 두고 -
클라이언트가 지원하는 최고의 프로토콜을 자동으로 선택하도록 맡김
-
-
HTTP/3(QUIC)까지 고려하는 시대
-
최신 브라우저/서비스는 이미 HTTP/3도 지원
-
하지만 이것도 보통 “HTTP/1.1 + HTTP/2 + HTTP/3”을 동시에 열어두고
클라이언트가 협상으로 고르는 구조입니다.
-
그래서 현실적인 결론은:
“HTTP/2만 고집하기보다는,
HTTP/2를 기본으로 켜고 HTTP/1.1은 자연스러운 Fallback으로 두는 게 베스트.”
입니다.

6. 요약 정리
한 번에 정리해 보면:
-
HTTP/1.1
-
텍스트 기반
-
persistent connection + (이론상의) pipelining
-
HOL Blocking 문제로 인해 브라우저는 여러 TCP 연결 열어서 사용
-
-
HTTP/2
-
바이너리 프레이밍
-
하나의 TCP 연결에서 여러 스트림을 동시에 처리하는 멀티플렉싱
-
HPACK 헤더 압축
-
서버 푸시는 사실상 실전에서 사망 상태
-
-
사용 전략
-
외부 웹(브라우저 대상): HTTPS + HTTP/2를 켜고 HTTP/1.1은 Fallback
-
내부 API: 기존 REST는 1.1 유지도 OK, 고빈도/스트리밍/gRPC면 HTTP/2 적극 활용
-
디버깅/레거시: 여전히 HTTP/1.1이 편하고 쓸모 있음
-
개발자가 기억하면 좋은 한 줄:
“앱 코드에서 버전 고르려고 고민하지 말고,
서버에서 HTTP/2를 켜 두고 나머지는 프로토콜 협상(ALPN)에 맡겨라.”
댓글이 없습니다.