Skip to content

Commit ccd93f5

Browse files
authored
Merge pull request #3528 from meilisearch/fix-sharding-docs-review
Fix sharding docs inaccuracies
2 parents fa779c8 + 1cbda4a commit ccd93f5

4 files changed

Lines changed: 122 additions & 119 deletions

File tree

resources/self_hosting/sharding/configure_replication.mdx

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ sidebarTitle: Configure replication
44
description: Set up replicated shards across multiple Meilisearch instances to ensure high availability and distribute search load.
55
---
66

7-
Replication assigns the same shard to multiple remotes in your Meilisearch network. If one remote goes down, another remote holding the same shard continues serving results. This guide covers how to configure replication, common patterns, and what to expect during failover.
7+
Replication assigns the same shard to multiple remotes in your Meilisearch network. This guide covers how to configure replication, common patterns, and scaling read throughput.
88

99
<Note>
1010
Replication requires the Meilisearch Enterprise Edition v1.37 or later and a [configured network](/resources/self_hosting/sharding/setup_sharded_cluster).
1111
</Note>
1212

1313
## How replication works
1414

15-
When you configure shards, each shard can be assigned to one or more remotes. If a shard is assigned to multiple remotes, Meilisearch replicates the data to each of them. During a search with `useNetwork: true`, Meilisearch queries each shard exactly once, picking one of the available remotes for each shard. This avoids duplicate results and provides automatic failover.
15+
When you configure shards, each shard can be assigned to one or more remotes. If a shard is assigned to multiple remotes, Meilisearch replicates the data to each of them. During a search, Meilisearch queries each shard exactly once, picking one of the available remotes for each shard (prioritizing the `self`/local remote). This avoids duplicate results.
1616

1717
## Assign shards to multiple remotes
1818

@@ -36,7 +36,7 @@ curl \
3636

3737
</CodeGroup>
3838

39-
In this configuration, every shard exists on two remotes. If any single instance goes down, all shards remain available.
39+
In this configuration, every shard exists on two remotes. If any single instance goes down, all shard data still exists on another instance.
4040

4141
## Common replication patterns
4242

@@ -83,26 +83,19 @@ Place replicas in different regions to reduce latency for geographically distrib
8383
}
8484
```
8585

86-
Route search requests to the closest cluster. Both regions hold all data, so either can serve a full result set.
86+
Route search requests to the closest cluster. Both regions hold all data, so either can serve a full result set. By default, Meilisearch prioritizes local search requests and will not transfer the request to a remote server. Make sure your search requests are made on the closest remote instance to ensure this setup is efficient.
8787

88-
## Failover behavior
88+
## Remote availability
8989

90-
When a remote becomes unavailable during a network search:
90+
When a network search runs, Meilisearch builds an internal set of remotes to query: it assigns each shard to a remote, then sends one query per remote with a shard filter. This guarantees that no shard is queried twice and that results are never duplicated.
9191

92-
1. Meilisearch detects the remote is unreachable
93-
2. If another remote holds the same shard, Meilisearch queries that remote instead
94-
3. The search completes with results from all shards, using the available replicas
95-
4. If no remote for a given shard is reachable, results from that shard are missing from the response
96-
97-
Meilisearch does not require manual intervention for failover. When the failed remote comes back online, it automatically rejoins the network and starts serving searches again.
92+
The downside is that there is no automatic fallback. If the remote assigned to a shard is unreachable, that shard's results are missing from the response — Meilisearch does not yet retry using another replica that holds the same shard.
9893

9994
## Scaling read throughput
10095

10196
Replication is the primary way to scale search throughput in Meilisearch. Each replica can independently handle search requests, so adding more replicas increases the total number of concurrent searches your cluster can handle.
10297

103-
To add a new replica for an existing shard:
104-
105-
1. Add the new remote to the network:
98+
To add a new replica for an existing shard, add the new remote and use `addRemotes` to append it to the shard without rewriting the full assignment:
10699

107100
<CodeGroup>
108101

@@ -112,45 +105,31 @@ curl \
112105
-H 'Content-Type: application/json' \
113106
-H 'Authorization: Bearer MEILISEARCH_KEY' \
114107
--data-binary '{
115-
"addRemotes": {
108+
"remotes": {
116109
"ms-03": {
117110
"url": "http://ms-03.example.com:7703",
118-
"searchApiKey": "SEARCH_KEY_03"
111+
"searchApiKey": "SEARCH_KEY_03",
112+
"writeApiKey": "WRITE_KEY_03"
119113
}
120-
}
121-
}'
122-
```
123-
124-
</CodeGroup>
125-
126-
2. Update the shard assignment to include the new remote:
127-
128-
<CodeGroup>
129-
130-
```bash
131-
curl \
132-
-X PATCH 'MEILISEARCH_URL/network' \
133-
-H 'Content-Type: application/json' \
134-
-H 'Authorization: Bearer MEILISEARCH_KEY' \
135-
--data-binary '{
114+
},
136115
"shards": {
137-
"shard-a": { "remotes": ["ms-00", "ms-01", "ms-03"] },
138-
"shard-b": { "remotes": ["ms-01", "ms-02"] },
139-
"shard-c": { "remotes": ["ms-02", "ms-00"] }
116+
"shard-a": { "addRemotes": ["ms-03"] }
140117
}
141118
}'
142119
```
143120

