Ramblings of an aging IT geek
← Ramblings of an aging IT geek
debugging

the leak was a map i forgot to empty

A long-running service slowly grew its memory until restart, and the cause was a cache that only ever got things added to it.

A terminal with a memory graph climbing

A service had developed the classic shape: memory climbing steadily across a week until it hit the limit and got restarted, then climbing again. No crash, no leak in the dramatic sense, just relentless growth. The kind of thing a cron-restart papers over until you notice you've quietly accepted a daily reboot as normal.

The cause was a map used as a cache, keyed by request ID. Every request added an entry. Nothing ever removed one. I'd written it as a quick lookup to deduplicate work within a request's lifetime and never gone back to bound it, so it was a perfect record of every request the process had ever seen, held in memory forever.

The fix was not clever. The cache only needed entries for a short window, so it became a small bounded structure with eviction, and the steady climb flattened into a sawtooth that never reaches the limit. No more nightly restart. The lesson, again, is that "cache" without "eviction" is just "leak" with a friendlier name.