tezvyn:

Angular Universal server memory leak: causes and diagnosis

AI-drafted, machine-checkedintermediate
WHAT IT TESTS

Angular SSR platform lifecycle in Node.js and cross-request retainers.

ANSWER OUTLINE

incomplete platform destruction, global DOM polyfills, unclosed RxJS; use heap snapshots and --inspect.

RED FLAG

blaming Angular, not citing request cleanup.

WHAT THIS TESTS: The interviewer wants to know if you understand that server-side rendering in Angular Universal is stateful per request. Unlike a browser tab that reloads, the Node process stays alive, so any object retained after a request finishes will accumulate. The question probes your knowledge of the Angular platform lifecycle on the server, the difference between browser and server DI scoping, and your ability to use Node-specific profiling tools rather than browser DevTools alone.

A GOOD ANSWER COVERS: First, explain that Angular Universal bootstraps a separate platform and NgModuleRef for every incoming request. If the server code fails to call platform.destroy() or moduleRef.destroy() after rendering, the entire application context and its component tree are retained in the heap. Second, mention global event listeners or DOM polyfills. Because Angular Universal uses a server DOM implementation like Domino, attaching listeners to global or document objects outside Angular's zone can create detached DOM nodes that survive garbage collection. Third, discuss unclosed RxJS subscriptions, setInterval timers, or unresolved promises that hold references to services or components after the response is sent. Fourth, for diagnosis, describe running the Node process with the --inspect flag, capturing heap snapshots under load with Chrome DevTools, and comparing retained objects between snapshots to find leaking constructors or detached DOM trees. Mention using server-side memory logging with process.memoryUsage() to correlate leak growth with request volume.

COMMON WRONG ANSWERS: A red flag is treating the server like a browser and suggesting Chrome Performance tabs on the client side. Another mistake is blaming Angular's change detection without explaining how server platforms differ from the browser platform. Candidates who only mention setState or componentWillUnmount patterns from React show framework confusion. Saying restart the server to fix it misses the architectural point entirely.

LIKELY FOLLOW-UPS: The interviewer may ask how you would automate leak detection in CI, how to handle third-party libraries that register global listeners, or what changes between Angular versions affect platform destruction. They might also ask for the specific flags passed to the Node runtime or how to read a heap snapshot retainers view to distinguish between a true leak and normal caching.

ONE CONCRETE EXAMPLE: A typical leak occurs when a shared logging service subscribes to a global error stream in its constructor. On the server, the service is instantiated once per request if provided in a lazy-loaded module, but the subscription is never torn down. After ten thousand requests, ten thousand error handlers remain in memory. To find it, you would start the server with node --inspect, trigger a baseline heap snapshot, send a batch of requests, take a second snapshot, and filter by the service name in the Comparison view. The fix is to move the subscription into ngOnInit and unsubscribe in ngOnDestroy, or use a takeUntil pattern tied to the application ref's onDestroy event.

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.