Skip to main content

Rob Pankow Rob Pankow

Why CSI Alone Can't Absorb CRUD Churn at Scale: Provisioning Latency and Day 2 Operations

Jul 27, 2026  |  10 min read

Why CSI Alone Can't Absorb CRUD Churn at Scale: Provisioning Latency and Day 2 Operations

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:

  1. Kubernetes API object created. The PersistentVolumeClaim (or VolumeSnapshot, or clone request) lands in etcd and the external-provisioner sidecar picks it up.
  2. 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.
  3. Array processes the request. The array allocates capacity, updates its own metadata, and returns a volume handle.
  4. Kubernetes reconciles. The PersistentVolume object 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 CreateVolume calls, 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 VolumeSnapshot creation 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.

Diagram contrasting CSI's two-hop external array round trip under CRUD churn with a Kubernetes-native control plane that keeps provisioning, replication, and DR inside the cluster
Figure 1: CSI's external array round trip throttles CRUD churn; a Kubernetes-native control plane keeps provisioning, HA, and DR inside the cluster instead.

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:

DimensionStandard CSI + external arrayIn-cluster pooled layerKubernetes-native control plane (simplyblock)
Provisioning pathKubernetes object, then a separate call to the array’s own management APIProvisioning logic runs as pods on worker nodesProvisioning stays inside the Kubernetes-native storage cluster, no external array hop
Behavior under CRUD churnSeconds per operation, serialized behind the array’s request queueFaster, but competes with application pods for node CPUMilliseconds per operation, scales with the storage cluster, not the array
Built-in HA, replication, DRBolted on per vendor, separate console and support pathBundled, but the failure domain includes your application nodesBuilt into every volume by default, one control plane
Where Day 2 burden landsPlatform team integrates and troubleshoots each vendor’s separate toolingPlatform team owns a data plane sharing fate with computePlatform 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.

You may also like:

NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric
NVMe/TCP vs NVMe/RoCE for Kubernetes Storage: Choosing the Right Fabric

NVMe over Fabrics gives Kubernetes clusters low-latency block storage over the network. The transport you pick, TCP or RoCE, determines your latency floor, infrastructure cost, and operational complexity. Here is how to choose.

We Break Our Storage So You Never Have To
We Break Our Storage So You Never Have To

Simplyblock runs 100+ hours of automated chaos engineering before every release: real NVMe hardware, real FIO workloads, four failure types injected under live load. This is what we test, why it is necessary, and what it means for your infrastructure.

NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency
NVMe Storage Cost Optimization in 2026: Erasure Coding, Thin Provisioning, and Compute Efficiency

NVMe drives deliver the performance Kubernetes stateful workloads need, but triple replication and thick provisioning multiply their cost fast. Here is a practical breakdown of erasure coding economics, thin provisioning, and how sub-millisecond latency reduces compute waste.