본문 바로가기
TYLER SONG2026
블로그 목록
Frontend

Cold vs Hot Observable: 구독마다 실행되는지 여부로 나뉘는 두 가지 실행 방식

Cold Observable은 구독(subscribe)할 때마다 데이터 생산 로직이 처음부터 새로 실행되고, Hot Observable은 이미 진행 중인 데이터 흐름을 여러 구독자가 공유한다. 이 차이는 HTTP 요청 중복 실행이나 실시간 이벤트 스트림 공유 같은 실무 문제와 직접 연결된다. 두 개념을 구분하지 못하면 의도치 않은 중복 실행이나 데이터 유실

송민성6분 읽기

1. 개념

Cold Observable은 구독자(subscriber)가 구독(subscribe)하는 시점에 데이터 생산이 시작되는 Observable이다. 구독자마다 독립적인 실행이 처음부터 다시 일어난다.

Hot Observable은 구독 여부와 상관없이 데이터가 생산되고 있으며, 구독자는 그 시점부터 흘러나오는 데이터를 함께 받아보는 Observable이다. 즉 하나의 실행을 여러 구독자가 공유한다.

비유하자면 Cold Observable은 넷플릭스 다시보기와 같다. 누가 언제 재생 버튼을 누르든 그 사람은 처음부터 영상을 본다. Hot Observable은 생방송 TV와 같다. 채널을 언제 틀든 그 시점에 방송되고 있는 장면부터 보게 된다.

2. 왜 사용하는가

이 구분이 필요한 이유는 "같은 Observable을 여러 곳에서 구독했을 때 어떤 일이 벌어지는가"를 예측하기 위해서다.

예를 들어 HTTP 요청을 감싼 Observable을 두 군데에서 구독하면, Cold Observable이라면 요청이 두 번 나가고, Hot Observable이라면 한 번의 요청 결과를 두 구독자가 나눠 받는다. 이 차이를 모르고 코드를 작성하면 서버에 불필요한 요청을 두 번 보내거나, 반대로 실시간 데이터를 놓치는 문제가 생길 수 있다.

3. 동작 원리

Cold Observable은 new Observable(subscriber => { ... }) 형태로 만들었을 때, 내부 콜백 함수가 subscribe가 호출될 때마다 매번 새로 실행된다. 각 구독자는 독립적인 실행 컨텍스트를 가지므로, 타이머든 배열 순회든 처음부터 다시 시작한다.

Hot Observable은 내부적으로 하나의 실행 흐름(예를 들면 이벤트 리스너나 소켓 연결)을 가지고 있고, 여러 구독자는 그 실행 흐름에 "귀를 기울이는" 역할만 한다. RxJS에서는 Subject가 대표적인 Hot Observable 역할을 한다. Subject는 자신을 구독한 모든 구독자에게 동일한 값을 동시에 전달(멀티캐스트, multicast)한다.

Cold를 Hot으로 바꾸고 싶을 때는 share 같은 연산자를 사용해서 하나의 실행을 여러 구독자가 공유하도록 만들 수 있다.

4. 예제

Cold Observable의 동작을 확인하려면 먼저 new Observable(subscriber => { const time = Date.now(); subscriber.next(time); }) 형태로 현재 시각을 방출하는 Observable을 만든다.

그다음 이 Observable을 source$.subscribe(value => console.log('구독자 A:', value))로 한 번 구독하고, 약간의 시간이 지난 뒤 source$.subscribe(value => console.log('구독자 B:', value))로 또 구독한다. 두 구독자가 받는 시각 값은 서로 다르게 찍힌다. 구독할 때마다 내부 콜백이 새로 실행되기 때문이다.

이번에는 Hot Observable을 확인해본다. 먼저 const subject = new Subject()로 Subject를 만든다. 그다음 subject.subscribe(value => console.log('구독자 A:', value))로 구독자 A를 등록하고, subject.next(1)을 호출해서 값 1을 흘려보낸다. 이 시점에 구독자 A만 1을 받는다.

그 후 subject.subscribe(value => console.log('구독자 B:', value))로 구독자 B를 뒤늦게 등록하고, subject.next(2)를 호출하면 이번에는 구독자 A와 B가 동시에 2를 받는다. 구독자 B는 이전에 흘러간 1을 받지 못한다. 이것이 Hot Observable의 특징이다.

5. 실무 사용 사례

HTTP 요청을 다루는 라이브러리 대부분은 Cold Observable을 기본으로 사용한다. 예를 들어 Angular의 HttpClient가 반환하는 Observable은 Cold이기 때문에, 같은 Observable을 두 번 구독하면 실제로 네트워크 요청이 두 번 나간다. 이런 경우 shareshareReplay 연산자로 요청 결과를 캐싱하고 공유해서 중복 요청을 막는다.

반대로 마우스 클릭, 웹소켓 메시지, 실시간 센서 데이터처럼 이미 외부에서 발생하고 있는 이벤트를 다룰 때는 Hot Observable 성격을 가진 SubjectfromEvent(DOM 이벤트 기반)를 사용해서 여러 구독자가 같은 이벤트 흐름을 동시에 관찰하게 만든다.

6. 주의할 점

Cold Observable을 여러 번 구독하면서도 "한 번만 실행되겠지"라고 착각하는 것이 가장 흔한 실수다. 특히 HTTP 요청이나 파일 읽기처럼 부수 효과(side effect)가 있는 로직을 Cold Observable로 감쌌다면, 구독 횟수만큼 부수 효과가 반복된다는 점을 항상 염두에 둬야 한다.

반대로 Hot Observable은 구독 시점 이전에 발생한 값을 놓친다는 점을 주의해야 한다. Subject를 구독하기 전에 이미 지나간 값은 다시 받을 수 없으므로, 늦게 구독한 값까지 받아야 한다면 BehaviorSubjectReplaySubject 같은 변형을 검토해야 한다.

7. 핵심 정리

Cold Observable은 구독할 때마다 실행이 새로 시작되고 구독자마다 독립적인 데이터를 받는다. Hot Observable은 이미 진행 중인 하나의 실행을 여러 구독자가 공유하며, 구독 시점 이후의 값만 받을 수 있다. 이 차이를 이해하면 HTTP 요청 중복 실행 방지, 실시간 이벤트 공유 같은 실무 문제를 정확하게 설계할 수 있다.

© 2026 Tyler Song