ScopedValue: The ThreadLocal Replacement Java 25 Finalized

In the ThreadLocal leak post, ScopedValue was the third fix — two paragraphs and a filter snippet. This is the full treatment, because JDK 25 changed its status: after an incubator round in JDK 20 and previews in JDK 21–24, JEP 506 made java.lang.ScopedValue final in JDK 25. No preview flag. No incubator module. It is now part of the platform. First, the honest framing. “Replacement” comes with an asterisk: JEP 506 explicitly does not deprecate ThreadLocal, and migration is not a goal for every use. ScopedValue replaces the dominant request-context pattern: bind an immutable value at an entry point, let callees read it, and guarantee it disappears when that operation ends. It does not replace per-thread mutable caches, accumulators that callees update for a caller, or values that must outlive the method that created them. That distinction is the whole article. Get it right and ScopedValue removes a bug class. Treat it as a nicer global variable and you will recreate the ThreadLocal mess with newer syntax. ...

2026-10-23 · 15 min · Ramesh

Floyd's Tortoise and Hare: Linked List Cycle Detection in Java, With the Proof

“Detect a cycle in a linked list.” Everyone recites it: slow moves one step, fast moves two, if they meet there’s a cycle. Then the interviewer says “why can’t fast skip over slow?” and the room goes quiet. Then “find where the cycle starts” — and the memorized answer runs out. Floyd’s tortoise and hare is a two-minute algorithm with a twenty-minute understanding. Here’s the understanding. The shallow answer (and why interviewers hate it) The HashSet version works and every candidate knows it: ...

2026-10-17 · 6 min · Ramesh

The ThreadLocal Leak: Why Your Spring Boot Heap Grows Until the 3 A.M. Restart

The symptom is always the same: heap usage climbs a little every day, GC reclaims less and less, and eventually someone sets a cron to restart the service at 3 AM. The heap dump shows nothing obviously wrong — no giant cache, no runaway collection. Just thousands of ordinary objects that should have died with their requests, all reachable through one path: Thread → ThreadLocalMap → Entry. This is the ThreadLocal leak, and it’s the quietest memory leak in Java. ...

2026-10-16 · 9 min · Ramesh

Dead Letter Queues: Where Your Poison Messages Actually Go

Every message-driven system eventually meets its poison message: one malformed payload, one downstream bug, one record that will never process successfully — retried forever, burning CPU, and in the worst designs blocking every message queued behind it. The dead letter queue is the answer, but “just add a DLQ” hides three decisions: how many attempts before giving up, what counts as an attempt, and who gets woken up when something lands in the DLQ. Get any of them wrong and the DLQ is theater. ...

2026-10-14 · 8 min · Ramesh

HashMap Internals: The Questions That Expose Shallow Knowledge

“How does HashMap work?” opens half of all Java interviews. Most candidates answer “array of linked lists, O(1) lookup” — and then the follow-ups start, and the room gets quiet. The interviewers aren’t testing whether you’ve memorized the structure. They’re testing whether you know why it’s built the way it is. Here are the questions that expose shallow knowledge, with the answers that don’t. Question 1: Why does HashMap mangle your hashCode? Everyone knows hashCode() feeds the map. Almost nobody asks what HashMap does to it first: ...

2026-10-13 · 8 min · Ramesh