HTTP/1.1·HTTP/2·HTTP/3 차이 완전정복

같은 HTTP인데 버전마다 무엇이 어떻게 달라졌는지, 아래 카드와 본문의 RFC 번호·비교표로 정리했습니다.

📄

HTTP/1.1 (1997년, RFC 2068)

지금도 널리 쓰이는 기본 형태의 HTTP로, 연결을 기본적으로 재사용(persistent connection)하도록 정해 매 요청마다 새로 연결을 맺던 초기 방식의 비효율을 개선했습니다.

다만 한 연결 안에서 요청을 보내면 응답이 올 때까지 다음 요청을 보낼 수 없는 순차 처리 구조라, 브라우저는 이를 우회하기 위해 한 사이트에 여러 개의 연결을 동시에 열어 여러 리소스를 병렬로 받는 방식을 써왔습니다. 이 방식은 연결 수가 늘어날수록 서버와 네트워크에 부담을 줍니다.

🚧

HTTP/1.1의 한계: 헤드 오브 라인(HOL) 블로킹

한 연결에서 앞선 요청의 응답이 늦어지면 뒤에 대기 중인 요청까지 모두 지연되는 현상을 헤드 오브 라인 블로킹이라고 합니다.

이미지, CSS, JS 파일이 많은 현대 웹페이지에서는 이 지연이 누적되어 전체 로딩 속도에 영향을 줍니다. 브라우저가 여러 연결을 동시에 여는 것도 결국 이 문제를 임시로 우회하기 위한 방편이었으며, 근본적인 해결은 HTTP/2에서 이뤄집니다.

🔀

HTTP/2 (2015년, RFC 7540)

요청과 응답을 작은 바이너리 프레임으로 쪼개 하나의 연결 위에서 여러 스트림을 동시에 주고받는 멀티플렉싱을 도입해 HOL 블로킹 문제를 크게 줄였습니다.

텍스트 기반이던 HTTP/1.1과 달리 바이너리 프레이밍 계층을 사용하고, 반복되는 헤더 정보를 압축하는 HPACK 기술로 오버헤드를 줄였습니다. 서버가 클라이언트 요청 없이도 필요할 리소스를 미리 보내주는 "서버 푸시" 기능도 도입되었지만, 실효성 논란으로 크롬은 2022년 106 버전부터 기본으로 끄는 등 브라우저에서 사용이 줄었습니다.

🧱

HTTP/2도 완전히 해결하지 못한 문제

HTTP/2는 애플리케이션 계층의 HOL 블로킹은 해결했지만, 그 아래 TCP 계층에서 패킷 손실이 생기면 여전히 모든 스트림이 함께 지연됩니다.

TCP는 데이터를 순서대로 전달해야 하는 프로토콜이라, 하나의 연결 위에서 여러 스트림을 함께 보내다가 패킷 하나가 유실되면 재전송이 끝날 때까지 같은 연결의 다른 모든 스트림도 기다려야 합니다. 이 TCP 계층의 한계는 프로토콜을 아예 UDP 기반으로 바꾼 HTTP/3에서 해결됩니다.

⚡

HTTP/3와 QUIC (2022년, RFC 9114)

TCP 대신 UDP 위에서 동작하는 구글 개발의 QUIC 프로토콜을 기반으로 하여, 한 스트림의 패킷 손실이 다른 스트림에 영향을 주지 않도록 설계되었습니다.

QUIC은 TCP와 TLS 암호화 과정을 통합해 연결을 맺는 데 걸리는 왕복 횟수를 줄이고, 이미 접속한 적 있는 서버에는 0-RTT(왕복 없이 즉시 데이터 전송)로 더 빠르게 재연결할 수 있습니다. 또한 스트림마다 독립적으로 순서를 관리해 진짜 의미의 멀티플렉싱을 구현했습니다.

🔍

내가 보는 사이트가 어떤 버전을 쓰는지 확인하는 법

