Right-sizing Longhorn replicas for Harvester virtual machines
How to choose Longhorn replica counts in Harvester so edge nodes stay responsive without losing fault tolerance.
17 Dec 2025, 14:13 UTC

The problem: three copies do not fit everywhere
You add a new Harvester node to a two-node edge cluster, deploy a virtual machine, and watch the node's memory climb. The culprit is often not the guest workload but the storage layer: Harvester's built-in Longhorn creates three copies of every volume by default, and each copy consumes memory and CPU on a node. If your cluster has fewer than three nodes, or if each node is small, that default can starve the workloads it is meant to protect.
Takeaway: match Longhorn's replica count to your node count and workload criticality, then verify with a test PVC before rolling out production VMs.
Longhorn is the open-source distributed block storage bundled with Harvester. It presents storage to Kubernetes through the Container Storage Interface (CSI), so VMs and pods consume it as persistent volume claims (PVCs). A replica is one copy of a volume's data, running as a Longhorn engine instance on a specific node.
What a replica costs
Longhorn's default replica count is three. Each replica is a separate engine instance, so the resource cost multiplies. The table below shows planning estimates; verify actual usage in your cluster because workload patterns and Longhorn versions change the numbers.
| Replicas | Approx. RAM per volume | Approx. vCPU per volume | Nodes needed to spread replicas |
|---|---|---|---|
| 2 | 400 MiB | 0.4 | 2 |
| 3 | 600 MiB | 0.6 | 3 |
On a node with 4 GiB of RAM, ten 3-replica volumes could reserve roughly 6 GiB of replica engine memory before the virtual machines start. That math is why small edge deployments often run better with two replicas.
Worked example: a two-replica StorageClass for an edge cluster
Imagine a two-node Harvester cluster at a remote site. The default three-replica policy cannot place copies on three distinct nodes, so you either accept co-located replicas, which defeats the availability goal, or lower the count. This example creates a StorageClass that provisions two-replica volumes.
Save the manifest as edge-vm-storage.yaml:
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: longhorn-2-replica
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "2"
staleReplicaTimeout: "30"
fsType: ext4
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
Run from an admin workstation with a kubeconfig pointed at the Harvester cluster. You need permissions to create StorageClasses, typically cluster-admin or an equivalent storage role.
kubectl apply -f edge-vm-storage.yaml
Verify the class:
kubectl get storageclass longhorn-2-replica -o yaml
Expect numberOfReplicas: "2" in the parameters. Next, create a PVC that references the class and attach it to a test pod:
kubectl run storage-test --image=busybox --rm -i --restart=Never -- \
sh -c "dd if=/dev/zero of=/mnt/data/testfile bs=1M count=10 && sync"
Mount the PVC at /mnt/data in the pod spec. dd overwrites testfile, so use a scratch path inside the container only. Expect the command to finish without I/O errors.
Open the Longhorn UI through the Harvester dashboard or the endpoint listed in your cluster documentation. The volume should show two replicas, ideally on different nodes, both marked healthy.
The trade-off: availability versus node headroom
Two replicas can survive the loss of one node if the remaining replica is healthy, but the volume is unavailable if both nodes fail or if the surviving replica is also unhealthy. Three replicas remain the safer default for production clusters with three or more nodes. Snapshots and backups consume additional space on top of replica storage, so monitor Longhorn disk usage after you change the count.
What to check before you change anything
- Run
kubectl get storageclassand confirm thelonghornclass exists. - Run
kubectl describe storageclass longhornand note the currentnumberOfReplicas. - Deploy a scratch PVC with
storageClassName: longhorn, or your custom class, and verify a pod can write and read data. - Check the Longhorn UI for replica count, replica locations, and health status.
- Review your Harvester release notes: older bundled Longhorn versions may not support encrypted volumes, so verify your version before planning encryption.
To remove the example class, delete any PVCs using it first, then run kubectl delete storageclass longhorn-2-replica.
Closing
Start with the default, measure replica engine memory with kubectl top pod in the Longhorn system namespace, and lower the replica count only when your node count or memory budget requires it. A two-replica StorageClass is a practical fit for small Harvester edge clusters, provided you accept the reduced fault tolerance and verify the result with a real read-write test.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.