DEV Community

Cover image for Hot vs Cold Observables: Getting Started with RxJS - IV
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on • Edited on

Hot vs Cold Observables: Getting Started with RxJS - IV

Hello, I'm Maneshwar. I'm working on git-lrc: a Git hook for Checking AI generated code.

I recently came across MkDocs-Material by Martin Donath, a fantastic open-source project with over 22k GitHub stars.

It’s an incredible contribution to the community, making documentation hosting effortless.

While exploring it, I got curious about how such a large project achieves reactiveness.

The stack is mostly HTML, SCSS, Preact, RxJS, and a few workers, and I saw this as the perfect opportunity to dive into RxJS—especially how it utilizes Observables and other advanced patterns.

RxJS observables come in two flavors: hot and cold.

Understanding the difference between them is crucial when working with reactive programming, as it affects how data is produced and shared among subscribers.

In this article, we’ll break down the differences with examples and show how to work with each type effectively.

Cold Observables: Fresh Data for Every Subscriber

A cold observable is one where the underlying data is created inside the observable.

This means that each subscription starts a new execution of the observable, producing unique values for each subscriber.

Example of a Cold Observable

import { Observable } from 'rxjs';

const coldObservable = new Observable(observer => {
    const randomNum = Math.random(); // Generates a new number per subscription
    observer.next(randomNum);
    observer.complete();
});

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

// Output:
// Subscriber 1: 0.645732
// Subscriber 2: 0.927384
Enter fullscreen mode Exit fullscreen mode

Each subscriber gets a different random number because the observable generates a new value each time someone subscribes.

Hot Observables: Shared Data Among Subscribers

A hot observable is one where the data is generated outside the observable.

All subscribers receive the same data and share execution, preventing redundant computations.

Example of a Hot Observable

import { Observable } from 'rxjs';

const sharedRandomNum = Math.random();

const hotObservable = new Observable(observer => {
    observer.next(sharedRandomNum);
    observer.complete();
});

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

// Output:
// Subscriber 1: 0.645732
// Subscriber 2: 0.645732
Enter fullscreen mode Exit fullscreen mode

Since the random number is generated before the observable is created, all subscribers receive the same value.

Making a Cold Observable Hot with publish()

Instead of generating data externally, we can use the publish() operator to convert a cold observable into a hot one.

import { Observable } from 'rxjs';
import { publish } from 'rxjs/operators';

const coldObservable = new Observable(observer => {
    const randomNum = Math.random();
    observer.next(randomNum);
    observer.complete();
});

const hotObservable = coldObservable.pipe(publish());

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

hotObservable.connect(); // Ensures the observable emits shared values

// Output:
// Subscriber 1: 0.845291
// Subscriber 2: 0.845291
Enter fullscreen mode Exit fullscreen mode

Calling connect() ensures that the observable emits data only once, making it behave like a hot observable.

Completing Observables & Avoiding Memory Leaks

Observables should be properly completed to avoid potential memory leaks, especially when dealing with continuous streams.

Example: Completing an Observable Automatically

Using finally(), we can detect when an observable completes:

import { timer } from 'rxjs';
import { finalize } from 'rxjs/operators';

timer(1000).pipe(
    finalize(() => console.log('Observable completed'))
).subscribe(() => console.log('Emitted value'));
Enter fullscreen mode Exit fullscreen mode

Example: Manually Unsubscribing

For infinite observables like interval(), we must manually unsubscribe to prevent leaks:

import { interval } from 'rxjs';

const subscription = interval(1000).subscribe(value => console.log(value));

setTimeout(() => {
    subscription.unsubscribe();
    console.log('Unsubscribed from observable');
}, 3000);
Enter fullscreen mode Exit fullscreen mode

After 3 seconds, the subscription stops receiving values, freeing resources.

Conclusion

  • Cold observables generate new data for each subscriber.
  • Hot observables share data among subscribers.
  • You can convert a cold observable into a hot one using publish() and connect().
  • Always handle completion and unsubscribing to prevent memory leaks.

Understanding these concepts will help you build efficient and scalable reactive applications using RxJS!

I’ll be sharing more learnings, so stick around/follow for more deep dives into RxJS and beyond! 🚀

While exploring mkdocs-material implementation, I've been learning how to adapt these techniques for a product I've been passionately working on for quite a while.

With , you can quickly generate interactive API documentation that allows users to execute APIs directly from the browser.

Return only the cleaned text without any additional commentary:

git-lrc
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.

⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Unlimited AI Code Reviews That Run on Commit

git-lrc logo

git-lrc

Free, Unlimited AI Code Reviews That Run on Commit



git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt



AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
  • 🔗 Why git? Git is universal. Every editor, every IDE, every AI…

Top comments (2)

Collapse
 
dariomannu profile image
Dario Mannu

Very nice series of intros to Observables. If you'd like to help even more people understand, appreciate and use them effectively, including less experienced developers in your audience, you might want to try Rimmel.js in some of your examples. It's just another UI library but it makes Observables soooo much easier to use and make sense of than Preact, React, and the others...

Collapse
 
lovestaco profile image
Athreya aka Maneshwar

Thanks a lot :)
I see, I'll try it out tonight.