크롬·엣지 등 브라우저의 개발자 도구(F12)에서 네트워크 탭을 열고 프로토콜(Protocol) 열을 추가하면 각 요청이 h1.1·h2·h3 중 무엇을 썼는지 바로 확인할 수 있습니다.

네트워크 탭에서 열 머리글을 마우스 오른쪽 버튼으로 클릭해 "Protocol" 항목을 체크하면 열이 추가됩니다. 대부분의 대형 웹사이트와 CDN은 이미 HTTP/2를, 상당수는 HTTP/3까지 지원하고 있으며, 서버와 클라이언트가 모두 지원하는 가장 높은 버전이 자동으로 협상되어 사용됩니다.

📊

실제로 체감할 수 있는 속도 차이

이미지·스크립트가 많은 복잡한 페이지에서는 HTTP/2·3의 이점이 뚜렷하지만, 리소스가 하나뿐인 단순한 요청은 버전 차이를 체감하기 어렵습니다.

이커머스나 뉴스 사이트처럼 수십~수백 개의 파일을 동시에 불러오는 페이지일수록 멀티플렉싱과 헤더 압축의 효과가 크게 나타납니다. 반대로 API 서버에 단일 요청 하나만 보내는 경우처럼 병렬로 받을 리소스가 적다면 버전에 따른 체감 속도 차이는 크지 않을 수 있습니다.

한눈에 보기

HTTP는 웹 브라우저와 서버가 주고받는 요청·응답의 약속입니다. 겉으로는 주소창의 https://가 그대로여도, 그 아래에서 메시지를 실어 나르는 방식은 1990년대 초의 텍스트 한 줄짜리 요청에서 출발해 바이너리 프레임, 그리고 UDP 기반 QUIC까지 바뀌어 왔습니다. 이 글은 버전별로 무엇이 문제였고 무엇이 고쳐졌는지, 어떤 RFC에 정의되어 있는지를 정리합니다. 위의 카드는 버전별 핵심을, 아래 본문은 문서 번호·비교표·확인 방법·오해를 다룹니다.

HTTP/0.9에서 HTTP/3까지: 문서 번호로 보는 연표

버전마다 RFC(IETF가 발행하는 표준·기술 문서)가 있고, 개정되면서 번호가 바뀐 경우가 많습니다. 아래는 RFC 편집자(rfc-editor.org) 정보 페이지에서 확인한 발행 시기입니다.

버전대표 문서발행 시기비고
HTTP/0.9RFC 아님(W3C의 "HTTP as implemented" 문서)1991년 프로토타입GET 요청 한 줄, 헤더 없음, 응답 후 서버가 연결을 닫음
HTTP/1.0RFC 19451996년 5월Informational(정보성) 문서
HTTP/1.1RFC 2068 → RFC 2616 → RFC 7230~7235 → RFC 9110·91121997년 1월 → 1999년 6월 → 2014년 6월 → 2022년이후 문서가 이전 문서를 대체(obsolete)함
HTTP/2RFC 7540 → RFC 91132015년 5월 → 2022년헤더 압축은 별도의 RFC 7541(HPACK, 2015년 5월)
HTTP/3RFC 9114 (전송은 RFC 9000 QUIC)2022년 (QUIC은 2021년)Proposed Standard

표의 2022년 항목은 해당 문서의 저작권 표기 연도 기준이며 월은 확인하지 못해 적지 않았습니다. 같은 HTTP/1.1이라도 문서가 여러 번 갈아치워졌다는 점이 중요합니다. RFC 2616은 RFC 7230~7235로, 이것이 다시 RFC 9110·9112 등으로 대체되었고, RFC 9112는 HTTP/1.1의 메시지 문법과 연결 관리를 다룹니다.

왜 이렇게 바뀌어 왔나: 병목이 옮겨 간 과정

