---
title: "Dedupe Plugin"
description: "Prevent redundant requests by deduplicating similar in-flight requests, reducing the number of requests sent to the server."
sidebar:
  label: "Dedupe"
---

## Overview

```ts
import { DedupeLinkPlugin } from '@orpc/client/plugins'

const link = new RPCLink({
  plugins: [
    new DedupeLinkPlugin({
      groups: [
        {
          condition: () => true,
          context: {}, // Context used for the rest of the request lifecycle
        },
      ],
    }),
  ],
})
```

:::info
The `link` can be any supported oRPC link, such as [RPCLink](/docs/rpc/link), [OpenAPILink](/docs/openapi/link), or a custom one.
:::

## Filter

By default, the plugin deduplicates `GET` and `QUERY` requests. You can customize this behavior by providing a `filter` function.

```ts
const link = new RPCLink({
  plugins: [
    new DedupeLinkPlugin({
      filter: ({ request }) => request.method === 'GET',
      groups: [
        {
          condition: () => true,
          context: {},
        },
      ],
    }),
  ],
})
```

:::warning
If you are using [RPC Link](/docs/rpc/link), you might need to [customize the request method](/docs/rpc/link#request-method) because it defaults to `POST`.
:::

:::tip
If your application does not need to run multiple mutation requests in parallel within the same [call stack](https://developer.mozilla.org/en-US/docs/Glossary/Call_stack), you can expand the filter to deduplicate **all** request types.
This can also help prevent duplicate mutation requests when users click actions too quickly.
:::

## Groups

Only requests in the same group are deduplicated together. Each group also defines a `context`, as described in [client context](/docs/client/client-side#client-context).

The following example deduplicates requests by cache policy:

```ts
interface ClientContext {
  cache?: RequestCache
}

const link = new RPCLink<ClientContext>({
  method: ({ context }) => {
    if (context?.cache) {
      return 'GET'
    }

    return 'POST'
  },
  plugins: [
    new DedupeLinkPlugin({
      groups: [
        {
          condition: ({ context }) => context?.cache === 'force-cache',
          context: { // used for the rest of the request lifecycle
            cache: 'force-cache',
          },
        },
        { // Fallback for all other requests. Keep this last.
          condition: () => true,
          context: {},
        },
      ],
    }),
  ],
  fetch: (url, init, { context }) => globalThis.fetch(url, {
    ...init,
    cache: context?.cache,
  }),
})
```

Now, calls made with `cache = 'force-cache'` use that cache setting whether they are deduplicated or sent individually.

## Learn More

For implementation details, see the [source code](https://github.com/middleapi/orpc/blob/main/packages/client/src/plugins/dedupe.ts).
