네트워크 용어 사전
실시간Server-Sent Events · EventSource · text/event-stream · Last-Event-ID

SSE

응답을 끝내지 않고 계속 흘려보내는 단방향 푸시. 브라우저가 재연결까지 알아서 한다.

HTTP 응답을 끝내지 않고 계속 흘려보내는 단방향 푸시 방식.

생김새

GET /events HTTP/1.1
Accept: text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

id: 42
event: price
data: {"symbol":"AAPL","price":231.5}

retry: 3000

: 이 줄은 주석이다 — 프록시 버퍼를 밀어내는 하트비트로 쓴다

형식 규칙

  • 필드는 field: value 형태, 이벤트는 '빈 줄' 로 끝난다
  • data 가 여러 줄이면 줄마다 data: 를 붙인다 (수신 측에서 \n 으로 이어진다)
  • id 를 주면 브라우저가 기억한다
  • retry 는 재연결 대기 시간(ms)

브라우저가 대신 해 주는 일

const es = new EventSource("/events");
es.addEventListener("price", (e) => render(JSON.parse(e.data)));

연결이 끊기면 브라우저가 알아서 다시 붙는다 이때 마지막으로 받은 id 를 Last-Event-ID 헤더로 보낸다

  • 서버는 그 다음 것부터 보내면 된다. 유실 복구가 프로토콜에 들어 있다

WebSocket 은 재연결·재개를 전부 직접 짜야 한다 — 이 차이가 생각보다 크다

지금 SSE가 다시 쓰이는 이유 — LLM 토큰 스트리밍

  • 서버가 토큰을 생성하는 대로 밀어 준다. 클라이언트는 받기만 한다
  • 정확히 SSE 의 모양이다

주요 LLM API 의 스트리밍 응답이 text/event-stream 으로 나간다 브라우저 챗 UI, 서버 간 중계 모두 같은 형식을 쓴다

"WebSocket 은 과하고 폴링은 느린" 자리를 SSE 가 정확히 메운다

반드시 걸리는 함정 — 프록시 버퍼링

리버스 프록시가 응답을 모았다가 한꺼번에 보내면 스트리밍이 '한참 뒤 한꺼번에' 도착한다 → 스트리밍이 아니게 된다

  • nginx — proxy_buffering off;
    • 또는 응답에 X-Accel-Buffering: no 헤더
  • 압축 — gzip 이 버퍼링을 유발할 수 있다 → 이 엔드포인트만 끄거나 flush 보장
  • CDN — 스트리밍 응답은 캐시·버퍼 대상에서 제외한다

"로컬에선 되는데 배포하면 안 된다" 의 1순위 원인이다

HTTP 버전이 성능을 가른다

  • HTTP/1.1 — 브라우저는 오리진당 동시 연결이 6개로 제한된다

    • SSE 연결 하나가 그 자리를 계속 차지한다
    • 탭을 여러 개 열면 다른 요청이 막힌다
  • HTTP/2+ — 하나의 연결에 스트림을 다중화하므로 이 제한이 사라진다

    • SSE 를 쓸 거면 HTTP/2 이상을 전제로 두는 편이 안전하다

무엇을 못 하나

  • 단방향이다 — 클라이언트가 보낼 것이 있으면 별도 POST 를 쓴다
    • (실무에서는 이 조합으로 충분한 경우가 많다)
  • 텍스트만 나른다 — 바이너리는 base64 로 감싸야 해서 33% 커진다
  • EventSource 는 커스텀 헤더를 못 붙인다 (Authorization 불가)
    • 쿠키를 쓰거나, fetch + ReadableStream 으로 직접 파싱한다
      • (요즘은 이 방식이 오히려 흔하다 — 헤더·POST 본문·중단 제어가 자유롭다)

선택 기준

  • 서버 → 클라이언트 단방향 — SSE
  • 양방향이 잦다 (채팅·협업 편집) — WebSocket
  • 초당 수십 회 이상 · 저지연 — WebSocket
  • 갱신이 드물다 (분 단위) — 그냥 폴링

면접 함정

  • "SSE는 구식이다" → 단방향 스트리밍에서는 지금도 최선이고, LLM 스트리밍으로 오히려 쓰임이 늘었다.
  • "응답이 200이면 잘 흐른다" → 프록시 버퍼링에 막히면 200인 채로 아무것도 안 온다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — HTTP — 요청/응답·메서드·1.1/2/3·HoL