TimescaleDB v2.28 now on Tiger Cloud
TimescaleDB 2.28.2 is the first release of the 2.28 line on Tiger Cloud, and it rolls up three upstream releases into a single upgrade: the 2.28.0 feature release, the 2.28.1 correctness patch, and the 2.28.2 upgrade-path patch. 2.28.0 closes several long-requested developer experience asks on continuous aggregates and continues maturing the columnstore, while 2.28.1 and 2.28.2 harden correctness on compressed data and stabilize the upgrade path. TimescaleDB 2.28.0 was released on June 16, 2026, 2.28.1 on June 23, and 2.28.2 on June 30; all three are delivered to Tiger Cloud as 2.28.2 starting July 2, 2026.
Highlighted features in TimescaleDB v2.28
Section titled “Highlighted features in TimescaleDB v2.28”Developer experience improvements on continuous aggregates
Continuous aggregates now support in-place schema evolution, direct statistics maintenance, and incremental manual refresh, so you can build and maintain materialized data with the same familiar SQL you already use for ordinary tables.
-
ALTER MATERIALIZED VIEW ... ADD COLUMN: Continuous aggregates now support adding new aggregate columns in place, when the new column is aGENERATED ALWAYS AS (<aggregate>) STOREDexpression. Previously, evolving a CAgg's schema meant creating a versioned copy, waiting for it to materialize, and switching application reads over. Now the column is added directly — new refreshes populate it going forward, and you backfill historical rows.ALTER MATERIALIZED VIEW conditions_summary_hourlyADD COLUMN max_temp double precisionGENERATED ALWAYS AS (max(temperature)) STORED; -
ANALYZEandVACUUMwork directly on continuous aggregates: Both maintenance commands are now transparently redirected to the underlying materialization hypertable and all associated chunks, including columnstore chunks, so you no longer invoke them on internal table names. -
Incremental manual refresh:
refresh_continuous_aggregate()now supports batched, incremental refresh through a new JSONB options argument, bringing manual refresh in line with policy-driven refresh and reducing memory pressure and lock duration on large refreshes.CALL refresh_continuous_aggregate('metrics_hourly',now() - INTERVAL '30 days', now(),options => '{"buckets_per_batch": 24}'::jsonb); -
timescaledb.skip_cagg_invalidationGUC for bulk loads: A new session- or transaction-scoped GUC suppresses continuous aggregate invalidation tracking during DML and DDL on hypertables, for trusted bulk-load workflows where the caller refreshes affected CAggs afterward. This eliminates per-row invalidation overhead during large ingests. -
Lighter locking during invalidation processing: Refresh operations now use a targeted row-level lock on the
continuous_aggcatalog row instead of a broaderShareUpdateExclusiveLock, so unrelated work on the same CAgg can proceed concurrently with refresh.
Faster recency queries on the columnstore
Sparse indexes for compressed chunks now record first and last values alongside the existing min/max metadata for each orderby column, and ColumnarIndexScan (default-on since 2.26) picks them up. "Latest reading per series" queries using two-argument first(value, orderby) or last(value, orderby) can now read straight from sparse-index metadata without touching batch payloads. Existing compressed chunks must be recompressed or retrofitted to pick up the new metadata.
SELECT device_id, last(value, time)FROM metricsGROUP BY device_id;Broader vectorized execution
- Vectorized
CASEin the columnar executor:CASE ... WHEN ... THEN ... ELSE ... ENDexpressions inside vectorized aggregation over compressed hypertables no longer force a row-by-row fallback — a meaningful speedup for conditional aggregation. - Higher parallelism for
SELECTon compressed hypertables: Parallelism is now sized more closely to the uncompressed data size, speeding up large analytical scans that were previously under-parallelized.
Sparse-index maintenance
- Retrofit sparse indexes on existing chunks: A new internal utility
_timescaledb_functions.rebuild_sparse_index()updates sparse-index metadata on already-compressed chunks without a full decompress and recompress cycle. It diffs current metadata against the active compression settings and applies only what changed — useful after changingsegmentby,orderby, or index settings on a hypertable that already has compressed data. - Automatic cleanup when dropping columns: When a column is dropped from a hypertable on the columnstore, TimescaleDB now removes all associated sparse-index metadata columns from compressed chunks. Previously those columns were left behind.
In-memory observability for compressed chunks
A new in-memory observability layer captures per-chunk statistics during compression events, queries, and DML on compressed data. Inspect compressed-batch counts, row averages, and activity counters through the stat_chunk_activity view or the chunk_statistics() functions. A new GUC timescaledb.stats_max_chunks controls how many chunks are tracked in memory.
SELECT hypertable_name, chunk_name, compressed_batch_rows_avgFROM timescaledb_information.stat_chunk_activity;Gap-fill planning improvements
- Better row-count estimates for
time_bucket_gapfill(): The planner now accounts for rows synthesized by gap-filling rather than relying solely on the subplan's row count. Whenstart,finish, andperiodare known at plan time, estimates are materially closer to actual emitted rows, leading to better join and aggregation plans downstream. - Subquery execution-parameter arguments to
time_bucket_gapfill(): Gap-fill arguments can now resolve from subquery execution parameters, removing a previous limitation for some dynamic-argument query shapes.
Correctness and upgrade hardening
Section titled “Correctness and upgrade hardening”The 2.28.1 and 2.28.2 patches folded into this rollout focus on compressed-data correctness and a clean upgrade path.
- Compressed-data correctness (2.28.1): Fixes a data-loss bug where a
DELETEwith a subquery resolving to constant false could remove every row; fixes a server crash during DML when the planner chose a Bitmap Heap Scan; enforcesCHECK,NOT NULL, and viewWITH CHECK OPTIONconstraints on direct-compress inserts; correctsALTER TABLE ... RENAME COLUMNon compressed chunks; and resolves severalfirst/lastaggregate edge cases. - Upgrade path (2.28.1 and 2.28.2): The 2.28.0 upgrade blocker that prevented older instances (created before 2.15.0 without a prior PostgreSQL version upgrade) from upgrading is resolved. 2.28.2 stabilizes the migration further by correctly migrating internal catalog tables, automatically dropping incompatible bloom filters during upgrade instead of halting for manual intervention, and fixing sparse-index column ordering for
first/last.
Deprecations and backward-incompatible changes
Section titled “Deprecations and backward-incompatible changes”- PostgreSQL 15 support removed: TimescaleDB 2.28.0 removes support for PostgreSQL 15, ending the deprecation window announced in 2.23. This is a TimescaleDB requirement, not a Tiger Cloud platform deprecation: PostgreSQL 15 remains available on Tiger Cloud, but a PostgreSQL 15 service must upgrade to PostgreSQL 16 or higher before it can adopt TimescaleDB 2.28.2.
_timescaledb_catalog.chunk_constraintremoved: The internalchunk_constraintcatalog table has been removed. Customers who query this catalog table directly will need to migrate. There are no SQL-surface behavior changes for standard TimescaleDB users.
For complete details, refer to the TimescaleDB 2.28.0 release notes, 2.28.1 release notes, and 2.28.2 release notes.





























