144121
</CodeGroup>
145122

123+
This triggers a `NetworkTopologyChange` task that replicates the shard's documents to `ms-03`.
124+
146125
## The leader instance
147126

148-
The leader is responsible for all write operations (document additions, settings changes, index management). Non-leader instances reject writes with a `not_a_leader` error.
127+
The leader is responsible for all write operations (document additions, settings changes, index management). Non-leader instances reject writes with a `not_leader` error.
149128

150129
If the leader goes down:
151130

152-
- **Search continues**: replicas still serve search results for all replicated shards
153-
- **Writes are blocked**: no documents can be added or updated until a leader is available
131+
- **Search may be affected**: if search requests are routed to the downed leader, they will fail
132+
- **Writes are blocked**: no documents can be added or updated until a leader is available. Note that alive remote instances continue to process tasks
154133
- **Manual promotion**: you must designate a new leader by updating the network topology with `PATCH /network` and setting `"leader"` to another instance
155134

156135
<Warning>

resources/self_hosting/sharding/manage_network.mdx

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
---
22
title: Manage the network
33
sidebarTitle: Manage the network
4-
description: Add and remove remotes, update shard assignments, and manage your Meilisearch network topology dynamically.
4+
description: Add remotes, update shard assignments, and manage your Meilisearch network topology dynamically. Includes rebalancing behavior and validation rules.
55
---
66

77
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.
88

99
## Add a remote
1010

11-
Use `addRemotes` to add a new instance to the network without rewriting the entire `remotes` configuration:
11+
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:
1212

1313
<CodeGroup>
1414

@@ -18,22 +18,36 @@ curl \
1818
-H 'Content-Type: application/json' \
1919
-H 'Authorization: Bearer MEILISEARCH_KEY' \
2020
--data-binary '{
21-
"addRemotes": {
21+
"remotes": {
2222
"ms-03": {
2323
"url": "http://ms-03.example.com:7703",
24-
"searchApiKey": "SEARCH_KEY_03"
24+
"searchApiKey": "SEARCH_KEY_03",
25+
"writeApiKey": "WRITE_KEY_03"
2526
}
27+
},
28+
"shards": {
29+
"shard-a": { "addRemotes": ["ms-03"] }
2630
}
2731
}'
2832
```
2933

3034
</CodeGroup>
3135

32-
After adding the remote, update your shard configuration to assign shards to it.
36+
<Note>
37+
`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.
38+
</Note>
39+
40+
## Update shard assignments
41+
42+
Each shard object in a `PATCH /network` request accepts three fields:
3343

34-
## Remove a remote
44+
| Field | Type | Behavior |
45+
|-------|------|----------|
46+
| `remotes` | array | Full replacement of the shard's remote list |
47+
| `addRemotes` | array | Adds remotes to the existing list |
48+
| `removeRemotes` | array | Removes remotes from the existing list, applied after `addRemotes` |
3549

36-
Use `removeRemotes` to take an instance out of the network:
50+
Shards not included in the request are left unchanged. To remove a remote from a specific shard:
3751

3852
<CodeGroup>
3953

