Cache and Multicast HTTP Requests with RxJS shareReplay
When several components need the same HTTP data, each subscription can fire a new request. RxJS’s shareReplay can multicast a single call and cache the result. This guide explains how to use shareReplay, shows a concrete example, discusses trade‑offs, and gives actionable steps for real‑world use.
02 Jul 2026, 14:08 UTC

Problem: Multiple Subscribers, One HTTP Call
In a reactive UI, it’s common to have several components that need the same data from a REST endpoint. If each component subscribes to the observable returned by ajax.getJSON, the HTTP request will fire every time, consuming bandwidth and potentially causing race conditions if the responses arrive out of order.
Thesis: shareReplay Multicasts and Caches
The shareReplay operator turns a cold observable into a hot one that multicasts a single source execution to all subscribers and replays the last value(s) to new ones. By configuring bufferSize and refCount, you can achieve a shared HTTP request that is executed once and reused.
Understanding shareReplay({bufferSize, refCount})
- bufferSize: How many emissions to keep in memory. For a single HTTP GET,
1is sufficient. - refCount: When set to
true, the source observable is subscribed to only when the first downstream subscriber appears, and unsubscribed when the last one disappears. This prevents the source from staying alive forever. - In RxJS 7.5+,
shareReplayswitched from a “legacy” implementation that always replayed cached values to a new implementation that respectsrefCountandbufferSizesemantics. Older code that usedshareReplay(bufferSize)may now behave differently.
How to Wire It Up
import { ajax } from 'rxjs/ajax';
import { shareReplay } from 'rxjs/operators';
// Replace <URL> with your endpoint.
const apiUrl = '<URL>';
export const cachedUser$ = ajax.getJSON(apiUrl).pipe(
// Keep the last emission and automatically manage subscription.
shareReplay({ bufferSize: 1, refCount: true })
);
Place this in a shared service or module so that every component imports cachedUser$.
Worked Example: Two Components Subscribe
- Component A mounts and subscribes to
cachedUser$. The HTTP request is sent. - After 1 s, Component B mounts and subscribes. The cached value is replayed immediately; no new request is made.
- Both components receive the same data stream.
To verify that only one request occurs, open the browser’s Network panel or set up a mock server that logs requests. You should see a single GET entry, even after both subscriptions.
Trade‑offs and Limitations
- Memory Footprint: The cached value remains until the last subscriber unsubscribes. If the source emits many values or large payloads, this can grow quickly.
- Stale Data: shareReplay does not automatically refresh. If the underlying data changes on the server, clients will continue to see the old value until they unsubscribe and resubscribe.
- RefCount Re‑Execution: With
refCount: true, if all subscribers unsubscribe, the source observable is torn down. A new subscriber later will trigger a fresh HTTP call. This is desirable for short‑lived components but may be problematic if you expect long‑term caching. - Error Replay: If the source emits an error, that error is replayed to all future subscribers. Ensure error handling logic is appropriate for your use case.
Actionable Take‑away
Use shareReplay({ bufferSize: 1, refCount: true }) when:
- The data is relatively static (e.g., configuration or user profile).
- Multiple components or services need the same result.
- You can tolerate a single point of failure (the HTTP request).
Monitor memory usage in long‑running applications and consider manual cache invalidation or a time‑to‑live strategy if data can become stale. For highly dynamic data, a different caching strategy (e.g., a dedicated service with explicit refresh) may be more appropriate.
Quick Checklist
- Use RxJS 7.5+ to get the new
shareReplaysemantics. - Set
bufferSize: 1for single‑value HTTP calls. - Enable
refCount: trueto avoid leaking subscriptions. - Verify network traffic to confirm only one request is made.
- Plan for cache invalidation if data changes.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.