Skip to content
ClickHouse Pricing Explained: 2026 Guide

Click to use (opens in a new tab)

ClickHouse Pricing Explained: 2026 Guide

September 17, 2026 by Chat2DBChat2DB Team

ClickHouse is open source and free to run yourself. ClickHouse Cloud is not, and its bill behaves unlike a traditional database service: there is no instance size to pick, compute scales itself, and storage is billed separately against compressed bytes in object storage. That decoupling is the whole model, and understanding it is the difference between a predictable bill and a surprising one.

This guide explains the pricing structure and the levers you control. It deliberately avoids quoting rates — ClickHouse revises them, and regions differ — so check clickhouse.com/pricing (opens in a new tab) for current figures and use this as the map of where those figures apply.

The core idea: compute and storage are separate

Self-hosted ClickHouse stores data on the disks attached to your servers. Scaling storage means scaling servers, so you pay for CPU you do not need in order to get disk you do.

ClickHouse Cloud splits them. Data lives in object storage (S3, GCS, Azure Blob); stateless compute nodes read it with an aggressive local cache. The consequences for your bill:

  • Storage is billed per compressed TB per month. Compression ratio therefore directly reduces the storage line.
  • Compute is billed per unit of memory and CPU per hour, only while replicas are running.
  • Scaling one does not force you to scale the other. A 50 TB archive queried twice a day costs almost nothing in compute.

Compute: the part that moves

Compute is where surprises live, because it is dynamic by design.

Vertical autoscaling. Services grow and shrink their replica size within bounds you set, based on load. You do not choose an instance type; you choose a floor and a ceiling. Setting the floor too high is the most common source of waste — it is the number you pay for during every idle hour.

Replica count. Services run multiple replicas for availability, and you pay per replica. Doubling replicas doubles compute cost; it adds read throughput but does nothing for a single slow query.

Idling. Development-oriented services can suspend after a period of inactivity and stop billing compute. The first query after a suspension pays a wake-up latency of some seconds. For non-production services this is usually the single biggest saving available; for anything user-facing it is a false economy.

The practical model: compute cost ≈ replica size × replica count × hours awake. Every optimization below reduces one of those three.

Storage: compression is a pricing feature

You are billed on compressed bytes, which turns schema design into a cost decision. Check what you actually store:

SELECT
    table,
    formatReadableSize(sum(data_compressed_bytes))   AS compressed,
    formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed,
    round(sum(data_uncompressed_bytes) /
          sum(data_compressed_bytes), 2)             AS ratio
FROM system.columns
WHERE database = currentDatabase()
GROUP BY table
ORDER BY sum(data_compressed_bytes) DESC;

A ratio near 1 means a column is not compressing — usually a high-cardinality String that should be something else. Then drill into the worst offenders:

SELECT
    name, type,
    formatReadableSize(sum(data_compressed_bytes)) AS compressed,
    round(sum(data_uncompressed_bytes) /
          sum(data_compressed_bytes), 2)           AS ratio
FROM system.columns
WHERE table = 'events'
GROUP BY name, type
ORDER BY sum(data_compressed_bytes) DESC
LIMIT 20;

Three changes typically move the number a lot:

-- 1. LowCardinality for repeated strings (under ~10k distinct values)
ALTER TABLE events MODIFY COLUMN country LowCardinality(String);
 
-- 2. Delta + ZSTD for timestamps and monotonic integers
ALTER TABLE events MODIFY COLUMN event_time DateTime CODEC(Delta, ZSTD(1));
 
-- 3. Right-size numeric types: UInt8 not Int64 for a status enum
ALTER TABLE events MODIFY COLUMN status UInt8;

Because the sorting key determines how well data compresses, ORDER BY is a cost lever too: sorting so that similar values sit next to each other can change the ratio substantially. The ClickHouse MergeTree table generator (opens in a new tab) applies these codec and key conventions when you sketch a new table.

TTL: the cheapest storage is deleted storage

Most event data is queried intensively for days and then almost never. TTL automates the cleanup:

ALTER TABLE events
MODIFY TTL event_date + INTERVAL 90 DAY DELETE;

Or keep it, but move it to cheaper storage:

