What Is Request Coalescing and Why Duplicate Work Should Share One Result
Request coalescing means that when several requests ask for the same thing at the same time, the work is done once and every one of them gets the answer. The other requests don’t queue up behind the first and repeat it. They attach to it.
It sounds like a cache, and it’s related, but it works at a different moment. A cache helps after the answer exists. Coalescing helps while the answer is still being made, which is exactly when duplicates hurt most: a slow report, an expensive API call, a page that a thousand visitors hit the second it expires from the cache.

Where You Already Meet It
Web caches have done this for years. When a popular page expires, nginx’s proxy_cache_lock lets one request go to the backend and holds the rest until it returns, and Varnish coalesces requests for the same object the same way. Without it, a busy site’s backend gets a “thundering herd” every time something expires.
In Go, the standard answer is singleflight, from golang.org/x/sync. Callers that ask for the same key at the same time share a single function call and its result. It’s tiny and it works well.
Payment APIs come at the same problem from the other side. A client sends an idempotency key with a request, and if the request is repeated, after a timeout say, the server returns the first answer instead of charging the card twice.
What Those Leave Out
Each of these covers part of the problem. singleflight lives in one process’s memory: if the process crashes or restarts in the middle, the work is lost, and a second process never knew it was happening. A web cache’s lock lasts seconds and only covers fetching a URL. Idempotency keys stop the second request, but somebody still has to build the storage and the rules behind them.
What’s missing is a record of the work itself, written down before anyone is told it exists. It needs to say what was asked for, who is running it, how many attempts it has had and what came back, so that any process can find it, wait on it, take it over when its worker dies, or read the result long after.
Doing It Durably
That’s the job TaskFused does. Each piece of work gets a name: a namespace, a handler, the handler’s version and a key. The first request with that name creates an operation in a local SQLite file. Equal requests join it. A worker runs it on a lease, and if the worker dies, another one takes over under the same ID once the lease runs out. When it finishes, the result is stored, and later requests with the same name get it straight away.
Two rules keep it honest. First, a name is bound to its input: the same name with different input is refused, so two different pieces of work can never end up sharing an answer. Second, TaskFused runs work at least once, and it doesn’t promise exactly once. A worker that dies after doing the work but before saving it means the work runs again. Joining never causes an extra run, but crashes can, so anything with outside effects should use the operation ID as its idempotency key.
When It’s Worth It
Coalescing pays when work is expensive and repeats close together: reports and exports, calls to paid AI or data APIs, rendering, imports, anything a user can trigger twice by impatience. It doesn’t help with work that is cheap, or where every request really is different. The skill is in choosing the name. Too narrow and nothing shares; too broad and different requests collide, and TaskFused stops that as a conflict before it can hand back the wrong result.
The quick start shows two identical requests sharing one run, in about five minutes.