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

# Manage the network

> Add remotes, update shard assignments, and manage your Meilisearch network topology dynamically. Includes rebalancing behavior and validation rules.

Once your [sharded cluster is set up](/resources/self_hosting/sharding/setup_sharded_cluster), you can modify the topology without restarting instances. All topology changes go through `PATCH /network` on the leader instance.

## Add a remote

Include the new remote in the `remotes` object. To assign it to an existing shard, either send the full `remotes` list for that shard, or use `addRemotes` as a convenience to append without rewriting the full list:

<CodeGroup>
  ```bash theme={null}
  curl \
    -X PATCH 'MEILISEARCH_URL/network' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer MEILISEARCH_KEY' \
    --data-binary '{
      "remotes": {
        "ms-03": {
          "url": "http://ms-03.example.com:7703",
          "searchApiKey": "SEARCH_KEY_03",
          "writeApiKey": "WRITE_KEY_03"
        }
      },
      "shards": {
        "shard-a": { "addRemotes": ["ms-03"] }
      }
    }'
  ```
</CodeGroup>

<Note>
  `addRemotes` and `removeRemotes` are write-only convenience fields. They are applied on top of the existing shard configuration and are never returned by `GET /network`, which always returns the full `remotes` list for each shard.
</Note>

## Update shard assignments

Each shard object in a `PATCH /network` request accepts three fields:

| Field           | Type  | Behavior                                                           |
| --------------- | ----- | ------------------------------------------------------------------ |
| `remotes`       | array | Full replacement of the shard's remote list                        |
| `addRemotes`    | array | Adds remotes to the existing list                                  |
| `removeRemotes` | array | Removes remotes from the existing list, applied after `addRemotes` |

Shards not included in the request are left unchanged. To remove a remote from a specific shard:

<CodeGroup>
  ```bash theme={null}
  curl \
    -X PATCH 'MEILISEARCH_URL/network' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer MEILISEARCH_KEY' \
    --data-binary '{
      "shards": {
        "shard-a": { "removeRemotes": ["ms-03"] }
      }
    }'
  ```
</CodeGroup>

To fully replace a shard's assignment, use `remotes`:

<CodeGroup>
  ```bash theme={null}
  curl \
    -X PATCH 'MEILISEARCH_URL/network' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer MEILISEARCH_KEY' \
    --data-binary '{
      "shards": {
        "shard-a": { "remotes": ["ms-00", "ms-01", "ms-03"] },
        "shard-b": { "remotes": ["ms-01", "ms-02"] },
        "shard-c": { "remotes": ["ms-02", "ms-03"] }
      }
    }'
  ```
</CodeGroup>

## Topology changes and rebalancing

When you modify shard assignments, Meilisearch triggers a `NetworkTopologyChange` task on all remotes. This task runs in three steps:

1. **Compute new shards**: each instance uses rendezvous hashing on document IDs to determine which documents belong to which shard under the new topology.
2. **Export and import**: documents are sent to remotes that now own them.
3. **Delete stale data**: once all remotes confirm their imports are complete, each instance deletes the documents it no longer owns. Search switches to the new shard definitions at this point.

Cancelling a topology change at step 3 only results in stale documents being retained temporarily. It does not cause data loss.

<Warning>
  Search requests may return incomplete results during a topology change. Wait for all `NetworkTopologyChange` tasks to complete before resuming normal search traffic.
</Warning>

## Validation

`PATCH /network` rejects requests with a `400 invalid_network_shards` error in the following cases:

* The shard list would become empty after applying the patch
* A shard's `remotes` list would become empty after applying `removeRemotes`
* A shard references a remote that is not in the `remotes` object
* A remote is removed from `remotes` and this leaves a shard with no remotes

## Filter searches by shard

Target specific shards using the `_shard` filter in search requests:

<CodeGroup>
  ```bash theme={null}
  curl \
    -X POST 'MEILISEARCH_URL/indexes/movies/search' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer MEILISEARCH_KEY' \
    --data-binary '{
      "q": "batman",
      "filter": "_shard = \"shard-a\""
    }'
  ```
</CodeGroup>

Supported `_shard` filter operators:

| Syntax                             | Behavior                                             |
| ---------------------------------- | ---------------------------------------------------- |
| `_shard = "shard-a"`               | Documents associated to `shard-a`                    |
| `_shard != "shard-a"`              | Documents associated to all shards except `shard-a`  |
| `_shard IN ["shard-a", "shard-b"]` | Documents associated to both `shard-a` and `shard-b` |

## Attribute visibility via `/network`

<Warning>
  If an attribute is not on the `displayedAttributes` list but is present on `sortableAttributes`, its value can become publicly accessible through the `/network` endpoint. Do not enable the `network` feature if you rely on the value of attributes not present in `displayedAttributes` to remain hidden at all times. Either add such attributes to `displayedAttributes` so their exposure is explicit, or remove them from `sortableAttributes` before opting into network search.
</Warning>

## Private network security

By default, Meilisearch blocks requests to non-global IP addresses. If your instances communicate over a private network, configure the `--experimental-allowed-ip-networks` flag on each instance:

<CodeGroup>
  ```bash theme={null}
  meilisearch --experimental-allowed-ip-networks 10.0.0.0/8,192.168.0.0/16
  ```
</CodeGroup>

Only allow the CIDR ranges your instances actually use.

## Next steps

<CardGroup cols={2}>
  <Card title="Replication and sharding overview" href="/resources/self_hosting/sharding/overview">
    Understand the concepts behind sharding, replication, and network search.
  </Card>

  <Card title="Deployment overview" href="/resources/self_hosting/deployment/overview">
    Deploy Meilisearch to production on various cloud providers.
  </Card>
</CardGroup>