ALTER TABLE events
MODIFY TTL event_date + INTERVAL 30 DAY TO VOLUME 's3',
           event_date + INTERVAL 365 DAY DELETE;

You can also aggregate on expiry — keeping the shape of old data at a fraction of the size:

ALTER TABLE events
MODIFY TTL event_date + INTERVAL 30 DAY
GROUP BY event_date, event_type
SET views = sum(views), duration_ms = avg(duration_ms);

The other meters

Beyond compute and storage, four things can appear on a bill:

  • Data transfer. Egress to the public internet and cross-region traffic are billed; traffic within the same region and cloud usually is not. Putting your application in the same region as the service is a real saving, not a rounding error.
  • Backups. One backup is typically included; extra retention or frequency adds storage cost.
  • ClickPipes. Managed ingestion from Kafka, S3 and Postgres is billed for the compute it consumes, separately from your service.
  • Support tier. Enterprise support is a percentage uplift on spend, not a flat fee.

Watching spend from inside the database

ClickHouse exposes its own usage, so you can attribute cost without leaving SQL:

-- Which queries burn the most CPU time?
SELECT
    normalized_query_hash,
    any(substring(query, 1, 80))       AS sample,
    count()                            AS runs,
    formatReadableTimeDelta(sum(query_duration_ms) / 1000) AS total_time,
    formatReadableSize(sum(read_bytes))                    AS bytes_read,
    formatReadableSize(sum(memory_usage))                  AS memory
FROM system.query_log
WHERE event_time > now() - INTERVAL 7 DAY
  AND type = 'QueryFinish'
GROUP BY normalized_query_hash
ORDER BY sum(query_duration_ms) DESC
LIMIT 20;

Sorting by read_bytes instead often finds the true cost driver: a query reading terabytes because its filter does not align with the sorting key forces the cluster to stay scaled up.

-- Full-scan detector: queries reading a large share of the table
SELECT
    substring(query, 1, 100) AS query,
    formatReadableSize(read_bytes) AS read,
    read_rows,
    query_duration_ms
FROM system.query_log
WHERE type = 'QueryFinish'
  AND event_time > now() - INTERVAL 1 DAY
  AND read_rows > 100000000
ORDER BY read_bytes DESC
LIMIT 10;

Practical ways to cut the bill

  1. Fix the sorting key before you add replicas. A query that scans the whole table is a compute bill. Reordering ORDER BY so the common filter is a leading column often removes more cost than any infrastructure change.
  2. Use materialized views for repeated aggregations. Pre-aggregating on insert turns a heavy dashboard query into a small read:
    CREATE MATERIALIZED VIEW events_daily_mv
    ENGINE = SummingMergeTree()
    ORDER BY (event_date, event_type)
    AS SELECT
        toDate(event_time) AS event_date,
        event_type,
        count()            AS events,
        sum(duration_ms)   AS total_duration
    FROM events
    GROUP BY event_date, event_type;
  3. Lower the autoscaling floor on anything that is not consistently busy.
  4. Enable idling on dev and staging. Non-production services are awake for no reason most of the week.
  5. Insert in batches. Many small inserts create many parts, and merging them is compute you pay for. Batch to tens of thousands of rows, or let async inserts do the batching.
  6. Apply TTL early. Storage you never query is the easiest line item to remove.

When self-hosting is cheaper

Self-hosted ClickHouse has no licence cost. On steady, predictable, high-utilization workloads — a cluster that is busy most hours of most days — running it on your own instances is usually less expensive in raw infrastructure.

What you take on is the operational surface: cluster setup, ClickHouse Keeper, replication and shard topology, upgrades, backup and restore, and monitoring. That is at least a part-time role for someone who understands ClickHouse specifically. The honest comparison is not "cloud bill versus EC2 bill" but "cloud bill versus EC2 bill plus engineer time plus the incidents you will handle yourself".

Cloud tends to win for spiky, unpredictable or growing workloads, and for teams without a dedicated data-infrastructure person. Self-hosting tends to win at sustained scale where someone already owns that expertise.

Whichever you run, you still need a client to explore the data. Chat2DB (opens in a new tab) connects to both self-hosted ClickHouse and ClickHouse Cloud, and the same tool handles the Postgres and MySQL databases alongside it; a browser version is at app.chat2db.ai (opens in a new tab).