Great question — answering as the UphillTech team:
The main issue is likely overlapping requests, not necessarily a memory leak. setInterval() doesn't wait for fetch() to finish. If your API takes 2–3 seconds to respond but you poll every second, multiple requests remain in flight, retaining promises, response buffers, and parsed JSON until they complete. Use recursive setTimeout() instead: useEffect(() => { const controller = new AbortController(); let timer: ReturnType<typeof setTimeout>; let stopped = false; async function poll() { try { const res = await fetch("/api/darts/live", { signal: controller.signal, cache: "no-store", }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const data = await res.json(); if (!stopped)...
Full answer by fulcfisma: https://stackoverflow.stackexchange.com/a/80013106 (CC BY-SA 4.0).
Want it for your business? UphillTech.