How do sharding and replication differ in a vector database?

Sharding splits data into disjoint pieces spread across nodes, so each node stores and searches only part of the corpus; it is how a system grows beyond one machine’s capacity and write throughput. Replication keeps additional copies of the same data on different nodes, so the system can survive a node failure and serve more concurrent reads. In short, sharding scales capacity and writes, replication scales availability and reads, and production vector databases use both at once.

Shards divide data; replicas copy serving capacity. More shards and more replicas have different resource and routing costs. Shards divide data; replicas copy serving capacity. More shards and more replicas have different resource and routing costs.

Sharding vs replication at a glance

ShardingReplication
What it doesDivides data; each shard holds a different subsetCopies data; each replica holds the same subset
Primary goalCapacity, write throughput, parallel searchFault tolerance, read throughput
Effect on memoryTotal stays roughly constant, spread across nodesMultiplies serving memory by the replica count
Query patternFan out to every relevant shard, then merge top-kRoute each query to any one healthy replica
Main risksSkew and hotspots, fan-out tail latency, rebalancingExtra cost, replica lag, copying bad writes
Protects against data loss?NoNot by itself (see backups below)

The classic database rule still holds. If writes outgrow one server, adding replicas will not help; if reads outgrow one server, adding shards alone may not help either.

What changes for vector search?

In a relational database, a well-chosen shard key often sends a query to a single shard. Vector similarity has no natural shard key: a query’s nearest neighbors could live anywhere. So a vector search usually scatters to every shard, runs ANN search on each, and gathers the per-shard top-k into a global top-k. That has three consequences:

  • Tail latency follows the slowest shard. One overloaded node, an expensive filter on one partition, or a garbage-collection pause sets the p99 for the whole query.
  • Each shard must return enough candidates. The merge can only choose from what shards return, so per-shard recall matters.
  • Fan-out cost grows with shard count. More shards add parallelism but also add per-query overhead, so more is not automatically faster.

Metadata can restore some locality. Partitioning by tenant or date and filtering on it lets the system prune whole partitions before searching, which is what Milvus partition keys do (see multi-tenancy design).

How does Milvus shard data?

Milvus separates write sharding from read distribution, which is worth understanding before you tune either.

Shards (write path). When you create a collection you set num_shards. Each shard corresponds to a WAL channel, and in current Milvus each shard is owned by a Streaming Node that consumes its log and holds the newest, still-growing data. More shards spread ingestion across more streaming nodes. The docs suggest roughly one shard per 200 million entities, or one per 100 GB of data you plan to insert, and recommend multiple shards when the instance runs multiple streaming nodes. The shard count is set at creation, so plan for growth.

Segments (read path). Data within a shard is written into segments. Once sealed and indexed, segments are stored in object storage and the Coordinator distributes them across Query Nodes. This is the real unit of read-side distribution: adding query nodes causes segments to rebalance, spreading search work without changing the shard count.

A search request flows like this: the Proxy sends it to the shard leader (delegator) for each shard; each delegator dispatches the query to the query nodes holding that shard’s sealed segments and includes growing data; partial results merge at the delegator, then at the Proxy, into the final top-k. How the Milvus architecture separates ingestion, storage, and search covers each component.

How does Milvus replicate data?

Durability and serving copies are separate concerns in Milvus.

  • Durable copies live in the storage layer: the WAL (Woodpecker by default, or Pulsar or Kafka) and object storage such as S3 or MinIO. Their redundancy comes from that storage system, not from extra query nodes.
  • In-memory replicas are serving copies. Load a collection with replica_number=2 and Milvus places two complete copies of its segments on different query nodes, in replica groups. If a node fails or is busy, the Proxy routes requests to another replica. You cannot have more replicas than query nodes, and each replica costs a full copy of the loaded data in memory.
client.load_collection(
    collection_name="docs",
    replica_number=2,
    resource_groups=["rg_a", "rg_b"],   # optional: spread replicas across node pools
)

Resource groups let you place replicas on specific sets of query nodes, for example one replica per availability zone or a dedicated pool for a critical collection.

Replication is not backup

A healthy replica faithfully reproduces a bad delete or a buggy upsert within seconds. Replicas protect against hardware failure, not against mistakes, corruption, or a dropped collection. You still need point-in-time backups to separate storage, and, for regional disasters, cross-cluster replication. See planning backup and recovery and Milvus CDC and migration.

Replication also interacts with freshness. What a reader sees right after a write depends on the consistency level you choose, not on replica count alone; eventual consistency in vector search explains the options.

How do you test a sharded, replicated setup?

Run capacity and failure tests separately:

  1. Distribution test. Load representative data and check segment counts and memory per query node. Look for skew, especially with partition keys and uneven tenants.
  2. Throughput test. Increase concurrency until p99 rises, then add a replica and confirm read QPS scales.
  3. Write test. Run sustained ingestion alongside queries and watch streaming node and data node load.
  4. Failure test. Kill a query node holding one replica. Measure error rate, latency during failover, and time to rebalance.
  5. Recovery test. Restore from backup into a fresh cluster and time it.

Steady-state QPS alone hides most of the interesting failure modes. Locating a bottleneck across Milvus components and what determines vector-database scalability help interpret the results.

Next steps

Read the Milvus in-memory replica guide, then try replica_number and resource groups on a test cluster with observability enabled. If you would rather not manage shard and replica placement yourself, Zilliz Cloud runs managed Milvus with replicas and scaling handled for you.

Sources and further reading

Need a VectorDB for Your GenAI Apps?

Zilliz Cloud is a managed vector database built on Milvus perfect for building GenAI applications.

Try Free

Like the article? Spread the word