How to Size Kubernetes Storage for ClickHouse® Dashboards Under Ingest Load
April Wong
Sub-second ClickHouse® dashboards depend on more than a fast query in an idle cluster. Inserts create new data parts, merges reorganize them, and concurrent users compete for CPU, memory and storage. Size the deployment for those activities together.
This guide focuses on ClickHouse using local or block-backed volumes on Kubernetes. It provides a worked planning example and a test procedure, not a new benchmark. Documentation was reviewed on 12 October 2026. Architectures using shared object storage have different caching and recovery behavior and should be evaluated separately.
TL;DR
- Define dashboard latency, query arrival rate, ingest rate and data freshness together; capacity in terabytes is only one requirement.
- Check query pruning and insert batching before buying more storage performance.
- Budget per-replica capacity for active data, growth and temporary work, then measure IOPS and throughput under simultaneous reads and writes.
- Choose the least-cost complete deployment that passes sustained-load and recovery tests; an IOPS specification is not a dashboard latency guarantee.
What workload must the storage sustain?
Write a workload contract before selecting a volume. Include the retained dataset, daily growth, query mix, arrival rate, latency percentiles, insert batch size, ingest rate and maximum acceptable delay before new records appear. Define whether the latency target covers an individual query or the complete dashboard response.
For example, suppose a dashboard serves 20 query requests per second, needs query p95 below 500 milliseconds and must show events within five seconds. These are illustrative acceptance targets, not Nirvana measurements. Replay realistic filters and tenant sizes: twenty identical cached queries do not represent twenty users exploring different data.
CPU and memory still matter. ClickHouse’s hardware guidance makes sizing workload-dependent. Memory pressure can cause external sorting or aggregation to spill to disk, adding storage work. Keep compute and memory fixed when isolating a storage change, then compare the complete configurations you would actually buy.
A 9 October 2026 ClickHouse case study of iSAM Funds illustrates why the input distribution matters: activity varied substantially across markets, making simple sharding difficult to balance. ClickHouse reports compression and ingest improvements for that customer’s migration from PostgreSQL. Those results describe its data and architecture, not a compression factor or performance promise for your Kubernetes deployment. Measure your own busiest tenant, shard and retention window.
Can the query read less before the disk works harder?
Inspect the common filters and ordering key first. ClickHouse’s sparse primary index can exclude granules that cannot match a query; effective pruning reduces the work sent down the storage path. The primary-key guide demonstrates this with EXPLAIN indexes = 1. Fewer bytes scanned does not imply a proportional latency improvement because other work remains.
For a tenant-and-time dashboard, inspect the plan for representative tenant IDs and time ranges. Check both the expected fast path and a broader investigation query. An ordering key that helps one access pattern may do little for another. Keep schema and query changes separate from infrastructure changes so you can identify what helped.
Ingestion also shapes the storage workload. ClickHouse recommends batching inserts to reduce per-insert overhead and part creation. Background merges read existing parts and write replacements. Many small parts can therefore turn an apparently modest ingest rate into substantial background work. Keep production-like batching and freshness requirements in the test.
How do you turn retained data into a volume budget?
Start with data-part occupancy per replica. For the example database analytics, this read-only query reports active parts by table on the current server:
SELECT
table,
count() AS active_parts,
sum(rows) AS rows,
formatReadableSize(sum(bytes_on_disk)) AS active_part_size
FROM system.parts
WHERE active AND database = 'analytics'
GROUP BY table
ORDER BY sum(bytes_on_disk) DESC;
The parts documentation distinguishes bytes_on_disk, which includes part files, from compressed column data alone. Active parts do not describe all filesystem occupancy. Check inactive parts, temporary work, logs and free disk space separately, and repeat per replica.
For a new deployment, estimate retained active data per shard as measured stored bytes per day × retention days, using representative data after merges and the intended schema, codecs and indexes. Account separately for materialized views and additional tables. Use the busiest shard rather than assuming perfectly even distribution. Then calculate volume per replica = (retained active data + growth allowance + temporary work and other occupancy) / chosen occupancy ceiling. Sum those volume budgets across every replica and shard; plan independent backups separately.
Here is a hypothetical budget for one replica of one shard, using decimal units. Substitute observations from your own dataset and maintenance operations.
| Planning component | Example allowance | How to establish it |
|---|---|---|
| Active retained data parts | 1.0 TB | Measure representative data after retention has stabilized. |
| Growth before the next capacity change | 0.2 TB | Forecast net growth after expiry, including new tables. |
| Temporary work and other occupancy | 0.4 TB | Observe merges, mutations, rebuilds and operational files. |
| Planned occupancy | 1.6 TB | Sum the three components. |
| Volume at a chosen 70% occupancy ceiling | At least 2.29 TB | 1.6 / 0.70; round up to a supported capacity. |
The 0.4 TB allowance and 70% ceiling are example policy choices, not ClickHouse defaults or universal recommendations. A large mutation can require more working space. Two full replicas of this shard require this budget twice; replication does not halve each replica’s dataset. Backups need a separate retention and capacity plan.
Size performance separately. IOPS measures operation count, while throughput measures bytes per second. At a hypothetical uniform 128 KiB per operation, 1 GiB/s corresponds to 8,192 operations/s. Real ClickHouse I/O is mixed and concurrent, so that arithmetic is only a unit conversion. Measure the actual operation sizes, read/write mix and latency.
How should you test queries while ingest and merges continue?
Use an isolated staging cluster with representative data, matching versions, schema, codecs, replica count and settings. Record the storage type, provisioned limits, node specifications and client location. Keep cold or newly attached storage runs distinct from warmed runs.
- Establish a query-only reference. Replay the chosen query mix at a fixed arrival rate. Record client latency, completions, errors and result correctness.
- Add the intended ingest stream. Preserve batch sizes and arrival patterns. Measure accepted rows and the time until known new records become queryable.
- Observe sustained operation. Continue until several merge cycles have occurred and the part-count trend is understandable. Track CPU, memory, disk reads/writes, latency, free space and ingest backlog together.
- Exercise the agreed peak. Increase to the expected production peak without changing multiple settings at once. Record when latency or freshness misses its target and whether backlog clears afterward.
Tag test queries with log_comment = 'sizing-run-01'. With query logging enabled and not sampled, this query summarizes successful initial SELECTs on the current server:
SELECT
normalized_query_hash,
count() AS completed_queries,
quantileExact(0.95)(query_duration_ms) AS p95_ms,
quantileExact(0.99)(query_duration_ms) AS p99_ms,
avg(read_rows) AS mean_rows_read
FROM system.query_log
WHERE type = 'QueryFinish'
AND is_initial_query = 1
AND query_kind = 'Select'
AND log_comment = 'sizing-run-01'
AND query_start_time >= now() - INTERVAL 1 HOUR
GROUP BY normalized_query_hash;
Query logs are local to each server and flush asynchronously; collect the relevant initiating servers and allow logs to flush. This query excludes failures, so report those from the client and exception records separately. Server duration is not complete dashboard latency. Query-log read counts are not a direct physical-disk throughput measurement; use storage telemetry for that.
Which storage option passes the operating test?
Compare local NVMe and network-attached block volumes on the same workload contract. Local volumes bind storage to a node; account for the recovery path when that node is unavailable. For block storage, verify the attachment topology, aggregate node limits and reattachment behavior, as well as the volume’s advertised performance.
Inspect the actual StorageClass: provisioner, binding mode, topology and reclaim policy. Expansion and snapshots depend on the driver and configuration; a Kubernetes API object alone does not establish support.
NKS documentation describes ABS-backed persistent volumes in us-sva-2 and a preconfigured StorageClass. ABS includes 20,000 baseline IOPS. That makes it a candidate for this evaluation, not proof of sub-second dashboard performance. Confirm the intended region and validate recovery, backups and expansion for the actual cluster.
Run a controlled worker-replacement test, validate known records and time recovery to useful queries. Rehearse an independent backup restore as a separate operation. Compare the total cost of the configurations that pass: compute, storage performance, replicas, backups, networking and operating effort.
For a managed service for ClickHouse, start an Altinity.Cloud trial and bring this workload contract. Then evaluate Nirvana as the infrastructure option. Use our BYOC evaluation and migration guide to plan ownership and cutover after the sizing test succeeds.
FAQ
How many IOPS does ClickHouse need?
There is no single number. Query pruning, block sizes, cache behavior, ingestion, merges and concurrency change demand. Measure the workload that must meet your latency and freshness targets.
Why can a fast disk still produce slow dashboards?
CPU saturation, inefficient queries, memory pressure, queueing and application/network time can dominate. Correlate client latency with database and storage evidence before changing the disk.
Does replication replace backups?
No. Test availability and independent data recovery separately. A replica can reproduce an unwanted logical change; a recovery plan needs a retained, restorable copy appropriate to the failure.
About Nirvana Labs
Nirvana Labs is a high-performance storage cloud purpose built for blockchain, AI and databases i.e. the most demanding, real-time, stateful workloads. Accelerated Block Storage (ABS) offers 20K baseline IOPS included, no over provisioning. Nirvana Kubernetes Service (NKS) with Karpenter auto-scaling, high clock-speed compute and private networking. Backed by Jump Trading, Crucible, etc with 50+ customers live in production today.
Learn more at Nirvana Labs
Nirvana Cloud | Pricing | Blog | Docs | Changelog | LinkedIn | Twitter | Telegram | YouTube
Related Posts

Build or Buy a Secure Code Interpreter Backend for AI Agents?
Decide who should operate your AI code execution backend, with clear security boundaries, durable-state requirements and an application acceptance test.

How to Benchmark PostgreSQL WAL and Commit Performance on Cloud Storage
A repeatable PostgreSQL storage evaluation: control durability settings, separate transaction and commit latency, inspect WAL and checkpoint metrics, and test recovery.

How to Test Redis AOF Rewrites and Recovery Before Production
A practical acceptance test for Redis persistence: measure rewrites under load, validate acknowledged writes after failure, and prove independent backup recovery.