An observable is a pattern in programming that allows us to subscribe to a stream of data, such as a stream of mouse clicks or a stream of API responses. There are two main types of observables: hot observables and cold observables.
Difference between hot and cold observables
A hot observable is an observable that is already emitting data, even before anyone has subscribed to it. An example of a hot observable is a mouse click event, which is generated regardless of whether anyone is listening for it.
On the other hand, a cold observable is an observable that only begins emitting data when someone has subscribed to it. An example of a cold observable is a data stream from an API, which only begins emitting data when someone has requested that data.
In general, hot observables are used in situations where data is generated independently of any subscriber, whereas cold observables are used in situations where data is generated in response to a subscriber.
One important thing to note is that, if a cold observable is subscribed to multiple times, it will start emitting data multiple times. This is not the case with hot observables, which will only emit the same data once.
Cold observable:
- A cold observable creates a data producer for each subscriber
- Each consumer receives data from his own producer. No values are missed in case of a cold Observable.
- There is one source per subscriber. When subscribing to a cold source, the entire pipeline gets recreated for each subscriber. (if your pipeline is computation heavy, then you’d be doing that computation every time a new subscriber subscribes to that source)
Hot observable:
- A hot observable creates a data producer first
- Each subscriber gets the data from one producer, starting from the moment of subscription (all the previous data are lost)
- The pipeline doesn’t get recreated for each subscriber. Hot sources are useful for when you don’t want to compute the pipeline for every subscriber. The pipeline will be computed once, and then the answer will be sent to all subscribers.
Pipeline execution in Hot and Cold observables
Let’s dig deeper into the third point of the above-reported lists.
When working with observables, it’s common to use operators like map, filter, and reduce to transform and filter the data emitted by the observable. These operators form a pipeline that processes the data before it reaches the subscriber.
When you create a cold observable, the pipeline is created for each subscriber. This means that if you have two subscribers, the pipeline will be computed twice, once for each subscriber. This can be inefficient if the pipeline is computationally expensive.
On the other hand, with a hot observable, the pipeline is created only once, regardless of the number of subscribers. This means that the pipeline is only computed once, and all subscribers receive the same processed data. This can be more efficient if the pipeline is computationally expensive, or if you have a large number of subscribers.
Let’s dive into the code.
Cold observable:
import { map, Subject } from 'rxjs';
import { tap } from 'rxjs/operators';
const subject = new Subject<number>();
const cold$ = subject.pipe(
map((x) => Math.random() * x),
tap(() => console.log('performed computation'))
);
cold$.subscribe((x) => console.log(`Sub 1: ${x}`));
cold$.subscribe((x) => console.log(`Sub 2: ${x}`));
cold$.subscribe((x) => console.log(`Sub 3: ${x}`));
subject.next(100);We have then subscribed three times to this cold observable.
When we call subject.next(100) it emits the value 100, this value is passed to the cold observable, the map operator multiplies it by a random number, and the tap operator logs “performed computation” on the console. This process is repeated for each subscription, so we will see the log “performed computation” printed three times on the console, once for each subscriber.
And also, each subscription will receive a different random number, as the random number is generated every time the cold observable is subscribed to, this is why we will see different values for Sub 1, Sub 2 and Sub 3.

Hot observable:
import { Subject } from 'rxjs';
import { map, tap, share } from 'rxjs/operators';
const subject = new Subject<number>();
const hot$ = subject.pipe(
map((x) => Math.random() * x),
tap(() => console.log('performed computation')),
share()
);
hot$.subscribe((x) => console.log(`Sub 1: ${x}`));
hot$.subscribe((x) => console.log(`Sub 2: ${x}`));
hot$.subscribe((x) => console.log(`Sub 3: ${x}`));
subject.next(100);The share operator makes the observable hot, so the pipeline is only created once, and the values are emitted to all subscribers.
We have then subscribed three times to this hot observable.
When we call subject.next(100) it emits the value 100, this value is passed to the hot observable, the map operator multiplies it by a random number, and the tap operator logs “performed computation” on the console. This process is only performed once, so we will see the log “performed computation” printed only once on the console.
And also, all subscriptions will receive the same random number, as the random number is generated only once when the hot observable is created, this is why we will see the same value for Sub 1, Sub 2 and Sub 3.

