Memory Checkpoint

Find the Leak in the Email Service

Reasoning Checkpoint

A design challenge, worked through in writing — no auto-grading, just a real attempt.

15–20 min

The Challenge

A week later, BlueTicket's email service starts slowing down every afternoon and restarts itself every evening. John hands Anna its memory graph and the suspicious piece of code.

The graph: memory goes up and down all day, but each low point is higher than the last — from 150 MB in the morning to 1.8 GB by evening.

The code: there's a global array, const sentEmails = [];. Every time sendEmail runs, it builds an email object (recipient, subject, the full body and the time), delivers it, and then runs sentEmails.push(email). The admin dashboard shows recent emails with sentEmails.slice(-20) — the last 20.

What Your Answer Needs

  • Read the graph: say whether this is healthy or a leak, and what in the graph tells you.
  • From the code described above, name the line that leaks and explain, using reachability, why the garbage collector can't free the old emails.
  • Explain the bug with one of this Act's analogies (hotel rooms, a tap left running, the restaurant...).
  • Propose a fix that still lets the dashboard show recent emails.
  • Explain how you would prove the fix works.
Stuck? A Few Hints
  • "Recent" doesn't mean "every email ever sent."
  • A global array is always reachable — and so is everything in it.
  • Think about the two graph shapes from the last chapter.

Before You Move On

This is the same bug as the 3 AM crash, wearing a different coat: a long-lived structure that only ever grows. Once you've seen it twice, you'll spot it everywhere — in caches, lists of "recent" things, and listeners. The fix is always to decide how long each thing should live, and let go of it after that.