Every time a pod requests a volume, a snapshot, or a clone, CSI does two things, not one. It creates a Kubernetes API object, a PersistentVolumeClaim or a VolumeSnapshot, and then the CSI driver’s controller plugin makes a separate call out to whatever storage array sits behind it to actually perform the operation. For a handful of volumes, that second hop is invisible. It disappears into normal API latency and nobody notices.
The problem shows up when the number of create, read, update, and delete operations against the storage layer stops being occasional and starts being constant, fleets of database pods scaling up and down, CI/CD pipelines cloning volumes for every test run, namespaces spinning up and tearing down all day. Each of those actions is a CRUD call that has to cross the same two-hop path: Kubernetes object, then external array round trip. Traditional CSI drivers built around this pattern provision in seconds; the platforms built to absorb this kind of churn need to do it in milliseconds. That gap is a control-plane problem, and it is distinct from the data-path problem we have covered before: even if every volume were mounted instantly, the object lifecycle behind provisioning, snapshotting, and cloning would still be waiting on an external controller.
The Two-Hop Round Trip Behind Every CSI Call
CSI standardizes volume lifecycle as a set of gRPC calls a driver’s controller plugin must implement: CreateVolume, DeleteVolume, CreateSnapshot, ControllerPublishVolume, and so on. The spec does not say how fast the driver has to answer, and it does not require the storage backend to keep any state locally. In practice, most enterprise array-backed drivers implement these calls by translating them into API requests against the array’s own management plane, often the same REST or CLI interface a storage admin would use by hand.
That means every kubectl apply of a PersistentVolumeClaim triggers this sequence:
- Kubernetes API object created. The
PersistentVolumeClaim(orVolumeSnapshot, or clone request) lands in etcd and the external-provisioner sidecar picks it up. - Controller plugin calls out. The CSI controller plugin translates the request into a call against the array’s own management API, over the network, outside the Kubernetes cluster’s own control loop.
- Array processes the request. The array allocates capacity, updates its own metadata, and returns a volume handle.
- Kubernetes reconciles. The
PersistentVolumeobject is bound, and only then can a pod mount it.
Step 2 is the one CSI itself has no opinion about, and it is where the latency lives. An array management API was not built to answer thousands of provisioning calls a minute; it was built to answer the handful a storage admin might issue in a shift. Some vendors’ drivers measure typical provisioning latency in seconds precisely because of this round trip, not because block allocation itself is slow.
Where CRUD Churn Turns a Minor Latency Into a Platform Bottleneck
A few seconds of provisioning latency is a rounding error for a one-off request. It stops being a rounding error the moment the request rate is the point:
- Elastic database and cache fleets. StatefulSets that scale replicas up under load generate a burst of
CreateVolumecalls, each waiting on the same external round trip, serialized behind the array’s own request queue. - CI/CD and ephemeral test environments. Cloning a volume per test run, then deleting it minutes later, is a CRUD-heavy pattern by design. If clone and delete each cost a full array round trip, the pipeline’s speed is capped by the array, not by the test suite.
- Multi-tenant namespace churn. Platform teams provisioning storage per tenant or per environment repeat the same create/snapshot/delete cycle across hundreds of namespaces, and the array-side API becomes a shared, serialized resource all of them compete for.
- Snapshot-heavy backup and DR schedules. Scheduled
VolumeSnapshotcreation across a large fleet is, again, a CRUD burst timed by a cron schedule instead of application load, which does not make the array any faster at absorbing it.
None of this is a defect in any one CSI driver. It is what happens when a spec designed around occasional, admin-driven provisioning gets asked to absorb the request volume of a platform running thousands of stateful workloads. The Day 2 reality is that provisioning latency under load, not raw mount performance, is what platform engineering teams end up escalating.
The Day 2 Gap: HA, Replication, and DR Were Never CSI’s Job
CSI’s scope stops at volume lifecycle calls. It does not define how a driver replicates data, fails over during a node or array outage, encrypts data at rest, or restores from a snapshot in a disaster. Every one of those capabilities, if it exists at all, is bolted on by the vendor behind the driver, with its own configuration surface, its own failure modes, and its own support boundary that is separate from Kubernetes itself.
That gap lands squarely on platform teams running mission-critical stateful services. High availability has to be wired up separately from the CSI driver. Disaster recovery is a different product with a different runbook. Security controls like encryption and access policy live in yet another console. None of it is visible to kubectl get pvc, so a platform on paper looking “CSI-compliant” can still be missing the operational primitives a production database actually needs.
Watching provisioning latency climb as your platform’s CRUD rate grows, cloning volumes for CI, scaling stateful replicas, or churning through multi-tenant namespaces? Talk to us before Day 2 gaps in HA, DR, or security turn into an outage you are debugging live. Talk to a storage architect
The three ways teams close this gap land on different tradeoffs for provisioning speed and where the operational burden sits:
| Dimension | Standard CSI + external array | In-cluster pooled layer | Kubernetes-native control plane (simplyblock) |
|---|---|---|---|
| Provisioning path | Kubernetes object, then a separate call to the array’s own management API | Provisioning logic runs as pods on worker nodes | Provisioning stays inside the Kubernetes-native storage cluster, no external array hop |
| Behavior under CRUD churn | Seconds per operation, serialized behind the array’s request queue | Faster, but competes with application pods for node CPU | Milliseconds per operation, scales with the storage cluster, not the array |
| Built-in HA, replication, DR | Bolted on per vendor, separate console and support path | Bundled, but the failure domain includes your application nodes | Built into every volume by default, one control plane |
| Where Day 2 burden lands | Platform team integrates and troubleshoots each vendor’s separate tooling | Platform team owns a data plane sharing fate with compute | Platform team operates one Kubernetes-native control plane |
Table 1: How CSI-plus-external-array, in-cluster pooled storage, and a Kubernetes-native control plane handle provisioning latency and Day 2 operations.
Closing the Gap Without Leaving CSI
The fix is not to abandon CSI, it is still the right interface for how a pod requests a volume. The fix is to stop routing every provision, snapshot, and clone call through a second, external management plane. Simplyblock keeps the standard CSI driver experience on the Kubernetes side and answers CreateVolume, CreateSnapshot, and clone requests from inside a Kubernetes-native storage cluster built on pooled NVMe capacity served over NVMe/TCP and NVMe/RoCE. There is no separate array management API to call out to, so provisioning latency does not carry the cost of a second network hop and a foreign request queue.
Because replication, thin provisioning, snapshots, clones, and encryption run in that same control plane, high availability and disaster recovery are not a bolt-on integration project. Every volume gets them by default:
- CRUD operations answered inside the cluster, so provisioning, snapshot, and clone latency scales with the storage cluster’s own capacity, not with an external array’s admin-facing API.
- HA, replication, and DR built into the control plane, so a database fleet does not depend on a separate vendor product with its own failure modes to survive a node or site outage.
- One support boundary, the Kubernetes-native storage layer itself, instead of a CSI driver, an array console, and a replication product each owned by a different team.
- Independent scaling of compute and storage, so adding provisioning throughput does not mean adding worker nodes purely to keep up with CRUD churn.
That is the same architectural principle behind why the 1:1 connection model breaks at scale, just applied to the control plane instead of the data path: absorb the pressure inside a purpose-built storage layer, not on your application nodes or a management API that was never sized for it. If you are evaluating a storage platform for CRUD-heavy stateful workloads, see simplyblock for Kubernetes storage.
Questions and Answers
Why does CSI provisioning get slow under heavy CRUD churn?
Most array-backed CSI drivers implement CreateVolume, CreateSnapshot, and similar calls by making a second, external call to the array’s own management API, on top of the Kubernetes API object that gets created first. That management API was built to handle occasional, admin-driven requests, not the constant create, read, update, and delete traffic generated by autoscaling database fleets, CI/CD volume cloning, or multi-tenant namespace churn. As the CRUD rate rises, requests queue behind that external API, and provisioning that used to take seconds starts taking much longer.
Is this the same problem as CSI’s 1:1 connection model?
No, they are related but distinct. The 1:1 connection model is a data-path problem: each pod gets its own map, attach, detach, and unmap cycle to mount a volume, and that overhead multiplies during upgrades, failover, and migrations. The CRUD churn problem covered here is a control-plane problem: the API round trip to provision, snapshot, or clone a volume in the first place, independent of how the resulting volume gets mounted. A platform can fix one without fixing the other.
What operational gaps does CSI leave for platform teams to fill?
CSI defines volume lifecycle calls, not data services. High availability, replication, disaster recovery, encryption, and access security are not part of the spec, so each vendor’s driver bolts them on separately, with its own configuration, failure modes, and support path. A cluster can look fully CSI-compliant in kubectl get pvc output and still be missing the HA or DR posture a production database actually needs.
How does simplyblock avoid the external array round trip?
Simplyblock answers CSI provisioning, snapshot, and clone requests from inside a Kubernetes-native storage cluster built on pooled NVMe capacity served over NVMe/TCP and NVMe/RoCE, instead of forwarding them to a separate array management API. That removes the second network hop from every CRUD operation, so provisioning latency scales with the storage cluster rather than with an external API’s request queue, while replication, snapshots, thin provisioning, and encryption run as built-in control-plane features rather than bolt-on integrations.