ClickHouse Cloud Performance, Scalability, High Availability and FinOps: 4 Proven Pillars of ChistaDATA’s Long-Term Commitment

ClickHouse Cloud performance is now a board-level concern for any enterprise that runs revenue-facing analytics, fraud models or customer dashboards on the service. The managed service removes a great deal of operational toil: no Keeper ensembles to size, no disks to provision, no binaries to patch. It does not remove the engineering decisions that set latency, resilience and the monthly invoice. Those remain the customer’s, and they compound for years.

This paper sets out ChistaDATA’s long-term commitment to ClickHouse Cloud performance and to the customers who depend on it. We cover four pillars, performance, scalability, high availability and FinOps. For each one we state what we own, how we measure it and the code we use. Where we have measured something ourselves, we publish the method alongside the number.

The position in brief

ChistaDATA was built on 100% open-source ClickHouse with zero vendor lock-in, and that does not change. Many enterprises have chosen ClickHouse Cloud, and many more will. Our commitment is to engineer ClickHouse Cloud performance, scale, availability and cost to the same standard we apply to self-managed estates. The same 24x7x365 operations team runs it from the SF Bay Area plus eleven global offices.

In our own lab, codec choices alone cut compressed storage by 60.5 percent, and an hourly rollup cut rows scanned 28.8 times for fleet-wide queries. In the illustrative cost model below, compute is more than twenty times the storage line, so the largest FinOps lever is compute design rather than storage.

Our position on ClickHouse Cloud

We are vendor-neutral by principle, and that applies to ClickHouse Cloud performance advice as much as to platform choice. ClickHouse Cloud fits well when a team wants elastic compute, storage separated from compute, idling for intermittent workloads, and a vendor-operated control plane. Self-managed open-source ClickHouse fits better when the workload is steady and large, when data residency rules require infrastructure the customer controls, or when engine-level control matters. We advise both ways and help customers move in either direction.

What we will not do is treat a managed service as a finished architecture. ClickHouse Cloud performance still depends on sort keys, codecs, rollups and query shape. Resilience still depends on replica placement, backup policy and drills. The invoice still depends on how many compute units are awake and why. Those are engineering responsibilities, and they are the ones we accept.

The operating model: four pillars and one measurement loop

Every engagement runs on the same model. Each pillar has an owner, a metric and a review date, and a change made for one pillar is checked against the other three. A larger replica improves ClickHouse Cloud performance and also raises cost. A shorter idle timeout saves money and also adds cold-start latency. Neither decision is made in isolation.

ClickHouse Cloud performance, scalability, high availability and FinOps operating model with the metrics ChistaDATA measures for each pillar

Figure 1. Four pillars of ClickHouse Cloud performance and cost engineering, each tied to a system table or billing metric and reviewed monthly.

Pillar one: ClickHouse Cloud performance engineering

ClickHouse Cloud performance starts from the same evidence as any ClickHouse estate: system.query_log. A service can have several replicas, so we always read it across all of them. The query below ranks query fingerprints by total bytes read over seven days. Bytes read are the closest single proxy for the compute a query consumes.

SELECT
    normalized_query_hash,
    any(query)                                   AS sample_query,
    count()                                      AS executions,
    formatReadableSize(sum(read_bytes))          AS total_read,
    round(quantile(0.95)(query_duration_ms))     AS p95_ms,
    round(quantile(0.99)(query_duration_ms))     AS p99_ms,
    any(user)                                    AS sample_user
FROM clusterAllReplicas('default', system.query_log)
WHERE event_date >= today() - 7
  AND type = 'QueryFinish'
  AND query_kind = 'Select'
GROUP BY normalized_query_hash
ORDER BY sum(read_bytes) DESC
LIMIT 25;

The top twenty-five fingerprints usually account for most of the bytes read. We work down that list with EXPLAIN indexes = 1, checking whether the sort key prunes granules. Where it does not, we change the key, add a projection, or add a rollup.

ClickHouse Cloud performance SLOs per service

