# Migrating Self-managed Milvus to Managed Milvus to gain >99% Performance

> At small scale, self-managing a vector database is manageable. Once you're in the tens of millions of embeddings you'll probably want to offload the headache to a managed service.

Author: Simon Hearne (https://simonhearne.com/about/)
Published: 2026-07-14
Canonical: https://simonhearne.com/2026/migrating-milvus/
Tags: Milvus, Zilliz, VectorDB

---
So you've built an application using Milvus as the vector database, using [Standalone](https://milvus.io/docs/install_standalone-docker.md) or  [Distributed](https://milvus.io/docs/install_cluster-milvusoperator.md?tab=helm). You've reached a point where the application is working, customers are using it and the data volume is growing. At some point managing the vector database starts consuming more time, pod failures cause service jitter, you're running out of RAM on the server, or `etcd` becomes a painful bottleneck.

At this stage you're probably exploring a managed service to take the operational burden away. The good news is that migrating from Milvus to Zilliz Cloud is straightforward, and the various options are [well documented](https://docs.zilliz.com/docs/migrate-from-milvus).

In my case, I had built a simple Wikipedia RAG application: 50M embeddings using Cohere's Embed v3 multi-lingual model at 1,024 dimensions (covering the entire Wikipedia English corpus). Initially I hosted this on my laptop using Milvus Standalone, but the container was unstable and restarts took \~20 minutes - not ideal when you want to show a demo!

Query performance was also suffering due to frequent paging (I don't have enough memory on my laptop, so I enabled [mmap](https://milvus.io/docs/mmap.md)). Below is a quick video showing the application in action:

<figure>
  <video style="aspect-ratio: 810 / 785.758;" autoplay loop muted playsinline preload="metadata">
    <source src="/images/migrating-milvus/standalone.webm" type="video/webm">
    <source src="/images/migrating-milvus/standalone.mp4" type="video/mp4">
    <source src="/images/migrating-milvus/standalone.mov" type="video/mov">
  </video>
  <figcaption>The app works, but it could be faster</figcaption>
</figure>

Three second query times aren't great, so without the budget for a new laptop, I planned my migration to managed Milvus on Zilliz Cloud. The following is the step-by-step process I followed - there are a number of methods available, but I chose backup / restore for simplicity.

## Create a backup

Zilliz provides the [milvus-backup](https://github.com/zilliztech/milvus-backup) utility, and installing it is as easy as `brew install milvus-backup`

You then need to create a config file (milvus-backup looks for `backup.yaml` in the current working directory by default). This is a minimal example to create a backup from Standalone running in Docker locally (see the full [yaml options](https://github.com/zilliztech/milvus-backup/blob/main/configs/backup.yaml) on GitHub):

```yml
milvus:
  address: localhost
  port: 19530
  user: "root"
  password: "Milvus"
  tlsMode: 0
  etcd:
    endpoints: 127.0.0.1:2379
    rootPath: "by-dev"
minio:
  storageType: "local"
  rootPath: "/../milvus_wikipedia/volumes/milvus/data"
  backupStorageType: "local"
  backupRootPath: "/../milvus-backup-test/backup"
```

Then run a quick check:

```bash
$ milvus-backup check

Milvus version: 2.6.2
Storage:
  milvus-storage-type: local
  milvus-bucket: a-bucket
  milvus-rootpath: /../milvus_wikipedia/volumes/milvus/data
  backup-storage-type: local
  backup-bucket: a-bucket
  backup-rootpath: /../milvus-backup-test/backup

Success!
```

And finally create the backup (this will take a little time):

```bash
milvus-backup create -n wiki_backup
```

## Create the target instance on Zilliz Cloud

First make sure you have a [Zilliz Cloud](https://cloud.zilliz.com/) account - then create an instance that matches the minimum requirements of your local deployment. For my 50M x 1,024-D embeddings on Tiered-Storage, the [public calculator](https://zilliz.com/pricing#calculator) estimated that I required 2 [Query CU](https://zilliz.com/blog/how-to-choose-the-right-cu-type-and-size):

![screenshot zilliz cloud pricing calculator](https://simonhearne.com/images/migrating-milvus/estimation.png)
*Public pricing calculator estimates Query CUs*

So I navigated to the cloud console, clicked "\+ Cluster" and used these settings:

![screenshot zilliz cloud cluster creation screen](https://simonhearne.com/images/migrating-milvus/creation.png)
*Creating a cluster in Zilliz Cloud*

While it is creating, you can retrieve / generate the API key we will need for the next step:

![screenshot zilliz cloud generate api key](https://simonhearne.com/images/migrating-milvus/api_key.png)
*Creating / retrieving API keys in Zilliz Cloud*

And note the cluster ID of the new instance:

![screenshot zilliz cloud get instance ID](https://simonhearne.com/images/migrating-milvus/connection.png)
*Retrieve Cluster ID from Zilliz Cloud*

## Migrate to Zilliz

Update your `backup.yaml` to include the cloud key you just generated / retrieved:

```yml
cloud:
  address: https://api.cloud.zilliz.com
  apikey: <your-api-key>
```

Then finally we just need to run one migration command, with the backup name and the target cluster ID passed as arguments:

```bash
milvus-backup migrate -n wiki_backup -c <your-cluster-id>
```

In my case it took a few hours to upload the \~120GB backup file to a [Volume](https://docs.zilliz.com/docs/managed-volume) on Zilliz Cloud, then about an hour to create the target cluster from the Volume. You can monitor the migration status in the Zilliz Cloud console under Jobs:

![screenshot zilliz cloud job progress](https://simonhearne.com/images/migrating-milvus/jobs.png)
*View job progress in Zilliz Cloud*

Once the migration is complete, make sure you load the collection into the cluster!

![screenshot zilliz cloud load collection ](https://simonhearne.com/images/migrating-milvus/load_collection.png)
*Load the new collection in the cluster*

## Validation

Now you can simply update the application to use the new cluster endpoint and credentials.

<figure>
  <video style="aspect-ratio: 810 / 785.758;" autoplay loop muted playsinline preload="metadata">
    <source src="/images/migrating-milvus/zilliz.webm" type="video/webm">
    <source src="/images/migrating-milvus/zilliz.mp4" type="video/mp4">
    <source src="/images/migrating-milvus/zilliz.mov" type="video/mov">
  </video>
  <figcaption>The app still works, and now queries are not the bottleneck!</figcaption>
</figure>

We observe a performance improvement compared to Milvus Standalone - 25ms compared to 3,112ms - that's over a *99% latency reduction*!. This is partly due to the increased compute allocated in the cloud service, as well as the proprietary index engine in Zilliz Cloud - [Cardinal](https://zilliz.com/cardinal) - which can achieve 10x faster queries compared to Milvus OSS.

The performance win is huge, but even better I no longer need to worry about the container stopping and I can free up \~20GB RAM on my laptop!

## Other considerations

- If your application isn't running 24x7, your vector database doesn't need to either. [Suspend](https://docs.zilliz.com/docs/manage-cluster#suspend) inactive clusters to drop the compute cost to zero when it is not being used.

- Tiered-Storage is a great cluster type for low (\<10 QPS) requirements, but there are [other options](https://docs.zilliz.com/docs/cu-types-explained) and you can [migrate](https://docs.zilliz.com/docs/offline-migration) data between them:

    - **On-Demand** - only uses compute when there are queries being run. This could drop the cost by 99%, depending on the frequency of queries, at a cost of higher cold-start latency.

    - **Capacity-Optimized** - provides reduced data density compared to Tiered-Storage, but achieves 10x greater throughput and 2-5x faster queries. This would increase the compute cost of my example by about 60%.

    - **Performance-Optimized** - provides even greater throughput (\>1,000 QPS per replica) and performance (10-100x faster) at the cost of further reduced data density.

- Zilliz Cloud supports mounting external volumes from Google Cloud Storage, Amazon S3, Azure Blob Storage etc. So a cleaner approach would be to upload the backup directly to cloud storage and restoring it from there.

- If creating / restoring a backup is not possible for any reason, and the Milvus deployment can be made accessible publicly - you can use the [Migrate from Milvus Endpoint](https://docs.zilliz.com/docs/via-endpoint) feature in Zilliz Cloud.

- Everything we performed in Zilliz Cloud can be managed via [API](https://docs.zilliz.com/reference/restful) and/or [Terraform](https://docs.zilliz.com/docs/terraform-provider) if click-ops is not your preferred methodology.

