DEV Community

Benjamin Arambide
Benjamin Arambide

Posted on

2

Understanding RxJS: Cold and Hot Observables

In RxJS, observables are cold by default, meaning that each subscription to an observable creates an independent execution of the observable's logic. This is why you see the map operator's logic being executed for each subscription. Each subscriber gets its own independent stream of emissions from the source observable.

Cold Observables

A cold observable is one where the data producer (the logic inside the observable) is created anew for each subscriber. This means that if you subscribe to a cold observable multiple times, each subscription will re-execute the observable's logic independently.

Example of Cold Observable

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

const source$ = of(1).pipe(
  map(value => {
    console.log('map called');
    return value * 2;
  })
);

source$.subscribe(value => console.log('Subscriber 1:', value));
source$.subscribe(value => console.log('Subscriber 2:', value));
Enter fullscreen mode Exit fullscreen mode

Output

map called
Subscriber 1: 2
map called
Subscriber 2: 2
Enter fullscreen mode Exit fullscreen mode

In this example, the map operator's logic is executed twice, once for each subscription.

When to use:

  • When you want each subscription to receive all the data from the beginning.
  • When you want to repeat the data for each new subscriber.
  • Examples: HTTP requests, mouse clicks, timer observables.

Hot Observables

A hot observable, on the other hand, shares a single execution of the observable's logic among all subscribers. Using operators like share, shareReplay, or publish can convert a cold observable into a hot observable.

Example of Hot Observable with shareReplay

import { of } from 'rxjs';
import { map, shareReplay } from 'rxjs/operators';

const source$ = of(1).pipe(
  map(value => {
    console.log('map called');
    return value * 2;
  }),
  shareReplay(1) // Shares the last emitted value with all subscribers
);

source$.subscribe(value => console.log('Subscriber 1:', value));
source$.subscribe(value => console.log('Subscriber 2:', value));

Enter fullscreen mode Exit fullscreen mode

Output

map called
Subscriber 1: 2
Subscriber 2: 2
Enter fullscreen mode Exit fullscreen mode

In this example, the map operator's logic is executed only once, and the result is shared among all subscribers.

When to use:

  • When you want subscribers to receive only values that are emitted after they subscribe.
  • When you don't want each subscriber to get its own independent stream of values.
  • Examples: WebSocket streams, mouse move events, stock tickers.

Choosing Between Hot and Cold Observables

  • Cold Observables are typically used when you want to ensure that each subscriber gets all the data and/or when the data source is created anew for each subscriber.

  • Hot Observables are useful when you want to share a single execution of the observable among multiple subscribers, or when you're dealing with data sources that are already producing events.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more