@@ -43,19 +57,15 @@ curl \
4357
-H 'Content-Type: application/json' \
4458
-H 'Authorization: Bearer MEILISEARCH_KEY' \
4559
--data-binary '{
46-
"removeRemotes": ["ms-03"]
60+
"shards": {
61+
"shard-a": { "removeRemotes": ["ms-03"] }
62+
}
4763
}'
4864
```
4965

5066
</CodeGroup>
5167

52-
<Warning>
53-
Before removing a remote, make sure its shards are replicated on other remotes. Removing the only remote holding a shard makes that data unavailable for network searches.
54-
</Warning>
55-
56-
## Update shard assignments
57-
58-
Reassign shards to different remotes by sending a new `shards` configuration:
68+
To fully replace a shard's assignment, use `remotes`:
5969

6070
<CodeGroup>
6171

@@ -75,6 +85,29 @@ curl \
7585

7686
</CodeGroup>
7787

88+
## Topology changes and rebalancing
89+
90+
When you modify shard assignments, Meilisearch triggers a `NetworkTopologyChange` task on all remotes. This task runs in three steps:
91+
92+
1. **Compute new shards**: each instance uses rendezvous hashing on document IDs to determine which documents belong to which shard under the new topology.
93+
2. **Export and import**: documents are sent to remotes that now own them.
94+
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.
95+
96+
Cancelling a topology change at step 3 only results in stale documents being retained temporarily. It does not cause data loss.
97+
98+
<Warning>
99+
Search requests may return incomplete results during a topology change. Wait for all `NetworkTopologyChange` tasks to complete before resuming normal search traffic.
100+
</Warning>
101+
102+
## Validation
103+
104+
`PATCH /network` rejects requests with a `400 invalid_network_shards` error in the following cases:
105+
106+
- The shard list would become empty after applying the patch
107+
- A shard's `remotes` list would become empty after applying `removeRemotes`
108+
- A shard references a remote that is not in the `remotes` object
109+
- A remote is removed from `remotes` and this leaves a shard with no remotes
110+
78111
## Filter searches by shard
79112

80113
Target specific shards using the `_shard` filter in search requests:
@@ -88,7 +121,6 @@ curl \
88121
-H 'Authorization: Bearer MEILISEARCH_KEY' \
89122
--data-binary '{
90123
"q": "batman",
91-
"useNetwork": true,
92124
"filter": "_shard = \"shard-a\""
93125
}'
94126
```
@@ -99,9 +131,9 @@ Supported `_shard` filter operators:
99131

100132
| Syntax | Behavior |
101133
|--------|----------|
102-
| `_shard = "shard-a"` | Results from `shard-a` only |
103-
| `_shard != "shard-a"` | Results from all shards except `shard-a` |
104-
| `_shard IN ["shard-a", "shard-b"]` | Results from both `shard-a` and `shard-b` |
134+
| `_shard = "shard-a"` | Documents associated to `shard-a` |
135+
| `_shard != "shard-a"` | Documents associated to all shards except `shard-a` |
136+
| `_shard IN ["shard-a", "shard-b"]` | Documents associated to both `shard-a` and `shard-b` |
105137

106138
## Private network security
107139

resources/self_hosting/sharding/overview.mdx

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,29 @@ Replication and sharding require the Meilisearch Enterprise Edition v1.37 or lat
1414

1515
Sharding distributes documents from a single index across multiple Meilisearch instances, called "remotes." Each remote holds one or more named shards containing a subset of your documents.
1616

17-
When a user searches, Meilisearch queries all remotes in the network, collects results from each shard, and merges them into a single ranked response, as if the data lived on one machine.
17+
When a user searches, Meilisearch queries the necessary remotes in the network, collects results from each shard, and merges them into a single ranked response, as if the data lived on a single machine.
1818

1919
## What is replication?
2020

21-
Replication assigns the same shard to more than one remote. If one remote becomes unavailable, another remote holding the same shard continues serving results. Meilisearch automatically queries each shard exactly once, avoiding duplicate results even when shards are replicated.
21+
Replication assigns the same shard to more than one remote. This ensures your data is stored redundantly across instances. During a network search, Meilisearch ensures each shard is queried exactly once, either from a remote shard or from the local one (chosen randomly, favoring the local one). This guarantees each shard is queried exactly once, so results are never duplicated regardless of how many replicas exist.
2222

2323
## How it works
2424

2525
```mermaid
2626
graph TD
27-
Client[Client application] -->|search with useNetwork: true| Leader[Leader instance]
28-
Leader -->|fan out| R1[Remote ms-00<br/>shard-a, shard-c]
29-
Leader -->|fan out| R2[Remote ms-01<br/>shard-a, shard-b]
30-
Leader -->|fan out| R3[Remote ms-02<br/>shard-b, shard-c]
31-
R1 -->|partial results| Leader
32-
R2 -->|partial results| Leader
33-
R3 -->|partial results| Leader
34-
Leader -->|merged results| Client
27+
Client[Client application] -->|search with useNetwork: true| Any[Any instance]
28+
Any -->|fan out| R1[Remote ms-00<br/>shard-a, shard-c]
29+
Any -->|fan out| R2[Remote ms-01<br/>shard-a, shard-b]
30+
Any -->|fan out| R3[Remote ms-02<br/>shard-b, shard-c]
31+
R1 -->|partial results| Any
32+
R2 -->|partial results| Any
33+
R3 -->|partial results| Any
34+
Any -->|merged results| Client
3535
```
3636

