What Is shareReplay in RxJS and How Can It Silently Break Your Angular App?

LowEasyAngular
Preparing for interviews?

Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.

Quick Answer

shareReplay is an RxJS operator that turns a cold observable into a shared hot one and caches the last emitted values. Used incorrectly, it can cause memory leaks, stale data bugs, and unexpected behavior—especially in Angular services and HTTP streams.

Answer

Core idea

shareReplay does two things at once:
• It shares a single subscription among multiple subscribers.
• It replays the last N emitted values to new subscribers.

This is extremely useful for caching HTTP calls—but also extremely easy to misuse.

The classic Angular use-case

You want multiple components to consume the same HTTP data without triggering multiple requests.

TYPESCRIPT
users$ = this.http.get<User[]>('/api/users').pipe(
  shareReplay(1)
);
                  

What problem does this solve?

Without shareReplay, every subscribe() or async pipe would trigger a new HTTP request. With shareReplay(1), the first request is cached and reused.

Behavior

Without shareReplay

With shareReplay(1)

Second subscriber

Triggers new HTTP request

Gets cached value

Third subscriber

Triggers new HTTP request

Gets cached value

Network usage

Many duplicate calls

Single call

Why people use shareReplay

How shareReplay can silently break your app

Problem

Why it happens

Symptom in real apps

Memory leaks

By default, shareReplay keeps the source subscribed forever.

Services never released, websockets/intervals never stop.

Stale data

Cached value is reused even when data should refresh.

User navigates away/back and sees outdated data.

Error caching

If the source errors, the error is also replayed.

Stream is permanently broken until reload.

Unexpected global state

shareReplay turns cold streams into hot singletons.

Components influence each other indirectly.

The hidden dangers

The most important option: refCount

Modern RxJS lets you write:

TYPESCRIPT
users$ = this.http.get<User[]>('/api/users').pipe(
  shareReplay({ bufferSize: 1, refCount: true })
);
                  

What does refCount: true do?

It tells RxJS: “When there are no subscribers left, unsubscribe from the source and free resources.” Without this, the source stays alive forever.

Configuration

When last subscriber unsubscribes

Memory behavior

shareReplay(1)

Source stays subscribed

❌ Potential leak

shareReplay({ bufferSize: 1, refCount: true })

Source unsubscribes

✅ Safe cleanup

Why refCount matters

Another subtle trap: error caching

If the HTTP call errors once, shareReplay will replay that error forever. All future subscribers instantly get the error, and the stream never retries unless you rebuild it or add retry logic.

TYPESCRIPT
users$ = this.http.get<User[]>('/api/users').pipe(
  retry(1),
  shareReplay({ bufferSize: 1, refCount: true })
);
                  

Senior rule of thumb

• Use shareReplay for caching expensive or shared streams.
• Prefer { bufferSize: 1, refCount: true } unless you intentionally want a forever-alive cache.
• Be explicit about refresh/invalidation semantics.
• Never blindly slap shareReplay(1) everywhere.

Angular scenario

Should you use shareReplay?

How

Config loaded once at app startup

✅ Yes

shareReplay(1) without refCount may be OK

User-specific API data

⚠️ Be careful

Use refCount or explicit refresh trigger

WebSocket / interval stream

❌ Usually dangerous

You probably want manual lifecycle control

HTTP list used by many components

✅ Yes

shareReplay({ bufferSize: 1, refCount: true })

When to use shareReplay in Angular

Interview summary

shareReplay shares a single subscription and caches the last values. It is great for avoiding duplicate HTTP calls, but can cause memory leaks, stale data, and permanent error states if used carelessly. In Angular, the safe default is shareReplay({ bufferSize: 1, refCount: true }) and a clear cache invalidation strategy.

Similar questions
Guides
32 / 37