Averages hide the queries customers complain about, so ClickHouse Cloud performance is reported as percentiles per user and per hour. This query feeds the monthly review and the alerting thresholds we agree with each customer:

SELECT
    toStartOfHour(event_time)                    AS hour_bucket,
    user,
    count()                                      AS queries,
    round(quantile(0.95)(query_duration_ms))     AS p95_ms,
    round(quantile(0.99)(query_duration_ms))     AS p99_ms,
    countIf(exception_code != 0)                 AS failed,
    formatReadableSize(sum(read_bytes))          AS read_total
FROM clusterAllReplicas('default', system.query_log)
WHERE event_time >= now() - INTERVAL 1 DAY
  AND type IN ('QueryFinish', 'ExceptionWhileProcessing')
  AND query_kind = 'Select'
GROUP BY
    hour_bucket,
    user
ORDER BY
    hour_bucket,
    p99_ms DESC;

A ClickHouse Cloud performance SLO is only useful if it is owned. Each customer-facing service gets a named p99 target, an error budget and a review date. When the p99 burns through its budget, the response is engineering work on the top fingerprints, not a larger replica by default.

Codecs: a storage lever that also reduces I/O

On ClickHouse Cloud, storage is billed per compressed terabyte-month and backups at the same rate. Compressed bytes are also what every query has to read from object storage or cache. We measured three codec strategies on 30 million rows of synthetic device telemetry with an identical sort key. Only the column definitions differed:

CREATE TABLE finops.telemetry_tuned_v2
(
    tenant_id     UInt32                  CODEC(T64, ZSTD(3)),
    event_time    DateTime                CODEC(DoubleDelta, ZSTD(3)),
    device_id     UInt64                  CODEC(ZSTD(3)),
    metric_name   LowCardinality(String)  CODEC(ZSTD(3)),
    metric_value  Float64                 CODEC(ZSTD(3)),
    status_code   UInt16                  CODEC(T64, ZSTD(3))
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(event_time)
ORDER BY (tenant_id, metric_name, event_time);
-- On ClickHouse Cloud the MergeTree engine is mapped to SharedMergeTree.

-- Measure the effect per column, before and after
SELECT
    table,
    name                                                    AS column,
    formatReadableSize(data_compressed_bytes)               AS compressed,
    round(data_uncompressed_bytes / data_compressed_bytes, 1) AS ratio
FROM system.columns
WHERE database = 'finops'
  AND table LIKE 'telemetry%'
ORDER BY
    column,
    table;

Default codecs produced 189.8 MiB. The tuned table with Gorilla on the float column produced 107.0 MiB. The same table with plain ZSTD on the float produced 75.0 MiB, a 60.5 percent reduction against the default. The largest single gain came from DoubleDelta on event_time: 98.2 MiB fell to 161.8 KiB. The result we did not expect was Gorilla. On this noisy float series it compressed worse than plain ZSTD, at 92.3 MiB against 71.8 MiB for the default codec on that column. Codec advice that is not measured on the customer’s own data is a guess, and so is any ClickHouse Cloud performance claim made without a measurement.

Rollups: where they pay and where they do not

CREATE TABLE finops.telemetry_hourly
(
    tenant_id    UInt32,
    metric_name  LowCardinality(String),
    hour_bucket  DateTime,
    samples      AggregateFunction(count),
    avg_value    AggregateFunction(avg, Float64),
    p95_value    AggregateFunction(quantileTDigest(0.95), Float64)
)
ENGINE = AggregatingMergeTree
PARTITION BY toYYYYMM(hour_bucket)
ORDER BY (tenant_id, metric_name, hour_bucket);

CREATE MATERIALIZED VIEW finops.telemetry_hourly_mv
TO finops.telemetry_hourly
AS
SELECT
    tenant_id,
    metric_name,
    toStartOfHour(event_time)                 AS hour_bucket,
    countState()                              AS samples,
    avgState(metric_value)                    AS avg_value,
    quantileTDigestState(0.95)(metric_value)  AS p95_value
FROM finops.telemetry_tuned_v2
GROUP BY
    tenant_id,
    metric_name,
    hour_bucket;

For a 30-day query across all tenants, EXPLAIN ESTIMATE put the raw table at 20,736,000 rows and the rollup at 720,000, which is 28.8 times fewer. Median latency fell from 579.0 ms to 300.4 ms. It fell by less than the row count because merging t-digest states costs CPU. For the same query scoped to one tenant, the raw table was already pruned to 49,152 rows by the sort key and ran in 5.3 ms. The rollup took 7.5 ms. A rollup earns its keep on wide scans, not on queries the sort key has already narrowed. That is the kind of distinction ClickHouse Cloud performance reviews exist to make.

ClickHouse Cloud performance lab results: codec tuning cut storage from 189.8 to 75.0 MiB and an hourly rollup cut rows scanned 28.8 times

Figure 2. Measured effect of two ClickHouse Cloud performance levers. Lab: chDB 4.4.0 embedding ClickHouse 26.9.2.1, 2 vCPU, 7 GB RAM, median of 7 runs. This is not a ClickHouse Cloud benchmark; the absolute latencies will differ on Cloud hardware.

Our commitment: every ClickHouse Cloud performance recommendation we make arrives with the EXPLAIN output, the before-and-after read_bytes and the p95 change that justify it.

Pillar two: ClickHouse Cloud scalability by design

On the Scale tier, ClickHouse Cloud scales vertically on its own and horizontally on request. Autoscaling is useful. It is not a scalability design. Without one, ingest, dashboards and ad-hoc analysis compete for the same replicas, and the autoscaler buys more memory to settle the argument.

Our default design uses ClickHouse Cloud warehouses, the compute-compute separation available on the Scale and Enterprise tiers. Several services share one copy of the data in object storage. Each service has its own replicas, size, autoscaling and idling. Read-only secondaries run no background merges, so all of their capacity goes to queries.

ClickHouse Cloud scalability design with compute-compute separation: read-write primary for ingest and read-only secondaries for dashboards and analysts sharing SharedMergeTree storage

Figure 3. A warehouse layout that protects ClickHouse Cloud performance for customer-facing queries: ingest on the primary, dashboards and analysts on separate read-only services.

Separation is enforced with roles and settings profiles as well as endpoints. An analyst who connects to the wrong service still hits a ceiling:

CREATE SETTINGS PROFILE analyst_guardrails
SETTINGS
    max_execution_time = 120,
    max_bytes_to_read = 500000000000,
    read_overflow_mode = 'throw',
    max_result_rows = 1000000,
    max_memory_usage = 20000000000
TO analyst_role;

-- Wide scans on large services: let replicas share the read.
-- Measure p95 before and after; parallel replicas add coordination overhead.
SELECT
    metric_name,
    avg(metric_value) AS avg_value
FROM finops.telemetry_tuned_v2
WHERE event_time >= now() - INTERVAL 90 DAY
GROUP BY metric_name
SETTINGS
    enable_parallel_replicas = 1,
    max_parallel_replicas = 3;

We track three scalability signals monthly alongside ClickHouse Cloud performance percentiles: memory headroom per replica, the number of autoscaling events that reached the configured ceiling, and ingest lag at the daily peak against the agreed freshness SLO. A service that regularly reaches its ceiling is under-designed, not under-provisioned, and ClickHouse Cloud performance will degrade at the next peak.

Our commitment: scalability changes are checked against ClickHouse Cloud performance targets and against the invoice before they are applied, never after.

Pillar three: ClickHouse Cloud high availability you have rehearsed

The Scale tier spreads a service across two or more availability zones, and ClickHouse Keeper is operated by the vendor. Two facts from the published documentation shape our designs. Single-replica services are limited to small memory sizes, so a production service should run at least two replicas. The default backup policy is one backup every 24 hours, retained for one day, which is rarely enough for a regulated workload.

We check replica health from inside the service, then codify the backup policy so it cannot drift:

-- Every replica of the current service should answer
SELECT
    hostName()                      AS replica,
    uptime()                        AS uptime_seconds,
    version()                       AS server_version
FROM clusterAllReplicas('default', system.one)
ORDER BY replica;
# Terraform, ClickHouse provider. Values are an example policy, not a default.
# Plan and review in a non-production workspace before applying.
resource "clickhouse_service" "analytics_primary" {
  name                  = "analytics-primary"
  cloud_provider        = "aws"
  region                = "us-east-1"
  num_replicas          = 3
  min_replica_memory_gb = 16
  max_replica_memory_gb = 64
  idle_scaling          = false
  password_hash         = var.ch_password_hash

  ip_accesses = [
    { source = var.vpc_egress_cidr, description = "application VPC" }
  ]

  backup_configuration = {
    backup_period_in_hours           = 6
    backup_retention_period_in_hours = 720
  }
}

Backups run only from the primary service of a warehouse, and a restore creates a new service outside the warehouse. A restore is therefore a reconfiguration of endpoints and secondaries, not a single click. We rehearse it every quarter, record the restore time against the agreed RTO and the recovery point against the agreed RPO, and file the result with the customer. An untested backup is a hypothesis, not a recovery plan. Availability is the part of ClickHouse Cloud performance that users notice most when it fails.

Our commitment: a restore drill every quarter, with the measured RTO and RPO filed with the customer, and a backup policy held in code.

Pillar four: ClickHouse Cloud FinOps a CFO can audit

ClickHouse Cloud bills compute per compute unit (8 GiB of memory and 2 vCPU) per hour, metered per minute. It bills storage and backups per terabyte-month, and egress per gigabyte. The published ClickHouse Cloud list rates for AWS us-east-1 were USD 0.39030 per compute-unit-hour and USD 25.30 per TB-month when we checked on 5 November 2026. Prices change, so verify them before relying on any figure below.

Cost attribution comes from the billing API, not from estimates, and it sits next to the ClickHouse Cloud performance figures in the same monthly report. This read-only script pulls daily cost by entity and meter from the usageCost endpoint:

"""Daily ClickHouse Cloud cost by service and meter, from the usageCost API.

Read-only. Needs an API key with control-plane:organization:view.
Usage: CH_ORG_ID=... CH_KEY_ID=... CH_KEY_SECRET=... python3 usage_cost.py 2026-10-01 2026-10-31
"""
import os
import sys
from collections import defaultdict

import requests

API = "https://api.clickhouse.cloud/v1/organizations/{org}/usageCost"


def fetch(org_id, key_id, key_secret, from_date, to_date, tag=None):
    params = {"from_date": from_date, "to_date": to_date}  # max 31 days, UTC
    if tag:
        params["filter"] = [f"tag:{tag}"]
    resp = requests.get(API.format(org=org_id), params=params,
                        auth=(key_id, key_secret), timeout=30)
    resp.raise_for_status()
    return resp.json()["result"]


def summarise(result):
    by_entity = defaultdict(lambda: defaultdict(float))
    for row in result["costs"]:
        name = f'{row["entityType"]}:{row["entityName"]}'
        for meter, value in (row.get("metrics") or {}).items():
            by_entity[name][meter] += value or 0.0
        by_entity[name]["totalCHC"] += row.get("totalCHC") or 0.0
    return by_entity


if __name__ == "__main__":
    result = fetch(os.environ["CH_ORG_ID"], os.environ["CH_KEY_ID"],
                   os.environ["CH_KEY_SECRET"], sys.argv[1], sys.argv[2],
                   tag=os.environ.get("CH_TAG_FILTER"))  # e.g. Environment=Production
    grand = result["grandTotalCHC"] or 1.0
    rows = sorted(summarise(result).items(),
                  key=lambda kv: kv[1]["totalCHC"], reverse=True)
    for name, m in rows:
        print(f"{name[:48]:48} compute={m['computeCHC']:10.2f} "
              f"storage={m['storageCHC']:9.2f} backup={m['backupCHC']:8.2f} "
              f"share={100 * m['totalCHC'] / grand:5.1f}%")

The illustrative model below uses the list compute rate above with the warehouse in Figure 3. The always-on column keeps every service awake for the whole month. The designed column keeps the primary always on, wakes the dashboard service fourteen hours a day, and wakes the analyst service six hours on 22 working days.

Service (illustrative)Compute unitsAlways on, USD/monthDesigned, USD/month
Primary, 3 x 16 GiB61,709.511,709.51
Dashboards, 2 x 32 GiB82,279.351,328.89
Analysts, 1 x 64 GiB82,279.35412.16
Compute total226,268.223,450.56
Storage, 10 TB compressedn/a253.00100.01 with lab codec ratio

These figures are arithmetic on list prices, not a quote or a customer result. Two conclusions hold regardless of scale. Idling design removed 45 percent of compute spend in this model. Compute was more than twenty times storage, so a FinOps programme that starts with storage starts in the wrong place. The idling and the ceilings belong in code:

resource "clickhouse_service" "analysts" {
  name                  = "analytics-adhoc"
  warehouse_id          = var.analytics_warehouse_id   # warehouse of the primary service
  readonly              = true
  cloud_provider        = "aws"
  region                = "us-east-1"
  num_replicas          = 1
  min_replica_memory_gb = 16
  max_replica_memory_gb = 64     # spend ceiling: autoscaling stops here
  idle_scaling          = true
  idle_timeout_minutes  = 15     # minimum 5; trade cold starts against cost
  password_hash         = var.ch_password_hash
}

Our twelve-metric ClickHouse Cloud FinOps scorecard covers the monthly metrics in detail, and the managed ClickHouse Cloud FinOps service runs them for customers.

Our commitment: cost is reported per service, per meter and per tag every month, and no saving is traded for ClickHouse Cloud performance the business has not agreed to give up.

What the commitment means in practice

CadenceWhat we deliver
Continuous24x7x365 support with an S1 response in 15 minutes, S2 in 12 hours, S3 in 24 hours and S4 in 48 hours
MonthlyClickHouse Cloud performance and cost review: top fingerprints, p95 and p99 per service, cost by service and meter
QuarterlyRestore drill with measured RTO and RPO; warehouse and ceiling review; capacity forecast
Per releaseReview of behaviour changes against the customer’s query history before the service’s upgrade window
At any timeAn honest assessment of whether ClickHouse Cloud or self-managed open-source ClickHouse is the better fit, and a migration path in either direction

The last line matters most to us. A long-term commitment to a customer’s ClickHouse Cloud performance is only credible if we are also prepared to say when Cloud is the wrong answer.

Where this guidance stops

The lab figures come from a single small node running the open-source engine through chDB, not from ClickHouse Cloud hardware. They show the mechanisms behind ClickHouse Cloud performance; they do not predict your latency or bill. The cost table is illustrative arithmetic on list prices that change. ClickHouse Cloud features, tiers and Terraform provider arguments also evolve, so confirm them against the vendor’s current documentation. Test every change on your own workload in a non-production service first, with a verified backup and a rehearsed restore behind it.

Engineer ClickHouse Cloud performance and cost for the long term

ChistaDATA architects review your ClickHouse Cloud performance, warehouse design, sort keys, codecs, backup policy and invoice against measured evidence, then stay on to operate what they recommend, 24x7x365.

ClickHouse consulting 24×7 ClickHouse support

About ChistaDATA Inc. 270 Articles
ChistaDATA is a full-stack ClickHouse infrastructure operations company delivering consulting, 24×7 enterprise support, and managed services, with core expertise in performance engineering, scalability, and data SRE. Headquartered in California, our consulting and support engineering teams operate from San Francisco, Vancouver, London, Germany, Russia, Ukraine, Australia, Singapore, and India, providing follow-the-sun, enterprise-class consultative support around the clock. We work closely with more than 200 customers globally, including some of the largest planet-scale internet properties, financial-services institutions, consumer brands, and industrial IoT programmes.