2.25.0 (2026-01-29)
This release contains performance improvements and bug fixes since the 2.24.0 release. We recommend that you upgrade at the next available opportunity.
Highlighted features in TimescaleDB v2.25.0
This release features multiple improvements for continuous aggregates on the columnstore:
- Faster refreshes: You can now utilize direct compress during materialized view refreshes, resulting in higher throughput and reduced I/O usage.
- Efficiency: The enablement of delete optimizations significantly lowers system resource requirements.
- Smaller transactions: Adjusted defaults for
buckets_per_batchto 10 reduces transaction sizes, requiring less WAL holding time. - Faster queries: Smarter defaults for
segmentbyandorderbyyield improved query performance and better compression ratio on the columnstore.
Sunsetting announcements
- This release removes the WAL-based invalidation of continuous aggregates. This feature was introduced in 2.22.0 as tech preview to use logical decoding for building the invalidation logs. The feature was designed for high ingest workloads, reducing the write amplification. With the upcoming stream of improvements to continuous aggregates, this feature was deprioritized and removed.
- The old continuous aggregate format, deprecated in version 2.10.0, has been fully removed from TimescaleDB in this release. Users still on the old format should read the migration documentation to migrate to the new format. Users of Tiger Cloud have already been automatically migrated.
Features
- https://github.com/timescale/timescaledb/pull/8777 Enable direct compress on continuous aggregate refresh using new GUC
timescaledb.enable_direct_compress_on_cagg_refresh - https://github.com/timescale/timescaledb/pull/9031 Change default
buckets_per_batchon continuous aggregate refresh policy to10 - https://github.com/timescale/timescaledb/pull/9032 Add in-memory recompression for unordered chunks
- https://github.com/timescale/timescaledb/pull/9017 Move
bgw_jobtable into schema_timescaledb_catalog - https://github.com/timescale/timescaledb/pull/9033 Add
rebuild_columnstoreprocedure - https://github.com/timescale/timescaledb/pull/9038 Change default configuration for compressed continuous aggregates
- https://github.com/timescale/timescaledb/pull/9042 Enable batch sorted merge on unordered compressed chunks
- https://github.com/timescale/timescaledb/pull/9046 Allow non timescaledb namespace
SEToption for continuous aggregates - https://github.com/timescale/timescaledb/pull/9059 Allow configuring
work_memfor background worker jobs - https://github.com/timescale/timescaledb/pull/9074 Add function to estimate uncompressed size of compressed chunk
- https://github.com/timescale/timescaledb/pull/9085 Don't register timescaledb-tune specific GUCs
- https://github.com/timescale/timescaledb/pull/9088 Add
ColumnarIndexScancustom node - https://github.com/timescale/timescaledb/pull/9090 Support direct batch delete on hypertables with continuous aggregates
- https://github.com/timescale/timescaledb/pull/9094 Enable the columnar pipeline for grouping without aggregation to speed up the queries of the form
select column from table group by column. - https://github.com/timescale/timescaledb/pull/9103 Support
FIRSTandLASTinColumnarIndexScan - https://github.com/timescale/timescaledb/pull/9108 Support multiple aggregates in
ColumnarIndexScan - https://github.com/timescale/timescaledb/pull/9111 Allow recompression with orderby/index changes
- https://github.com/timescale/timescaledb/pull/9113 Use
enable_columnarscanto control columnarscan - https://github.com/timescale/timescaledb/pull/9127 Remove primary dimension constraints from fully covered chunks
- https://github.com/timescale/timescaledb/pull/8710 Add SQL function to fetch continuous aggregate grouping columns
- https://github.com/timescale/timescaledb/pull/9133 Allow pushing down sort into columnar unordered chunks when it is possible
- https://github.com/timescale/timescaledb/pull/8229 Removed
time_bucket_ngfunction - https://github.com/timescale/timescaledb/pull/8859 Remove support for partial continuous aggregate format
- https://github.com/timescale/timescaledb/pull/9022 Remove WAL based invalidation
- https://github.com/timescale/timescaledb/pull/9016 Remove
_timescaledb_debugschema - https://github.com/timescale/timescaledb/pull/9030 Add new chunks to hypertable publication
Bug fixes
- https://github.com/timescale/timescaledb/issues/8706 Fix planning performance regression on Postgres 16 and later on some join queries.
- https://github.com/timescale/timescaledb/pull/8986 Add pathkey replacement for
ColumnarScanPath - https://github.com/timescale/timescaledb/pull/8989 Ensure no XID is assigned during chunk query
- https://github.com/timescale/timescaledb/pull/8990 Fix
EquivalenceClassindex update forRelOptInfo - https://github.com/timescale/timescaledb/pull/9007 Add validation for compression index key limits
- https://github.com/timescale/timescaledb/pull/9024 Recompress some chunks on
VACUUM FULL - https://github.com/timescale/timescaledb/pull/9045 Fix missing UUID check in compression policy
- https://github.com/timescale/timescaledb/pull/9056 Fix split chunk
relfrozenxid - https://github.com/timescale/timescaledb/pull/9058 Fix missing chunk column stats bug
- https://github.com/timescale/timescaledb/pull/9061 Fix update race with background worker jobs
- https://github.com/timescale/timescaledb/pull/9069 Fix applying multikey sort for columnstore when one numeric key is pinned to a Const of different type
- https://github.com/timescale/timescaledb/pull/9102 Support retention policies on UUIDv7-partitioned hypertables
- https://github.com/timescale/timescaledb/pull/9120 Fix for pre Postgres 17, where a
DELETEfrom a partially compressed chunk may miss records ifBitmapHeapScanis being used - https://github.com/timescale/timescaledb/pull/9121 Allow any immutable constant expressions as default values for compressed columns
- https://github.com/timescale/timescaledb/pull/9121 Fix a potential "unexpected column type 'bool'" error for compressed bool columns with missing value
- https://github.com/timescale/timescaledb/pull/9144 Fix handling implicit constraints in
ALTER TABLE - https://github.com/timescale/timescaledb/pull/9155 Fix column generation during compressed chunk insert
- https://github.com/timescale/timescaledb/pull/9129 Fix
time_bucketwith timezone during DST - https://github.com/timescale/timescaledb/pull/9177 Add alias for
bgw_job - https://github.com/timescale/timescaledb/pull/9176 Handle
NULLvalues in continuous aggregate invalidation more gracefully - https://github.com/timescale/timescaledb/pull/9175 Do not remove dimension constraints for OSM chunks
GUCs
enable_columnarindexscan: Enable returning results directly from compression metadata without decompression. This feature is experimental and in development towards a GA release. Not for production environments. Default:falseenable_direct_compress_on_cagg_refresh: Enable experimental support for direct compression during Continuous Aggregate refresh. Default:falseenable_qual_filtering: Filter qualifiers on chunks when complete chunk would be included by filter. Default:true
Thanks
- @t-aistleitner for reporting the planning performance regression on PG16 and later on some join queries.
- @vahnrr for reporting a crash when adding columns and constraints to a hypertable at the same time
- @cracksalad and @eyadmba for reporting a bug with timezone handling in
time_bucket
2.24.0 (2025-12-03)
This release contains performance improvements and bug fixes since the 2.23.1 release. We recommend that you upgrade at the next available opportunity.
Highlighted features in TimescaleDB v2.24.0
- Direct Compress just got smarter and faster: it now works seamlessly with hypertables generating continuous aggregates. Invalidation ranges are computed directly in-memory based on the ingested batches and written efficiently at transaction commit. This change reduces the IO footprint drastically by removing the write amplification of the invalidation logs.
- Continuous aggregates now speak UUIDv7: hypertables partitioned by UUIDv7 are fully supported through an enhanced
time_bucketthat accepts UUIDv7 values and returns precise, timezone-aware timestamps — unlocking powerful time-series analytics on modern UUID-driven table schemas. - Lightning-fast recompression: the new
recompress := trueoption on thecompress_chunkAPI enables pure in-memory recompression, delivering a 4–5× speed boost over the previous disk-based process.
ARM support for bloom filters The sparse bloom filter indexes will stop working after upgrade to 2.24. If you are affected by this problem, the warning "bloom filter sparse indexes require action to re-enable" will appear in the Postgres log during upgrade.
In versions before 2.24, the hashing scheme of the bloom filter sparse indexes used to depend on the build options of the TimescaleDB executables. These options are set by the package publishers and might differ between different package sources or even versions. After upgrading to a version with different options, the queries that use the bloom filter lookups could erroneously stop returning the rows that should in fact match the query conditions. The 2.24 release fixes this by using distinct column names for each hashing scheme.
The bloom filter sparse indexes will be disabled on the compressed chunks created before upgrading to 2.24. To re-enable them, you have to decompress and then compress the affected chunks.
If you were running the official APT package on AMD64 architecture, the hashing scheme did not change, and it is safe to use the existing bloom filter sparse indexes. To enable this, set the GUC timescaledb.read_legacy_bloom1_v1 = on in the server configuration.
The chunks compressed after upgrade to 2.24 will use the new index format, and the bloom filter sparse indexes will continue working as usual for these chunks without any intervention.
For more details, refer to the pull request #8761.
Deprecations
- The next release of TimescaleDB will remove the deprecated partial continuous aggregates format. The new format was introduced in
2.7.0and provides significant improvements in terms of performance and storage efficiency. Please usecagg_migrate(<CONTINUOUS_AGGREGATE_NAME>)to migrate to the new format. Tiger Cloud users are migrated automatically. - In future releases the deprecated view
timescaledb_information.compression_settingswill be removed. Please usetimescaledb_information.hypertable_columnstore_settingsas a replacement. - The experimental view
timescaledb_experimental.policiesand the adjacent experimental functionsadd_policies,alter_policies,show_policies,remove_policies, andremove_all_policiesto manage continuous aggregates will be removed in an upcoming release. For replacements, please use the Jobs API.
Backward-Incompatible Changes
- #8761 Fix matching rows in queries using the bloom filter sparse indexes potentially not returned after extension upgrade. The version of the bloom filter sparse indexes is changed. The existing indexes will stop working and will require action to re-enable. See the section above for details.
Features
- #8465 Speed up the filters like
x = any(array[...])using bloom filter sparse indexes. - #8569 In-memory recompression
- #8754 Add concurrent mode for merging chunks
- #8786 Display chunks view range as timestamps for UUIDv7
- #8819 Refactor chunk compression logic
- #8840 Allow
ALTER COLUMN TYPEwhen compression is enabled but no compressed chunks exist - #8908 Add time bucketing support for UUIDv7
- #8909 Support direct compress on hypertables with continuous aggregates
- #8939 Support continuous aggregates on UUIDv7-partitioned hypertables
- #8959 Cap continuous aggregate invalidation interval range at chunk boundary
- #8975 Exclude date/time columns from default segmentby
- #8993 Add GUC for in-memory recompression
Bugfixes
- #8839 Improve
_timescaledb_functions.cagg_watermarkerror handling - #8853 Change log level of continuous aggregate refresh messages to
DEBUG1 - #8933 Potential crash or seemingly random errors when querying the compressed chunks created on releases before 2.15 and using the minmax sparse indexes.
- #8942 Fix lateral join handling for compressed chunks
- #8958 Fix
if_not_existsbehaviour when adding refresh policy - #8969 Gracefully handle missing job stat in background worker
- #8988 Don't ignore additional filters on same column when building scankeys
GUCs
direct_compress_copy_tuple_sort_limit: Number of tuples that can be sorted at once in aCOPYoperation.direct_compress_insert_tuple_sort_limit: Number of tuples that can be sorted at once in anINSERToperation.read_legacy_bloom1_v1: Enable reading the legacybloom1version 1 sparse indexes forSELECTqueries.enable_in_memory_recompression: Enable in-memory recompression functionality.
Thanks
- @bezpechno for implementing
ALTER COLUMN TYPEfor hypertable with columnstore when no compressed chunks exist
2.23.1 (2025-11-13)
This release contains performance improvements and bug fixes since the 2.23.0 release. We recommend that you upgrade at the next available opportunity.
Bugfixes
- #8873 Don't error on failure to update job stats
- #8875 Fix decoding of UUID v7 timestamp microseconds
- #8879 Fix blocker for multiple hierarchical continuous aggregate policies
- #8882 Fix crash in policy creation
Thanks
- @alexanderlaw for reporting a crash when creating a policy
- @leppaott for reporting an issue with hierarchical continuous aggregates
2.23.0 (2025-10-29)
This release contains performance improvements and bug fixes since the 2.22.1 release. We recommend that you upgrade at the next available opportunity.
Highlighted features in TimescaleDB v2.23.0
- This release introduces full PostgreSQL 18 support for all existing features. TimescaleDB v2.23 is available for PostgreSQL 15, 16, 17, and 18.
- UUIDv7 compression is now enabled by default on the columnstore. This feature was shipped in v2.22.0. It saves you at least 30% of storage and delivers ~2× faster query performance with UUIDv7 columns in the filter conditions.
- Added the ability to set hypertables to unlogged, addressing an open community request #836. This allows the tradeoff between durability and performance, with the latter being favourable for larger imports.
- By allowing set-returning functions in continuous aggregates, this releases addresses a long standing blocker, raised by the community #1717.
PostgreSQL 15 deprecation announcement
We will continue supporting PostgreSQL 15 until June 2026. Closer to that time, we will announce the specific TimescaleDB version in which PostgreSQL 15 support will not be included going forward.
Features
- #8373 More precise estimates of row numbers for columnar storage based on Postgres statistics.
- #8581 Allow mixing Postgres and TimescaleDB options in
ALTER TABLE SET. - #8582 Make
partition_columninCREATE TABLE WITHoptional. - #8588 Automatically create a columnstore policy when a hypertable with columnstore enabled is created via
CREATE TABLE WITHstatement. - #8606 Add job history config parameters for maximum successes and failures to keep for each job.
- #8632 Remove
ChunkDispatchcustom node. - #8637 Add
INSERTsupport for direct compress. - #8661 Allow
ALTER TABLE ONLYto changereloptionsto apply setting changes only to future chunks. - #8703 Allow set-returning functions in continuous aggregates.
- #8734 Support direct compress when inserting into a chunk.
- #8741 Add support for unlogged hypertables.
- #8769 Remove continuous aggregate invalidation trigger.
- #8798 Enable UUIDv7 compression by default.
- #8804 Remove
insert_blockertrigger.
Bugfixes
- #8561 Show warning when direct compress is skipped due to triggers or unique constraints.
- #8567 Do not require a job to have executed to show status.
- #8654 Fix
approximate_row_countfor compressed chunks. - #8704 Fix direct
DELETEon compressed chunk. - #8728 Don't block dropping hypertables with other objects.
- #8735 Fix
ColumnarScanforUNIONqueries. - #8739 Fix cached utility statements.
- #8742 Potential internal program error when grouping by
boolcolumns of a compressed hypertable. - #8743 Modify schedule interval for job history pruning.
- #8746 Support show/drop chunks with UUIDv7 partitioning.
- #8753 Allow sorts over decompressed index scans for
ChunkAppend. - #8758 Improve error message on catalog version mismatch.
- #8774 Add GUC for WAL based invalidation of continuous aggregates.
- #8782 Stops sparse index from allowing multiple options.
- #8799 Set
next_startforWITHclause compression policy. - #8807 Only warn but not fail the compression if bloom filter indexes are configured but disabled with a GUC.
GUCs
cagg_processing_wal_batch_size: Batch size when processing WAL entries.enable_cagg_wal_based_invalidation: Enable experimental invalidations for continuous aggregates using WAL.enable_direct_compress_insert: Enable direct compression duringINSERT.enable_direct_compress_insert_client_sorted: Enable direct compressINSERTwith presorted data.enable_direct_compress_insert_sort_batches: Enable batch sorting during direct compressINSERT.
Thanks
- @brandonpurcell-dev For highlighting issues with
show_chunks()and UUIDv7 partitioning - @moodgorning for reporting an issue with the
timescaledb_information.job_statsview - @ruideyllot for reporting set-returning functions not working in continuous aggregates
- @t-aistleitner for reporting an issue with utility statements in plpgsql functions
2.22.1 (2025-09-30)
This release contains performance improvements and bug fixes since the 2.22.0 release. We recommend that you upgrade at the next available opportunity.
This release blocks the ability to leverage concurrent refresh policies in hierarchical continous aggregates, as potential deadlocks can occur. If you have concurrent refresh policies in hierarchical continous aggregates, please disable the jobs, as following:
SELECT alter_job("<job_id_of_concurrent_policy>", scheduled => false);
Bugfixes
- #7766 Load OSM extension in retention background worker to drop tiered chunks
- #8550 Error in gapfill with expressions over aggregates and groupby columns and out-of-order columns
- #8593 Error on change of invalidation method for continuous aggregate
- #8599 Fix attnum mismatch bug in chunk constraint checks
- #8607 Fix interrupted continous aggregate refresh materialization phase leaving behind pending materialization ranges
- #8638
ALTER TABLE RESETfororderbysettings - #8644 Fix migration script for sparse index configuration
- #8657 Fix
CREATE TABLE WITHwhen using UUIDv7 partitioning - #8659 Don't propagate
ALTER TABLEcommands to foreign data wrapper chunks - #8693 Compressed index not chosen for
varchartypedsegmentbycolumns - #8707 Block concurrent refresh policies for hierarchical continous aggregate due to potential deadlocks
Thanks
- @MKrkkl for reporting a bug in Gapfill queries with expressions over aggregates and groupby columns
- @brandonpurcell-dev for creating a test case that showed a bug in
CREATE TABLE WITHwhen using UUIDv7 partitioning - @snyrkill for reporting a bug when interrupting a continous aggregate refresh
2.21.4 (2025-09-25)
This release contains performance improvements and bug fixes since the 2.21.3 release. We recommend that you upgrade at the next available opportunity.
Bugfixes
https://github.com/timescale/timescaledb/pull/8667 Fix wrong selectivity estimates uncovered by the recent Postgres minor releases 15.14, 16.10, 17.6.
2.22.0 (2025-09-02)
This release contains performance improvements and bug fixes since the 2.21.3 release. We recommend that you upgrade at the next available opportunity.
Highlighted features in TimescaleDB v2.22.0
- Sparse indexes on compressed hypertables can now be explicitly configured via
ALTER TABLErather than relying only on internal heuristics. Users can define indexes on multiple columns to improve query performance for their specific workloads. - [Tech Preview] Continuous aggregates now support the
timescaledb.invalidate_usingoption, enabling invalidations to be collected either via triggers on the hypertable or directly from WAL using logical decoding. Aggregates inherit the hypertable’s method if none is specified. - UUIDv7 compression and vectorization are now supported. The compression algorithm leverages the timestamp portion for delta-delta compression while storing the random portion separately. The vectorized equality/inequality filters with bulk decompression deliver ~2× faster query performance. The feature is disabled by default (
timescaledb.enable_uuid_compression) to simplify the downgrading experience, and will be enabled out of the box in the next minor release. - Hypertables can now be partitioned by UUIDv7 columns, leveraging their embedded timestamps for time-based chunking. We’ve also added utility functions to simplify working with UUIDv7, such as generating values or extracting timestamps - e.g.,
uuid_timestamp()returns a PostgreSQL timestamp from a UUIDv7. - SkipScan now supports multi-column indexes in not-null mode, improving performance for distinct and ordered queries across multiple keys.
Removal of the hypercore table access method We made the decision to deprecate the hypercore table access method (TAM) with the 2.21.0 release. Hypercore TAM was an experiment and it did not show the performance improvements we hoped for. It is removed with this release. Upgrades to 2.22.0 and higher are blocked if TAM is still in use. Since TAM’s inception in 2.18.0, we learned that btrees were not the right architecture. Recent advancements in the columnstore, such as more performant backfilling, SkipScan, adding check constraints, and faster point queries, put the columnstore close to or on par with TAM without needing to store an additional index. We apologize for the inconvenience this action potentially causes and are here to assist you during the migration process.
Migration path
do $$
declare
relid regclass;
begin
for relid in
select cl.oid from pg_class cl
join pg_am am on (am.oid = cl.relam)
where am.amname = 'hypercore'
loop
raise notice 'converting % to heap', relid::regclass;
execute format('alter table %s set access method heap', relid);
end loop;
end
$$;
Features
- #8247 Add configurable alter settings for sparse indexes
- #8306 Add option for invalidation collection using WAL for continuous aggregates
- #8340 Improve selectivity estimates for sparse minmax indexes, so that an index scan on a table in the columnstore is chosen more often when it's beneficial.
- #8360 Continuous aggregate multi-hypertable invalidation processing
- #8364 Remove hypercore table access method
- #8371 Show available timescaledb
ALTERoptions when encountering unsupported options - #8376 Change
DecompressChunkcustom node name toColumnarScan - #8385 UUID v7 functions for testing pre PG18
- #8393 Add specialized compression for UUIDs. Best suited for UUID v7, but still works with other UUID versions. This is experimental at the moment and backward compatibility is not guaranteed.
- #8398 Set default compression settings at compress time
- #8401 Support
ALTER TABLE RESETfor compression settings - #8414 Vectorised filtering of UUID Eq and Ne filters, plus bulk decompression of UUIDs
- #8424 Block downgrade when orderby setting is
NULL - #8454 Remove internal unused index helper functions
- #8494 Improve job stat history retention policy
- #8496 Fix dropping chunks with foreign keys
- #8505 Add support for partitioning on UUIDv7
- #8513 Support multikey SkipScan when all keys are guaranteed to be non-null
- #8514 Concurrent continuous aggregates improvements
- #8528 Add the
_timescaledb_functions.chunk_status_texthelper function - #8529 Optimize direct compress status handling
Bugfixes
- #8422 Don't require
columnstore=falsewhen using the TimescaleDB Apache 2 Edition - #8493 Change log level of
not nullconstraint message - #8500 Fix uniqueness check with generated columns and hypercore
- #8545 Fix error in LOCF/Interpolate with out-of-order and repeated columns
- #8558 Error out on bad args when processing invalidation
- #8559 Fix
timestamp out of rangeusingend_offset=NULLon CAgg refresh policy
GUCs
enable_multikey_skipscan: Enable SkipScan for multiple distinct keys, default: onenable_uuid_compression: Enable UUID compression functionality, default: offcagg_processing_wal_batch_size: Batch size when processing WAL entries, default: 10000cagg_processing_low_work_mem: Low working memory limit for continuous aggregate invalidation processing, default: 38.4MBcagg_processing_high_work_mem: High working memory limit for continuous aggregate invalidation processing, default: 51.2MB
Thanks
- @CodeTherapist for reporting an issue where foreign key checks did not work after several insert statements
- @moodgorning for reporting a bug in queries with LOCF/Interpolate using out-of-order columns
- @nofalx for reporting an error when using
end_offset=NULLon CAgg refresh policy - @pierreforstmann for fixing a bug that happened when dropping chunks with foreign keys
- @Zaczero for reporting a bug with CREATE TABLE WITH when using the TimescaleDB Apache 2 Edition
2.21.3 (2025-08-12)
This release contains performance improvements and bug fixes since the 2.21.2 release. We recommend that you upgrade at the next available opportunity.
- https://github.com/timescale/timescaledb/pull/8471 Fix MERGE behaviour with updated values
2.21.2 (2025-08-05)
This release contains performance improvements and bug fixes since the 2.21.1 release. We recommend that you upgrade at the next available opportunity.
Bugfixes
2.21.1 (2025-07-22)
This release contains a bug fix since the 2.21.0 release. We recommend that you upgrade at the next available opportunity.
Bugfixes
- #8336 Fix generic plans for foreign key checks and prepared statements
Thanks
- @CodeTherapist for reporting the issue with foreign key checks not working after several
INSERTstatements