> ## Documentation Index
> Fetch the complete documentation index at: https://cosmo-docs.wundergraph.com/llms.txt
> Use this file to discover all available pages before exploring further.

# @defer

> The @defer directive marks a fragment that the router delivers after the initial response, in a later part of the same HTTP response.

## Definition

```graphql theme={"system"}
directive @defer(
  if: Boolean! = true
  label: String
) on FRAGMENT_SPREAD | INLINE_FRAGMENT
```

## Arguments

| Argument | Type       | Default | Description                                                                                                                                               |
| -------- | ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `if`     | `Boolean!` | `true`  | Controls whether the router defers the fragment. Accepts a literal or a variable. With `false`, the router delivers the fragment in the initial response. |
| `label`  | `String`   |         | A static string that identifies the fragment in the response. The router returns it on the `pending` entry of the fragment.                               |

## Overview

`@defer` is an executable directive.
Clients use it in operations, not in subgraph schemas.
It marks a fragment whose fields the client does not need in the initial response.
The router returns all other fields in the initial response.
The router delivers the deferred fragment in a later part of a `multipart/mixed` response.

The router provides the directive when you set `engine.enable_defer` to `true`.
You change no subgraph and no composition.
See [Defer](/router/defer) for the router configuration and the response format.

The [Incremental Delivery spec draft](https://github.com/graphql/graphql-spec/pull/1110) defines `@defer`.
The draft is at RFC stage 2 of the GraphQL specification process.
The router follows the response format of that draft.

### Supported locations

* **Inline fragments** without a type condition: `... @defer { ... }`.
* **Inline fragments** with a type condition: `... on Product @defer { ... }`.
* **Fragment spreads**: `...ProductReviews @defer`.

### Supported operations

* **Queries**, on root fields and on nested fields.
* **Mutations**, on nested fields below the root selection set.

## Examples

### Example schema

```graphql theme={"system"}
type Query {
  product(id: ID!): Product
}

type Product @key(fields: "id") {
  id: ID!
  name: String!
  reviews: [Review!]!
}

type Review {
  rating: Int!
  body: String!
}
```

### Deferring an inline fragment

```graphql theme={"system"}
query ProductPage {
  product(id: "1") {
    id
    name
    ... @defer {
      reviews {
        rating
        body
      }
    }
  }
}
```

The response has two parts.
The initial response carries `id` and `name`.
It announces the deferred fragment:

```json theme={"system"}
{
  "data": { "product": { "id": "1", "name": "Router" } },
  "pending": [{ "id": "1", "path": ["product"] }],
  "hasNext": true
}
```

The incremental response delivers the fragment and completes it:

```json theme={"system"}
{
  "incremental": [
    {
      "data": { "reviews": [{ "rating": 5, "body": "Fast." }] },
      "id": "1"
    }
  ],
  "completed": [{ "id": "1" }],
  "hasNext": false
}
```

### Deferring a fragment spread

```graphql theme={"system"}
query ProductPage {
  product(id: "1") {
    id
    name
    ...ProductReviews @defer
  }
}

fragment ProductReviews on Product {
  reviews {
    rating
    body
  }
}
```

### Using Labels

```graphql theme={"system"}
query ProductPage {
  product(id: "1") {
    id
    ... @defer(label: "reviews") {
      reviews {
        rating
      }
    }
  }
}
```

The router returns the label on the `pending` entry:

```json theme={"system"}
{
  "data": { "product": { "id": "1" } },
  "pending": [{ "id": "1", "path": ["product"], "label": "reviews" }],
  "hasNext": true
}
```

### Conditional defer

```graphql theme={"system"}
query ProductPage($deferReviews: Boolean!) {
  product(id: "1") {
    id
    ... @defer(if: $deferReviews) {
      reviews {
        rating
      }
    }
  }
}
```

With `deferReviews: true`, `reviews` arrives in an incremental response.
With `deferReviews: false`, `reviews` belongs to the initial response.
The router then sends a single JSON response.

## Rules

* A `label` is a static string.
  The router does not accept a variable as a label.
* Labels must be unique across all `@defer` and `@stream` directives in the document.
* The client can select the same field inside and outside a deferred fragment on the same object.
  The router then delivers the field in the initial response and drops the deferred copy.
* A deferred fragment without field selections has no effect.
* `if` accepts a literal or a variable.
  The router resolves the variable value per request.
  The value belongs to the cache key of the query plan.

## Federation behavior

The router handles `@defer` itself.
It plans the deferred fragment as a separate set of subgraph fetches.
Those fetches run after the router sends the initial response.

A deferred fragment can select fields of an entity that another subgraph owns.
The router then fetches the entity key in the primary phase.
It uses that key as the representation for the deferred entity fetch.
Subgraphs never receive the `@defer` directive.

See [How the Router Executes @defer](/router/defer/how-it-works) for the execution model.