HTTP/0.9의 요청은 GET 문서주소 한 줄이었고, 서버는 HTML을 보낸 뒤 연결을 닫았습니다. 요청마다 TCP 연결을 새로 맺는 구조였기 때문에 이미지가 많은 페이지에는 맞지 않았습니다. HTTP/1.1(RFC 9112 9.3절)은 연결을 기본적으로 유지하도록 정해 한 연결로 여러 요청을 처리하게 했고, 응답 대기 없이 요청을 연달아 보내는 파이프라이닝도 허용했습니다. 다만 응답은 요청 순서대로 와야 하므로 앞 요청이 느리면 뒤가 밀립니다. RFC 9112 9.4절도 클라이언트가 이 헤드 오브 라인(HOL) 블로킹을 피하려고 여러 연결을 연다고 적고 있습니다.

HTTP/2는 한 연결 안에서 여러 스트림을 프레임 단위로 섞어 보내 애플리케이션 계층의 HOL 블로킹을 줄였습니다. 하지만 RFC 9114 1.1절의 설명대로 TCP 위에서는 패킷 하나가 유실되거나 순서가 바뀌면 모든 활성 트랜잭션이 멈춥니다. TCP는 HTTP/2의 스트림 경계를 모르기 때문입니다. HTTP/3는 이 문제를 QUIC의 스트림별 신뢰성 보장으로 피하려는 설계이고, QUIC은 TLS 1.3을 통합해 스트림 다중화를 전송 계층에서 제공합니다.

세 버전을 나란히 비교

항목HTTP/1.1HTTP/2HTTP/3
전송 계층TCPTCPQUIC(UDP 위)
메시지 형태텍스트바이너리 프레임QUIC 스트림 위의 프레임
한 연결의 동시 요청순차 응답(브라우저는 연결 여러 개를 엶)스트림 다중화스트림 다중화
헤더 압축없음HPACK(RFC 7541)QPACK(RFC 9204)
TCP 계층 HOL 블로킹해당 연결 안에서 발생모든 스트림에 영향스트림 단위로 격리하도록 설계
서버 푸시없음사양에 있음사양에 있음(선택 기능)

QPACK은 HPACK의 변형으로, HTTP/3에서 헤더 압축 때문에 생기는 HOL 블로킹을 줄이도록 설계되었다고 RFC 9204 초록에 적혀 있습니다.

실제로 있었던 일 두 가지

사례 1. HTTP/2 서버 푸시가 브라우저에서 꺼진 이야기

서버 푸시는 클라이언트가 요청하기 전에 필요할 자원을 미리 보내 주는 기능으로, HTTP/2의 대표 기능으로 소개되었습니다. 그러나 위키백과 정리에 따르면 구글은 2020년 11월 크롬에서 서버 푸시를 제거할 의사를 밝혔고, 2022년 10월에는 크롬 106이 서버 푸시를 기본적으로 끄는 첫 릴리스가 되었습니다. 구글이 든 이유는 실제 성능 이득이 낮고, 사용률이 적으며, 더 나은 대안이 있다는 점이었다고 합니다. 배울 점은 표준에 들어갔다고 해서 현장에서 쓸모가 입증되는 것은 아니라는 것입니다. 사양에는 남아 있어도 구현이 빠지는 기능이 있을 수 있습니다. (위키백과 기준 서술이며 크롬 공식 블로그 원문은 확인하지 않았습니다.)

사례 2. 사양이 문서만 새로 쓰이는 경우: HTTP/2의 RFC 교체

HTTP/2는 2015년 5월 RFC 7540으로 발행되었고, 2022년 RFC 9113이 이를 대체(obsolete)했습니다. RFC 9113 초록은 이 문서가 RFC 7540과 RFC 8740을 대체한다고 밝히고 있습니다. 즉 "HTTP/2"라는 프로토콜 버전 이름은 그대로지만 기준 문서가 바뀐 것입니다. 오래된 블로그나 자료에서 RFC 7540을 인용한다면 현재는 RFC 9113이 최신 기준이라는 점을 알고 읽어야 합니다. 마찬가지로 많은 글에서 HTTP/1.1의 표준으로 인용되는 RFC 2616은 이미 대체된 문서입니다.

