ClickHouse 26.8 LTS: pipe syntax, background queries and a faster GROUP BY
The 26.8 long-term-support release adds pipe SQL, queries that survive a dropped connection, IEJoin, new text tokenizers and an adaptive GROUP BY, and changes max_insert_threads to auto.
Source: clickhouse.com
Why it matters: 26.8 is a long-term-support release, so it is the version many teams will standardize on for the next year. It is also a release where several defaults change what your existing workload does: inserts parallelize by default, a new adaptive GROUP BY replaces the old heuristics, and views over Distributed tables are pushed down to the shards. The new SQL surface (pipe operators, background queries, IEJoin) is worth a look, but the upgrade checklist is what decides whether the move is quiet.
Sources: the official 26.8 changelog (released 2026-08-27) and the release post, which counts 98 new features, 128 performance optimizations and 556 bug fixes. PR numbers link to ClickHouse/ClickHouse. These features are newer than the 26.4 build used for this site’s tested examples, so the snippets are quoted or adapted from the changelog and were not run here.
New SQL and server features
- Pipe operators (#111151), in the style of GoogleSQL:
FROM t |> WHERE x > 1 |> AGGREGATE count() AS c GROUP BY y |> ORDER BY c DESC |> LIMIT 10. Each operator wraps the previous query as a subquery, so the resulting AST is the same as the nested-subquery form. It reads top to bottom, which suits exploration, and since it produces the same plan there is no performance reason to avoid it. run_query_in_background(#112816). The server accepts the query, returns an empty result immediately and runs it to completion whatever happens to the connection; the result is discarded and you track the query byquery_idinsystem.processesandsystem.query_log. It is meant for longINSERT ... SELECT,CREATE TABLE ... AS SELECTandCREATE MATERIALIZED VIEW ... POPULATEstatements that should not die with a laptop’s Wi-Fi.CREATE MATERIALIZED VIEW ... POPULATEis locally atomic (#108715): the view subscribes to new inserts and the existing data is snapshotted together under a brief exclusive lock on the source, so rows inserted concurrently through the same server are no longer missed or duplicated (materialized_views_populate_atomically, on by default). The guarantee is local to one server.IEJoin(#109920), enabled by addingie_jointojoin_algorithm, handlesONclauses with two inequality comparisons, such as interval-overlap joins. Previously these ran as aCROSS JOINwith a filter, which is slow on large tables.GROUPSframes for window functions (SQL:2011), whereN PRECEDINGcounts whole peer groups rather than rows (#108653).- HTTP interface.
CREATE HANDLER,ALTER HANDLERandDROP HANDLERdefine custom HTTP handlers from SQL (#106231). Tables and databases can be addressed by URL path, as in/database/table.format.gz?filter=a>0, and theX-ClickHouse-Formatheader now overrides theFORMATclause (#105249). Framing formats such asEventStream(server-sent events) multiplex data, progress, totals and exceptions in one response stream (#110127). system.user_query_logshows every user their own query log records without access to the full table (#110156).VALID FOR <interval>is a shorthand forVALID UNTILonCREATE USERandALTER USER.- Data lakes and integrations. A
bigquerytable function and engine (#110166), the S3 Tables catalog with workingINSERT(#113505), Snowflake Horizon for Iceberg reads and writes (#114547), thePuffinfile format (#103936), and aURLdatabase engine pluss3_basefor relative S3 URLs (#111512). - Text index tokenizers for Japanese (MeCab), Chinese (dictionary and HMM), locale-aware ICU segmentation and a regexp splitter that preserves tokens such as
C++(#111420, #89945, #109940, #110002). - Keeper on disk with a custom LSM tree (
use_lsmt_storage,storage_memory_only = false), with performance the changelog describes as similar to the previous in-memory storage (#113903). Also new: theginiaggregate function (#112280),mergedJSONPatchfor latest-state aggregation overJSON(#108349), andmergeTreeCodecBlockCountsto see how many blocks use each codec per part and column (#109623).
Performance
- Adaptive
GROUP BY(enable_adaptive_aggregator, on by default, #111459): each thread aggregates into its own hash table until it holdsadaptive_aggregator_freeze_thresholdkeys, then freezes it. Frequent keys keep updating small cache-resident tables without coordination; rare keys are routed by hash into per-bucket backlogs and aggregated once in the parallel merge. Expect the biggest differences on skewed, high-cardinality grouping, and watch memory on the first runs. GROUP BY ... ORDER BY ... LIMITkeeps a bounded heap during aggregation to drop groups that cannot appear in the result (enable_group_by_top_k_optimization, #96630). Smaller hash-table cells for single-Stringkeys (#110573) and a parallel final merge of single-level tables (#110395) are also on by default.- Parquet. Row-group skipping through dictionary pages for equality and
INconditions on fully dictionary-encoded columns (#106952), lazy materialization forORDER BY ... LIMIT nreads from object storage and Iceberg (#110970), and GeoParquet bounding-box pruning at row-group and page level (#104435). - Order-by-key reads.
read_in_order_use_virtual_rowis on by default: forORDER BY primary_key LIMIT nover a table with many parts, only parts that can contribute are read, which cuts peak memory (#106215). - Joins. A
parallel_full_sorting_mergealgorithm shards a full sorting merge join by key hash (#109005), and a join whoseONis always false no longer reads the non-contributing side. - Text and protocol.
text_index_posting_list_apply_modedefaults tolazy(#113521); the native protocol sendsStringcolumns as an offsets stream plus concatenated data (#110320);clickhouse-clientno longer pings the server before every query (#111990); formattingDecimalvalues as text is up to 190 times faster for a high-scaleDecimal256(#112457).
Experimental
The experimental Cascades cost-based optimizer for distributed plans (enable_cascades_optimizer with make_distributed_plan, #86353), adaptive codec selection per block (enable_adaptive_codec_selection, #111834), a wasm64 build of the clickhouse binary that runs clickhouse local under Node.js or in a browser (#113404), and a large PromQL and TimeSeries push. Packed skip-index storage (packed_skip_index_max_bytes = '1M') was promoted to beta and enabled by default (#111816).
Plan before you upgrade
max_insert_threadsis nowauto(#109000):INSERT SELECTparallelizes across the cores available to the server, and plainINSERTcan fan out when the write path allows. That can change the number of parts created and the order of inserted rows. Set it back to1, or usecompatibilitybelow26.8, if a pipeline depends on part count or order.- Views over a single
Distributedtable push the whole outer query to the shards (#101791).FINALandSAMPLEwritten on the view reference now reach the shard-local table instead of being ignored, so results can change. Disable withoptimize_trivial_view_pushdown_to_distributed = 0. - Lightweight
UPDATEpatch parts use a new v2 format (#103182). During a rolling upgrade keeppatch_parts_version = 'v1'or usecompatibilityuntil every replica runs 26.8. Date32range grows to 0000-9999 (#111534), matchingDateTime64;toDate32(N)for largeNis now read as a day number instead of being clamped.arrayIntersectandarraySymmetricDifferencestop treating repeated values in one argument as appearing in several (#113021).- Security tightening. The
PostgreSQLdatabase engines respectremote_url_allow_hosts; MySQL source TLS files can no longer be given as paths from SQL (use the*_pemsettings);SYSTEM ... CACHE ON CLUSTERcommands check their own privileges; NATS credentials move tonats_credentials. Test any named collection or dictionary that carries a file path. - Removals. The
librarydictionary source is gone (#111980), and the Apache Arrow library-based reader and writer are removed, so the native implementation that has been the default since 26.7 is the only one.include_fromno longer defaults to/etc/metrika.xml, and asynchronous per-core and per-device metrics became singleMapmetrics, which breaks dashboards that readOSUserTimeCPU0and friends.
For an LTS move, the cheapest safety net is the compatibility setting: set it to the version you run today, upgrade, then lower it one setting at a time with EXPLAIN ANALYZE (from 26.7) on your top queries to attribute each change.
Discussion
Comments live in GitHub Discussions. Sign in with GitHub to join in.