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)을 줄이고

  • 네트워크 자원을 더 효율적으로 쓰는 것

핵심 키워드만 뽑으면:

  1. 바이너리 프레이밍(Binary Framing)

  2. 스트림(Stream) 기반 멀티플렉싱(Multiplexing)

  3. 헤더 압축(HPACK)

  4. (원래는) 서버 푸시(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를 기본으로 생각해도 된다.”

가 맞습니다.

하지만 실무적으로는:

  1. HTTP/1.1을 완전히 없애기는 어렵다

    • 오래된 클라이언트나 특수 환경은 여전히 1.1만 가능

    • 디버깅/툴/내부 시스템 등에서 1.1이 편한 경우 많음

  2. 서버 입장에서는 ‘둘 다 지원’이 일반적

    • 웹 서버 설정에서 h2 http/1.1 같이 켜 두고

    • 클라이언트가 지원하는 최고의 프로토콜을 자동으로 선택하도록 맡김

  3. HTTP/3(QUIC)까지 고려하는 시대

    • 최신 브라우저/서비스는 이미 HTTP/3도 지원

    • 하지만 이것도 보통 “HTTP/1.1 + HTTP/2 + HTTP/3”을 동시에 열어두고
      클라이언트가 협상으로 고르는 구조입니다.

그래서 현실적인 결론은:

“HTTP/2만 고집하기보다는,
HTTP/2를 기본으로 켜고 HTTP/1.1은 자연스러운 Fallback으로 두는 게 베스트.”

입니다.


http버젼에 따른 전송방식 비교

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)에 맡겨라.