내 사이트가 어떤 버전인지 확인하는 방법

  1. 크롬·엣지에서 F12를 누르고 네트워크 탭을 연 뒤 열 머리글에서 Protocol을 켭니다. h2, h3 같은 값으로 표시됩니다.
  2. h3가 표시되지 않아도 이상한 것이 아닙니다. 서버는 응답 헤더 Alt-Svc로 HTTP/3 지원을 알릴 수 있고(RFC 9114 3.1.1절), 클라이언트가 이를 보고 QUIC 연결을 시도하므로 첫 접속은 h2로 이뤄질 수 있습니다.

서버 운영자라면 웹 서버·CDN이 해당 버전을 지원하는지 제품 문서에서 확인하세요. 설정 방법은 서버 종류마다 다릅니다.

흔한 오해와 정정

한계와 더 알아볼 점

버전별 체감 속도는 페이지 구성, 서버 설정, 네트워크 손실률, 단말 성능에 따라 달라지므로 일반론으로 단정하기 어렵습니다. 서버 푸시처럼 사양과 현장 사용이 어긋난 사례도 있습니다. 이 글은 RFC 정보 페이지와 몇몇 RFC 본문을 기준으로 정리했고, QPACK 같은 일부 세부 사양은 직접 확인하지 못했습니다. 실제 적용 전에는 해당 RFC 원문을 읽어 보세요.

HTTP 메서드와 상태 코드도 함께 정리했어요

GET·POST 같은 HTTP 메서드나 200·404 같은 상태 코드가 궁금하다면HTTP 메서드 완전정복과HTTP 상태 코드 완전정복도 확인해보세요.

양방향 실시간 통신이 필요하다면

HTTP의 요청-응답 구조를 넘어선 실시간 양방향 통신이 궁금하다면웹소켓(WebSocket)이란? 기초 개념 정리도 참고해보세요.

자주 묻는 질문

HTTP/3를 쓰려면 웹사이트가 따로 설정해야 하나요?

네, 서버가 QUIC과 HTTP/3를 지원하도록 설정되어 있어야 하며, 브라우저도 이를 지원해야 자동으로 협상되어 사용됩니다. 대부분의 주요 CDN과 최신 브라우저는 이미 HTTP/3를 지원하고 있습니다.

HTTP/1.1은 왜 아직도 쓰이나요?

HTTP/1.1은 기능이 단순하고 거의 모든 클라이언트와 서버가 지원하기 때문입니다. HTTP/2 이상은 협상을 통해 쓰이며, 지원하지 않는 상대와는 자동으로 낮은 버전으로 통신합니다.

HTTP 버전이 바뀌면 메서드나 상태 코드도 바뀌나요?

아닙니다. GET·POST 같은 메서드와 200·404 같은 상태 코드의 의미는 버전과 별개의 HTTP 의미 계층이고, 버전은 그 메시지를 어떻게 전송하느냐를 바꿉니다.

RFC 번호가 여러 개인데 어느 것이 최신인가요?

RFC 페이지의 "Obsoleted by" 항목을 보면 됩니다. 예를 들어 RFC 7540은 RFC 9113에 의해, RFC 2616은 RFC 7230~7235를 거쳐 RFC 9110·9112 등에 의해 대체되었습니다.

HTTP/3에서도 서버 푸시를 쓸 수 있나요?

RFC 9114에 서버 푸시용 프레임(PUSH_PROMISE 등)이 정의되어 있지만 선택 기능입니다. 다만 크롬은 2022년 106 버전부터 서버 푸시를 기본으로 끈 것으로 알려져 있습니다(위키백과 기준).

UDP는 신뢰성이 낮다고 알고 있는데 HTTP/3가 UDP를 쓰는 게 안전한가요?

HTTP/3가 사용하는 QUIC은 UDP 위에 자체적으로 순서 보장과 재전송 같은 신뢰성 기능을 구현해두었기 때문에, 일반 UDP 통신과 달리 데이터 유실 없이 안전하게 전달됩니다. 동시에 TCP처럼 하나의 손실이 전체를 지연시키지 않는 유연함도 함께 갖추고 있습니다.