왜 WebSockets는 대부분의 실시간 앱에 과도한가

발행: (2026년 2월 5일 오전 09:20 GMT+9)
9 min read
원문: Dev.to

Source: Dev.to

WebSockets vs SSE

실시간 기능을 구현할 때 대부분 사람들은 WebSocket을 사용합니다. 실제로 대부분의 애플리케이션은 단방향 업데이트만 필요하며, **Server‑Sent Events (SSE)**가 더 좋고, 간단하며, 비용도 적게 듭니다.

WebSocket이 실제로 의미가 있는 경우와 그렇지 않은 경우를 살펴보겠습니다.

WebSocket 기본 문제

“실시간”은 이제 “WebSocket 사용”의 약어가 되었다.
하지만 그 가정은 중요한 질문을 놓친다:

실제로 누가 대화하고 있나요?

대부분의 실제 애플리케이션에서는 답이 간단하다:

  • 서버가 업데이트를 생성한다
  • 클라이언트가 듣고 렌더링한다

이는 대화가 아니라 스트림이다.

그럼에도 팀은 여전히 WebSocket 비용을 지불한다:

  • 코드가 늘어난다
  • 상태가 늘어난다
  • 확장이 더 어려워진다
  • 디버깅 고통이 추가된다

데이터를 되돌려 보내지 않는 기능에도 종종 적용된다.

대부분의 실시간 기능이 실제로 어떻게 보이는가

이것들은 본질적으로 단방향이다

  • 대시보드(지표, 분석, 모니터링)
  • 알림 및 경고
  • 활동 피드
  • 주식 또는 암호화폐 티커
  • CI/CD 빌드 상태
  • 로그 스트리밍
  • AI 응답 스트리밍
  • 시스템 상태 업데이트

이 모든 경우에 데이터는 서버 → 클라이언트 로 흐릅니다.
클라이언트 입력(있는 경우)은 일반 HTTP 요청을 통해 이루어집니다. 여기서 SSE가 빛을 발합니다.

WebSockets가 실제로 중요한 경우

WebSockets는 다음과 같은 경우에 적합한 도구입니다:

  • 지속적인 양방향 통신
  • 클라이언트 주도 상태 변경
  • 초저지연
  • 바이너리 데이터 전송

예시

  • 멀티플레이어 게임
  • 협업 편집기
  • 실시간 거래 터미널
  • 음성/영상 신호 처리

이 범주는 존재하지만, 대부분의 팀이 생각하는 것보다 훨씬 작습니다.

서버‑전송 이벤트 (SSE)란 무엇인가?

SSE는 서버가 발생하는 대로 업데이트를 스트리밍하는 장기 HTTP 연결입니다. 프로토콜 업그레이드도 없고, 사용자 정의 프레이밍도 없으며, 하트비트 처리도 필요 없습니다 — 단순히 HTTP만 사용합니다.

클라이언트 (브라우저)

const source = new EventSource('/events');

source.onmessage = (e) => {
  console.log(JSON.parse(e.data));
};

서버 (Node.js)

app.get('/events', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');

  const interval = setInterval(() => {
    res.write(`data: ${JSON.stringify({ time: Date.now() })}\n\n`);
  }, 1000);

  req.on('close', () => clearInterval(interval));
});

이것은 작동하는 실시간 스트림이며, 별도의 라이브러리가 필요 없습니다.

왜 SSE가 더 나은 기본값인가

1. 그냥 HTTP다

SSE는 표준 HTTP(80/443) 위에서 동작한다:

  • 프록시 뒤에서도 동작
  • CDN에서도 동작
  • 기업 네트워크에서도 동작
  • HTTP가 동작하는 모든 곳에서 동작

WebSocket은 제한된 환경에서 조용히 실패하는 경우가 많다.

2. 자동 재연결이 내장돼 있다

연결이 끊기면:

  • 브라우저가 자동으로 재연결
  • 백오프 적용
  • 여러분이 코드를 작성할 필요 없음

WebSocket의 경우 재연결 로직은 여러분의 문제다.

3. 디버깅이 간단하다

실시간 데이터를 확인하고 싶나요?

curl -N https://example.com/events

즉시 가시화. 별도 도구가 필요 없다.

4. 성능이 사실상 동일하다

실제 시스템에서는:

  • 네트워크 지연이 지배
  • 데이터베이스 지연이 지배
  • 렌더링 시간이 지배

프로토콜 차이는 보통 밀리초 수준—대시보드, 피드, 알림에서는 사용자에게 보이지 않는다.

5. HTTP/2가 오래된 제한을 없앤다

예전 우려: “브라우저가 연결 수를 제한한다.”
HTTP/2에서는:

  • 하나의 TCP 연결
  • 다수의 멀티플렉스 스트림
  • 실질적인 연결 제한 없음

현대 브라우저와 서버는 이미 이를 지원한다.

Source:

SSE의 실제 활용 사례

AI 스트리밍 응답

사용자가 POST로 프롬프트를 전송합니다. 서버가 토큰을 스트리밍으로 반환합니다. 클라이언트는 점진적으로 렌더링합니다. 양방향 채널이 필요 없습니다.

관측 및 모니터링

메트릭과 로그는 서버에서 생성됩니다. 클라이언트는 이를 관찰만 합니다. SSE는 시스템을 단순하고 확장 가능하게 유지합니다.

기능 플래그 및 구성 업데이트

클라이언트는 변경 사항을 수신 대기합니다. 협상이 필요하지 않습니다. SSE에 최적화된 영역입니다.

SSE가 적합하지 않은 경우

다음이 필요할 때는 SSE를 피하세요:

  • 바이너리 스트리밍
  • 지속적인 클라이언트 측 입력
  • 10 ms 미만 지연 보장
  • 피어‑투‑피어 협상

그럴 때 WebSockets(또는 WebRTC)가 제 역할을 합니다.

일반적인 SSE 함정 (해결됨)

  • 버퍼링된 응답 → 프록시 버퍼링 비활성화
  • 유휴 타임아웃 → 가벼운 하트비트 전송
  • 수평 확장 → 백플레인으로 Redis/Kafka 사용
  • 인증 → 쿠키 또는 단명 토큰

이것들은 해결된 문제이며 — 차단 요소가 아닙니다.

더 나은 사고 모델

대신에 묻지 말고:

“실시간이 필요할까요?”

다음과 같이 물어보세요:

“누가 말하고, 누가 듣나요?”

서버가 대부분의 대화를 담당한다면, SSE가 첫 번째 선택이어야 합니다. WebSocket은 의도적으로 사용해야 하며, 자동이 아닙니다.

The Bottom Line

WebSockets는 강력하지만 종종 불필요합니다. 대부분의 실시간 기능에 대해 Server‑Sent Events는:

  • 더 간단함
  • 디버깅이 쉬움
  • 확장이 쉬움
  • 유지보수가 쉬움
  • 프로덕션에서 더 신뢰성 있음

지루한 기술이 프로덕션에서 승리합니다. 그리고 서버‑클라이언트 스트리밍의 경우, SSE가 지루하고 올바른 선택입니다.


Discussion
앱에서 실시간 기능을 어떻게 처리하고 있나요? SSE만으로 충분했을 텐데 WebSocket을 사용한 적이 있나요—또는 그 반대의 경우도 있나요? 실제 경험을 공유해주세요.

Back to Blog

관련 글

더 보기 »

HTTP 푸시 메커니즘

전통적인 HTTP Pull 모델 기본적으로 웹 통신은 HTTP Pull 모델을 따릅니다: - 클라이언트가 요청을 보냅니다 - 서버가 이를 처리합니다 - 서버…