# request deduplication: a worked example

Canonical page: https://vibe-coding-101.brighteng.org/c/request-deduplication/#before-and-after

## The problem

Two components request the same profile at the same time. We want one underlying read while it is pending, but different users must never share a response and a failed read must be retryable.

## Prompt to paste

Deduplicate these equivalent requests through the existing query cache. Verify one network call and preserve user-specific cache keys.

## Before

Each caller invokes the loader independently. Equivalent concurrent reads start twice, even though both callers need the same result.

## After

Keep a promise for each equivalent read within one owner. Include user identity and resource identity in the key. Return the existing pending promise, then remove it on either success or failure so later calls can refresh.

## Run the check

Save the following code as request-deduplication.mjs and run `node --test request-deduplication.mjs` with Node.js 22.12 or later.

```js
import test from 'node:test';
import assert from 'node:assert/strict';

function before(load) {
  return (user, resource) => load(user, resource);
}

function after(load) {
  const pending = new Map();
  return (user, resource) => {
    const key = JSON.stringify([user, resource]);
    if (!pending.has(key)) {
      const request = Promise.resolve()
        .then(() => load(user, resource))
        .finally(() => pending.delete(key));
      pending.set(key, request);
    }
    return pending.get(key);
  };
}

test('equivalent callers start two reads without deduplication', async () => {
  let calls = 0;
  const read = before(async () => { calls++; return 'profile'; });
  await Promise.all([read('alice', 'profile'), read('alice', 'profile')]);
  assert.equal(calls, 2);
});

test('reads share only within scope and failures do not stick', async () => {
  let calls = 0;
  const read = after(async (user) => { calls++; return user; });
  const a = read('alice', 'profile');
  const b = read('alice', 'profile');
  assert.equal(a, b);
  assert.deepEqual(await Promise.all([a, b, read('bob', 'profile')]),
    ['alice', 'alice', 'bob']);
  assert.equal(calls, 2);
  await read('alice', 'profile');
  assert.equal(calls, 3);
  let attempts = 0;
  const retry = after(() => {
    if (++attempts === 1) throw new Error('offline');
    return 'recovered';
  });
  const failed = await Promise.allSettled([retry('alice', 'profile'), retry('alice', 'profile')]);
  assert.deepEqual(failed.map((item) => item.status), ['rejected', 'rejected']);
  assert.equal(attempts, 1);
  assert.equal(await retry('alice', 'profile'), 'recovered');
  assert.equal(attempts, 2);
});
```

## Expected result

Two equivalent concurrent calls produce two loader calls before and one shared call afterward. Different users remain separate. Settled reads are removed, and a shared rejected read can be tried again.

## Limits

This in-memory example shares pending reads in one owner only. It is not a persistent cache, a distributed lock, or an idempotency guarantee for writes. Include every result-changing input in the key; create the owner inside the correct account or request lifetime. Decide how cancellation works when several consumers share one promise. Prefer an existing query cache when it already provides the needed lifecycle.

## Sources

- [MDN: Promise.prototype.finally](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally): Cleanup runs when a promise settles. The scoped map and behavior checks are original examples.

Sources checked: 2026-10-11. These are original illustrative examples with automated checks. Human editorial approval is not recorded. Policy: https://vibe-coding-101.brighteng.org/editorial/
