실시간 업데이트 — 폴링 · 롱폴링 · SSE · WebSocket
같은 이벤트 2개를 네 방식이 전달하는 과정을 나란히 실행해, 요청 수와 전달 지연이 실측으로 갈리는 것을 보여준다.
1 / 10네 방식이 같은 이벤트(3틱·6틱에 발생)를 클라이언트에 전합니다. 볼 것은 두 가지 — 요청을 몇 번 보내는가, 이벤트를 얼마나 늦게 받는가.
⚡ 서버에 이벤트 발생!
폴링요청 0수신 0
롱폴링요청 0수신 0
SSE요청 0수신 0
WebSocket요청 0수신 0
경과 0 / 8틱
단계 목록 · 키보드 ←/→ 이동, Space 재생
넷의 차이는 '누가 기다리는가'다 — 폴링은 클라이언트가 반복해 묻고, 롱폴링은 서버가 질문을 붙잡고, SSE/WebSocket은 연결 자체를 열어 둔다.
왜 헷갈리는가
"실시간 = WebSocket"이라는 등식이 과설계의 주범이다. 알림 배지 하나 띄우는 데 WebSocket 인프라(연결 상태 관리, LB 고정, 재연결 로직)를 들이는 경우가 흔한데, 그 요구는 SSE나 롱폴링으로 충분하다.
애니메이션이 보여주는 것
폴링 레인만 이벤트를 늦게 받는다 — 발생과 다음 질문 사이의 간격이 그대로 지연이 된다. 주기를 줄이면 지연은 줄지만 빈손 왕복이 늘어난다: 지연과 낭비를 맞바꾸는 다이얼이다.
롱폴링은 질문을 서버가 붙잡고 있다가 이벤트가 나는 순간 응답한다 — 지연은 0에 가깝지만 응답마다 재연결 왕복이 든다. SSE와 WebSocket은 연결 1개로 끝나며, 화면의 요청 수(1 vs 폴링 4+)가 그 비용 차이다.
선택 기준
요구의 방향과 빈도로 고른다.
- 수 분 간격 갱신, 구현 5분: 폴링. 부끄러운 답이 아니다 — 대시보드 갱신의 표준.
- 서버→클라 푸시만 필요(알림·진행률·시세·LLM 스트림): SSE. HTTP 그대로라 프록시·인증·HTTP/2 멀티플렉싱이 공짜고, EventSource가 재연결을 알아서 한다.
- 양방향·고빈도(채팅·커서 공유·게임): WebSocket. 대가는 상태ful 연결 — LB의 세션 유지, 배포 시 드레이닝, 하트비트 설계가 따라온다.
- 옛 브라우저·엄격한 프록시 환경에서 푸시 흉내: 롱폴링. 오늘날엔 주로 폴백(Socket.IO의 밑단)으로 산다.
운영 관점의 숨은 비용
폴링의 비용은 서버가 아니라 집계된다 — 클라이언트 10만이 5초마다 물으면 초당 2만 QPS의 빈손 트래픽이다. 반대로 WebSocket의 비용은 연결 수다 — 10만 연결의 메모리·FD·재연결 폭풍(배포 순간 전원 재접속)을 견뎌야 한다. SSE는 그 중간에서 대부분의 푸시 요구를 흡수한다.
기억할 것
- 폴링: 클라이언트가 묻는다 — 지연↔낭비 다이얼.
- 롱폴링: 서버가 질문을 붙잡는다 — 푸시 흉내의 원조, 지금은 폴백.
- SSE: 단방향 푸시의 기본값 — HTTP 그대로, 자동 재연결.
- WebSocket: 양방향이 진짜 필요할 때만 — 상태ful 연결의 운영 비용을 지불한다.