Author: Alexey Milovidov, 2026-06-25.
1. (50 min) What's new in ClickHouse 26.6.
2. (10 min) Q&A.
ClickHouse "10 Year Anniversary" Release.
โ 56 new features ๐
โ 79 performance optimizations ๐๏ธ
โ 366 bug fixes ๐ฆ
Append new Enum values without re-typing all the existing ones:
CREATE TABLE events (x Enum8('a' = 1, 'b' = 2)) ...;
-- Before: ALTER ... MODIFY COLUMN x Enum8('a'=1,'b'=2,'c'=3,'d'=4)
ALTER TABLE events MODIFY COLUMN x ADD ENUM VALUES('c' = 3, 'd' = 4);
-- x is now Enum8('a' = 1, 'b' = 2, 'c' = 3, 'd' = 4)
โ A pure metadata change โ instant, no data rewrite.
โ Forgetting an existing value is no longer possible.
Developer: Ilya Golshtein.
Precision arguments and decimal-point control for text output:
SELECT formatReadableSize(1234567890, 4);
-- 1.1498 GiB (default precision is 2: 1.15 GiB)
SELECT 1/3 SETTINGS output_format_float_precision = 4;
-- 0.3333
SELECT 5.0 SETTINGS output_format_always_write_decimal_pointโฆ = 1;
-- 5. (keep the decimal point even for whole numbers)
โ formatReadableSize / formatReadableQuantity / formatReadableDecimalSize take an optional precision.
Developers: Antonio Filipovic, phulv94, Ilya Yatsishin.
A refreshable MV can now trigger off another RMV's refresh:
CREATE MATERIALIZED VIEW base
REFRESH EVERY 1 HOUR ENGINE = MergeTree ORDER BY day AS โฆ;
CREATE MATERIALIZED VIEW rollup
REFRESH DEPENDS ON base ENGINE = โฆ AS
SELECT day, sum(x) FROM base GROUP BY day;
Developer: Michael Kolupaev.
Two new MergeTree settings decouple projection building from INSERT:
CREATE TABLE ...
SETTINGS materialize_projections_on_insert = 0;
-- INSERTs skip building projection parts โ faster ingestion
CREATE TABLE ...
SETTINGS materialize_projections_on_merge = 1;
-- a merge rebuilds a projection missing from all its source parts
โ Tables with many projections ingest faster;
โ projections are built during merges instead.
Developer: Christoph Wurm.
Key a quota by a subnet, not just a single address:
CREATE QUOTA q KEYED BY ip_address IPV4_PREFIX_BITS 24
FOR INTERVAL 1 hour MAX queries = 1000;
-- every client in a /24 shares one quota bucket
CREATE QUOTA q6 KEYED BY ip_address IPV6_PREFIX_BITS 64 โฆ;
โ Rate-limit a whole network range at once.
โ Works with IP_ADDRESS and FORWARDED_IP_ADDRESS keys.
โ Especially useful for IPv6.
Developer: Aditya Chopra.
Type help <name> in clickhouse-client / clickhouse-local to read the docs
right in the terminal โ backed by system.documentation:
:) help MergeTree
โ Also /help, man, /man. Resolves ambiguity and typos.
โ Markdown rendered in the terminal, with syntax-highlighted SQL.
Demo
Developer: Alexey Milovidov.
System tables that describe the system now describe themselves โ with
description, syntax, examples, introduced_in and related columns:
SELECT name, introduced_in
FROM system.table_engines WHERE name ILIKE '%kafka%';
SELECT name, description FROM system.data_type_families;
Now self-documenting: table_engines, database_engines, data_type_families, formats, aggregate_function_combinators, dictionary_layouts, dictionary_sources, data_skipping_index_types, disk_types.
Developer: Alexey Milovidov.
The whole reference manual, as a table, inside the server:
SELECT type, count() FROM system.documentation GROUP BY type;
| type | count |
|---|---|
| Function | 1592 |
| Setting | 1548 |
| Server Setting / MergeTree Setting | 412 / 316 |
| Aggregate Function, Data Type, Format, โฆ | โฆ |
โ The same docs as the website โ queryable, greppable, offline.
โ Good for integration with tools.
Developer: Alexey Milovidov.
More of ClickHouse, introspectable as tables:
SELECT table, name, type, expression FROM system.constraints;
โ system.constraints โ every table's CHECK / ASSUME constraints.
โ system.iceberg_files โ introspection of files in Iceberg tables.
Keeper related tables (available on clickhouse-keeper):
โ system.keeper_snapshots
โ system.keeper_changelogs
โ system.keeper_cluster.
Developers: Pedro Ferreira, Miัhael Stetsyuk, Han Fei.
ClickHouse now detects the AI coding agent that launched the client,
from its environment, and records it in a new client_agent column:
SELECT query_id, client_agent, interface FROM system.processes;
| query_id | client_agent | interface |
|---|---|---|
| ai_demo | claude-code | 1 |
โ Recognizes Claude Code, Cursor, Codex, Gemini CLI, Goose, โฆ
โ Also in system.query_log and system.query_thread_log.
Developer: Alexey Milovidov.
clickhouse-local can now start listening for connections on the fly:
clickhouse-local
:) SYSTEM START LISTEN TCP;
:) SYSTEM START LISTEN HTTP;
-- now other clients can connect to your local session
โ Turn an ad-hoc analysis session into a shareable endpoint.
โ SYSTEM STOP LISTEN to close it again.
Developer: Alexey Milovidov.
A new built-in web UI that draws the dependency graph of your database:
http://localhost:8123/schema
โ Tables, materialized views, refreshable MVs, dictionaries,
โ distributed tables and views โ and the arrows between them.
โ See at a glance how data flows from ingestion to rollups.
โ Embedded in the server.
Developer: Nikita Mikhaylov.
Render query results as an image. One row per pixel (r, g, b or v),
with implicit or explicitly defined pixel coordinates (x, y):
WITH number DIV 1024 AS y, number MOD 1024 AS x,
L2Norm((x - 512, y - 512)) / 512 AS radius, 60 AS stripe_size,
round((atan2(x - 512, y - 512) / pi() * 180 + exp(radius) * 90)
/ stripe_size) * stripe_size AS alpha,
radius <= 1 ? abs(1 - (radius - 0.5) * (radius - 0.5) * 4) : 0 AS a,
colorOKLCHToSRGB((0.7, 0.15, alpha)) AS rgb
SELECT rgb.1::UInt8 AS r, rgb.2::UInt8 AS g, rgb.3::UInt8 AS b, a
FROM numbers(1048576) FORMAT PNG
SETTINGS output_format_image_terminal_mode = 'kitty'
โ The Web UI shows the image directly.
โ Great for heatmaps, sparklines, generated art.
Developer: Maksim Dergousov.
date_part('unit', expr)
โ PostgreSQL-style sugar for EXTRACT(unit FROM expr):
SELECT date_part('year', toDateTime('2026-06-25 10:30:00')); -- 2026
SELECT date_part('doy', toDate('2026-06-25')); -- 176 (day of year)
SELECT date_part('dow', toDate('2026-06-25')); -- 4 (day of week)
โ All the PostgreSQL extras: epoch, dow, doy, isodow, isoyear, century, decade, millennium.
โ Also: EXTRACT(TIMEZONE_HOUR / TIMEZONE_MINUTE FROM dt)
โ and EXTRACT(โฆ FROM INTERVAL n โฆ).
Developers: Alexey Milovidov, Vinayak Joshi.
More SQL-standard / PostgreSQL spellings:
SELECT LOCALTIMESTAMP; -- now() โ DateTime
SELECT LOCALTIME; -- current time of day โ Time
SELECT SESSION_USER; -- alias of currentUser()
โ No parentheses needed โ they are reserved-word constants.
โ Makes more ported queries and BI-tool SQL just work.
Developers: Thomas Cabral, Takumi Hara.
min_by / max_by โ aliases for argMin, argMax for PostgreSQL, BigQuery:
SELECT min_by(user, score), max_by(user, score) FROM t;
-- aliases of argMin / argMax
REGEXP_SUBSTR โ alias of regexpExtract, for Oracle/MySQL/Snowflake:
SELECT REGEXP_SUBSTR('order 12345 shipped', '[0-9]+');
-- 12345
"These aliases are stupid, real engineers use the original ClickHouse names." โ the changelog
ALTER TABLE MODIFY COLUMN x UInt32 NULL; -- same as Nullable(UInt32)
Developers: Joey Yu, Alexey Milovidov, Takumi Hara.
PostgreSQL array quantifiers with a literal array on the right:
SELECT 3 = SOME([1, 2, 3]); -- 1 โ rewritten to has(...)
SELECT 5 > ALL([1, 2, 3]); -- 1 โ arrayAll lambda
SELECT 2 <> ALL([1, 3, 5]); -- 1
The subquery form of ANY / SOME / ALL still lowers to IN / NOT IN.
Developer: Alexey Milovidov.
Pick columns with * LIKE and * ILIKE instead of listing them:
SELECT * ILIKE '%user%' FROM events;
-- user_id, user_name, ... (case-insensitive)
SELECT t.* ILIKE '%id', count() FROM t GROUP BY ALL;
-- qualified form works too
Similar to * MATCH 'regexp' and COLUMNS('regexp'),
but with SQL-style LIKE patterns instead of a regular expression.
Developer: Yue Ni.
Define a custom escape character so % and _ can be literal:
SELECT '50% off' LIKE '50!% off' ESCAPE '!';
-- 1 (the !% matches a literal percent sign)
SELECT 'a_b' LIKE 'a!_b' ESCAPE '!';
-- 1 (the !_ matches a literal underscore)
โ SQL-standard syntax, also accepted by PostgreSQL, MySQL, โฆ
Developer: Ilya Yatsishin.
Read a GeoJSON FeatureCollection โ one row per feature:
SELECT id, properties.name, toTypeName(geometry)
FROM file('places.geojson', GeoJSON);
| id | properties.name | geometry |
|---|---|---|
| 1 | London | Geometry (Point) |
| 2 | square | Geometry (Polygon) |
โ Columns: id String, geometry Geometry, properties Nullable(JSON).
โ Point, LineString, MultiLineString, Polygon, MultiPolygon supported natively.
Developer: Mark Needham.
Serve map tiles straight out of ClickHouse with the new MVT functions:
-- Project lon/lat into a tile's pixel space:
SELECT MVTEncodeGeom((13.37, 52.52)::Point, 10, 550, 335);
-- (124, 3384)
-- Aggregate a group's geometries into one binary tile:
SELECT MVTEncode(geom_in_tile_space) FROM ...;
-- Tile bounding box for the WHERE clause:
SELECT MVTBoundingBox(12, 1205, 2557);
โ Point, line and polygon geometry.
โ Also available as PostGIS aliases ST_AsMVTGeom and ST_AsMVT.
Developer: Saarthak Gupta.
A round of Keeper improvements makes it more twice as fast overall:
โ Better request batching.
โ Pipelining messages to the leader.
โ Pipelining log appends.
โ Snapshot I/O moved to a background thread (nuraft_use_bg_thread_for_snapshot_io).
โ Lower peak memory when applying received snapshots.
On a realistic workload with keeper-bench:
26.5: 2899 RPS, 41.4 ms latency
26.6: 7230 RPS, 18.3 ms latency
Developers: Michael Kolupaev, Antonio Andelic, Mikhail Filimonov.
Per-query overhead for simple queries is significantly reduced:
SELECT count() FROM hits;
-- parsing + analysis + planning ~50% faster from a single connection
More analysis wins, all enabled by default:
โ Identifier-resolution caching during analysis.
โ Fast analysis of deeply nested subqueries.
โ Faster resolution for deeply nested function calls.
โ Faster processing of changing access control entities.
Deeply nested SELECT * over a 1200-column table:
โ analysis 1.46 s โ 0.023 s (~64x), 26.5 vs 26.6.
Developers: Raรบl Marรญn, Dmitry Novik, Max Justus Spransy, Azat Khuzhin.
Long or high-cardinality primary keys used to make index analysis slow.
Now (use_lightweight_primary_key_index_analysis, on by default):
โ For a long primary key, analysis time depends on the columns the query
โ actually filters on โ not on the length of the key.
โ Extending the sorting key is now nearly free for index analysis.
โ For a high-cardinality key, analysis works on just the selective
โ in-memory prefix instead of loading the whole key.
Developer: Nihal Z. Miaji.
The general-purpose comparison sorts are now C++ ports
of ipnsort and driftsort:
โ Faster ORDER BY on non-numeric columns and for stable sorts.
โ Removes a worst case on already reverse-sorted input.
โ State-of-the-art, adaptive, and battle-tested algorithms.
ORDER BY 20M strings, single thread:
โ 7.1 s โ 5.9 s (~1.2x), 26.5 vs 26.6.
Developer: Alexey Milovidov.
โ Sharded aggregation for high-cardinality, evenly-distributed keys
โ (enable_sharding_aggregator = 1): hash the key to scatter rows across
โ threads, so each thread aggregates a disjoint subset โ no merge phase.
โ Hash-table prefetching for string-key GROUP BY: ~8% faster.
โ Lower peak memory when merging large two-level aggregation states
โ (e.g. groupArray).
โ More optimal handling of Nullable columns in aggregation.
โ Packed keys32 / keys64 methods in HashJoin and Set.
Measured โ 300M-row high-cardinality GROUP BY, 16 threads:
โ enable_sharding_aggregator: 2.31 s โ 1.87 s.
Developers: Nihal Z. Miaji, Le Zhang, Yuri Fedoseev, Nikita Taranov.
A whole family of new optimizations for LIMIT BY (all on by default):
โ Run LIMIT BY inside each parallel sorted stream during ORDER BY
โ when its keys are a prefix of the sort key.
โ Stream LIMIT N BY cols in primary-key order with O(1) memory per stream.
โ Apply LIMIT BY per partition in parallel when the partition is a
โ function of the keys.
โ Drop redundant / injective key expressions
โ (LIMIT 5 BY toString(x) โ LIMIT 5 BY x).
Measured โ LIMIT 3 BY g over a 50M-row MergeTree (g is in the sort key):
โ memory 86 MiB โ 22 MiB (~4x), time 0.15 s โ 0.09 s.
Developer: Nihal Z. Miaji.
A batch of JOIN planner and runtime improvements, mostly on by default:
โ enable_join_transitive_predicates on by default โ push derived
โ predicates across the join (filter both sides for free).
โ Build-side FixedHashMap doubles as the probe-side runtime filter.
โ Lazy selector / replication indexes when a JOIN is followed by a
โ selective LIMIT / TopN / another JOIN.
โ parallel_hash is now allowed for ASOF JOIN.
โ Packed keys32 / keys64 in HashJoin; fast path for single-row probes.
โ Dynamic Programming join reordering now works with parallel replicas.
Developers: A. Gololobov, N. Taranov, H. Selmi, Xiaozhe Yu, G. Maher.
A SELECT that never ends โ the first step toward streaming queries. Append STREAM and it keeps emitting new rows as they are inserted:
SET enable_streaming_queries = 1;
SELECT id, msg FROM live_events STREAM; -- blocks, keeps streaming
Applications: filtering and real-time alerting on a stream of events.
Advanced usage with cursors:
SELECT _block_number AS bn, _block_offset AS bo, id, msg
FROM events STREAM CURSOR {'all': {'block_number': 2, 'block_offset': 0}}
Developer: Mikhail Artemenko.
The experimental distributed planner splits a query plan into stages
connected by exchanges โ and ships fragments to worker nodes:
โ scatter / broadcast / gather / shuffle exchanges.
โ Distributed shuffle and broadcast hash joins, shuffle aggregation, distributed sort.
โ Data between stages streamed over TCP or temp files in object storage.
โ Several workers per host (stateless_worker_port / streaming_exchange_port).
Controlled by a new setting, make_distributed_plan.
Developer: Alexander Gololobov.
The workload scheduler โ which already manages CPU, I/O and concurrency โ now manages memory too:
CREATE RESOURCE memory (MEMORY RESERVATION);
CREATE WORKLOAD all;
CREATE WORKLOAD prod IN all SETTINGS max_memory = '100G';
CREATE WORKLOAD reports IN all SETTINGS max_memory = '20G';
CREATE WORKLOAD vasya IN reports SETTINGS weight = 1;
CREATE WORKLOAD petya IN reports SETTINGS weight = 2;
-- route a query to a workload:
SELECT โฆ SETTINGS workload = 'prod';
-- reserve memory before processing:
SET reserve_memory = '5G';
Developer: Sergei Trifonov.
Ask "what if I had this skip index?" โ without building it:
CREATE HYPOTHETICAL INDEX idx_level ON logs (level) TYPE set(2) GRANULARITY 4;
EXPLAIN WHATIF SELECT count() FROM logs WHERE level = 'error';
Baseline (PK + partition + existing indexes): marks: 612, 19.56 MiB
With idx_level (set, hypothetical):
status: applicable
marks: 200 (was 612)
est_bytes: 6.39 MiB
skip_ratio: 67.3%
Estimation: empirical, sampled 5/5 parts
โ Session-scoped, visible in system.hypothetical_indexes.
Tune indexes data-driven.
Developer: Yarik Briukhovetskyi.
Generate text embeddings from inside ClickHouse, via an LLM API:
SELECT aiEmbed('qwen3-8b', review_text) AS embedding
FROM reviews
LIMIT 10;
-- Array(Float32) per row, ready for cosineDistance / vector search
โ Build a semantic-search or RAG pipeline without leaving SQL.
โ Pairs with the new quantization functions for compact vector indexes.
โ Experimental โ configure your embedding provider and model.
Developer: George Larionov.
A scalar codec that compresses embedding components to 8bit and below:
SELECT quantizeBFloat16ToInt8(1.5::BFloat16);
-- 107
SELECT dequantizeInt8ToBFloat16(quantizeBFloat16ToInt8(1.5::BFloat16));
-- 1.5 (near-lossless round-trip)
โ 256-level Gaussian LloydโMax quantizer; one byte per component.
โ Int4 / Int2 / binary codes fall out by bit-truncation โ trade size for recall.
โ Shrinks vector indexes 4x (or more) for cheaper similarity search.
Developer: Alexey Milovidov.
โ ๐ฆ๐บ Sydney: Agentic AI Unplugged, Jun 24
โ ๐บ๐ธ Seattle Iceberg Meetup, Jun 25
โ ๐ฒ๐พ Kuala Lumpur Meetup, Jun 26
โ ๐ฐ๐ท Seoul: ClickHouse + Confluent, Jun 30
โ ๐บ๐ธ San Francisco: AI Demo Night, Jul 1
โ ๐ฎ๐ณ Mumbai: Lakes to Queries, Jul 4
โ ๐บ๐ธ New York: AI Builders Night, Jul 8
โ ๐ฉ๐ช Berlin: WeAreDevelopers, Jul 8
โ ๐จ๐ฆ Montreal: OSS Happy Hour, Jul 9
โ ๐ฎ๐ณ Bangalore: Fast Data at Scale, Jul 11
โ ๐ฆ๐บ Melbourne Meetup, Jul 16
โ ๐ฏ๐ต Tokyo: Google Cloud Next, Jul 30
โ Ten years of open source
โ How ClickHouse became fast at joins
โ Integrating the Rust Delta Kernel into ClickHouse
โ Introducing multi-stage distributed query execution
โ CostBench: an open benchmark for data warehouse cost-performance
โ TPC-H for less than a cent: ClickHouse Cloud
โ vs. Snowflake, Databricks, BigQuery, and Redshift
โ The end-to-end cost-performance: Snowflake vs. ClickHouse Cloud
โ The future of observability: thousands of agents, not one proprietary AI