37-
1. **Network**: all instances register with each other through the `/network` endpoint, forming a topology with a designated leader
38-
2. **Shards**: the leader distributes document subsets across remotes based on shard assignments
39-
3. **Search**: when `useNetwork: true` is set, the leader fans out the search to all remotes, then merges and ranks the combined results
40-
4. **Failover**: if a remote is down, another remote holding the same shard serves those results
37+
1. **Network**: the user configures the topology via `/network` on the leader, and this instance propagates it to all remotes
38+
2. **Shards**: Remotes distribute the subsets of documents across themselves based on shard assignments
39+
3. **Search**: when `useNetwork: true` is set or not defined (defaults to `true`), the instance receiving the request fans out the search to all remotes, then merges and ranks the combined results
4140

4241
## When to use sharding and replication
4342

@@ -54,14 +53,18 @@ All instances in a Meilisearch network share a topology configuration that defin
5453

5554
- **`self`**: the identity of the current instance
5655
- **`leader`**: the instance coordinating writes and topology changes
57-
- **`remotes`**: all instances in the network with their URLs and search API keys
56+
- **`remotes`**: all instances in the network with their URLs, search API keys, and write API keys
5857
- **`shards`**: how document subsets are distributed across remotes
5958

60-
The leader instance is responsible for write operations. Non-leader instances reject write requests (document additions, settings changes, index creation) with a `not_a_leader` error.
59+
The leader instance is responsible for write operations and topology changes. Non-leader instances reject write requests (document additions, settings changes, index creation) with a `not_leader` error. Search requests can be sent to any instance in the network.
6160

6261
## Searching across the network
6362

64-
To search across all instances, add `useNetwork: true` to your search request:
63+
To search across all instances:
64+
65+
<Note>
66+
`useNetwork` defaults to `true` when a network topology is defined.
67+
</Note>
6568

6669
<CodeGroup>
6770

@@ -71,8 +74,7 @@ curl \
7174
-H 'Content-Type: application/json' \
7275
-H 'Authorization: Bearer MEILISEARCH_KEY' \
7376
--data-binary '{
74-
"q": "batman",
75-
"useNetwork": true
77+
"q": "batman"
7678
}'
7779
```
7880

@@ -83,7 +85,6 @@ The response includes `_federation` metadata showing which remote each result ca
8385
```json
8486
{
8587
"q": "batman",
86-
"useNetwork": true,
8788
"filter": "_shard = \"shard-a\""
8889
}
8990
```
@@ -101,8 +102,8 @@ curl \
101102
-H 'Authorization: Bearer MEILISEARCH_KEY' \
102103
--data-binary '{
103104
"queries": [
104-
{ "indexUid": "movies", "q": "batman", "useNetwork": true },
105-
{ "indexUid": "comics", "q": "batman", "useNetwork": true }
105+
{ "indexUid": "movies", "q": "batman" },
106+
{ "indexUid": "comics", "q": "batman" }
106107
]
107108
}'
108109
```
@@ -117,16 +118,20 @@ Most Meilisearch features work transparently across a sharded network. The follo
117118
|---------|---------------------|-------|
118119
| Full-text search | Yes | Results merged and ranked across all remotes |
119120
| Filtering and sorting | Yes | Filters applied on each remote before merging |
120-
| Faceted search | Yes | Facet counts aggregated across remotes |
121+
| Faceted search | Partial | Facet distribution in search results works across remotes, but the `/facet-search` endpoint does not support `useNetwork` |
121122
| Hybrid/semantic search | Yes | Each remote runs its own vector search, results merged |
122123
| Geo search | Yes | Geographic filters and sorting work across remotes |
123-
| Multi-search | Yes | Use `useNetwork: true` per query |
124+
| Multi-search | Yes | Works per query; `useNetwork` defaults to `true` when a network is configured |
124125
| Federated search | Yes | Federation merges results from both indexes and remotes |
125126
| Analytics | Partial | Events are tracked on the instance that receives the search request |
126127
| Tenant tokens | Yes | Token filters apply on each remote |
127128
| Document operations | Leader only | Writes must go through the leader instance |
128129
| Settings changes | Leader only | Settings updates must go through the leader |
129-
| Conversational search | Yes | Chat queries can use network search |
130+
| Conversational search | No | Chat completions do not support `useNetwork` |
131+
132+
<Warning>
133+
Search requests may return errors during a network topology change if they reference shards that are being added or removed. Wait for all `NetworkTopologyChange` tasks to complete before searching.
134+
</Warning>
130135

131136
## Prerequisites
132137

@@ -147,7 +152,7 @@ Before setting up sharding and replication, you need:
147152
Set up replicated shards for high availability and read scaling.
148153
</Card>
149154
<Card title="Manage the network" href="/resources/self_hosting/sharding/manage_network">
150-
Add and remove remotes, update topology, and handle failover.
155+
Add and remove remotes, update shard assignments.
151156
</Card>
152157
<Card title="Enterprise Edition" href="/resources/self_hosting/enterprise_edition">
153158
Learn about the differences between Community and Enterprise editions.

0 commit comments

Comments
 (0)