TigerData logo
TigerData logo
  • Product

    Product

    Tiger Cloud

    Robust elastic cloud platform for startups and enterprises

    TimescaleDB Enterprise

    Self-managed TimescaleDB for on-prem, edge and private cloud

    Open source

    TimescaleDB

    Time-series, real-time analytics and events on Postgres

    Search

    Vector and keyword search on Postgres

  • Industry

    Data Centers

    Energy & Utilities

    Oil & Gas Operations

    Smart Manufacturing

    Crypto

  • Docs
  • Pricing
  • Developer Hub

    Changelog

    Benchmarks

    Blog

    Community

    Customer Stories

    Events

    Support

    Integrations

    Launch Hub

  • Company

    About

    TigerData logo

    Timescale

    Partners

    Security

    Careers

Contact usStart a free trial
Home
What Is DCIM Software, and What Database Does It Use?Data Center Power Monitoring: The Database Layer Behind PUE, PDU, and Sustainability MetricsPrometheus Long-Term Storage: Thanos, Mimir, VictoriaMetrics, and PostgreSQL Compared
Time Series Forecasting with PostgreSQL: Methods, SQL Examples, and When to Use PythonThe Best Time-Series Databases Compared (2026)Time Series Anomaly Detection: Methods, SQL, and Real-Time ImplementationAWS Timestream Alternatives: Your Migration Options After LiveAnalyticsWhat Is Temporal Data?Time-Series Database: What It Is, How It Works, and When You Need OneIs Your Data Time Series? Data Types Supported by PostgreSQL and TimescaleUnderstanding Database Workloads: Variable, Bursty, and Uniform PatternsTime-Series Analysis and Forecasting With Python What Are Open-Source Time-Series Databases—Understanding Your OptionsStationary Time-Series AnalysisAlternatives to TimescaleWhy Consider Using PostgreSQL for Time-Series Data?Time-Series Analysis in RWhat Is a Time Series and How Is It Used?How to Work With Time Series in Python?Tools for Working With Time-Series Analysis in PythonGuide to Time-Series Analysis in PythonUnderstanding Autoregressive Time-Series ModelingCreating a Fast Time-Series Graph With Postgres Materialized Views
PostgreSQL vs. Cassandra: The Decision Framework for Time-Series and Write-Heavy WorkloadsUnderstanding PostgreSQLOptimizing Your Database: A Deep Dive into PostgreSQL Data TypesUnderstanding FROM in PostgreSQL (With Examples)How to Address ‘Error: Could Not Resize Shared Memory Segment’ Understanding FILTER in PostgreSQL (With Examples)How to Install PostgreSQL on MacOSUnderstanding GROUP BY in PostgreSQL (With Examples)Understanding LIMIT in PostgreSQL (With Examples)Understanding PostgreSQL FunctionsUnderstanding ORDER BY in PostgreSQL (With Examples)PostgreSQL Mathematical Functions: Enhancing Coding EfficiencyUnderstanding PostgreSQL WITHIN GROUPUnderstanding WINDOW in PostgreSQL (With Examples)Using PostgreSQL String Functions for Improved Data AnalysisUnderstanding DISTINCT in PostgreSQL (With Examples)PostgreSQL Joins : A SummaryUnderstanding PostgreSQL Date and Time FunctionsWhat Is a PostgreSQL Cross Join?Understanding ACID Compliance Understanding PostgreSQL Conditional FunctionsStructured vs. Semi-Structured vs. Unstructured Data in PostgreSQLUnderstanding percentile_cont() and percentile_disc() in PostgreSQL5 Common Connection Errors in PostgreSQL and How to Solve ThemData Processing With PostgreSQL Window FunctionsPostgreSQL Join Type TheoryA Guide to PostgreSQL ViewsData Partitioning: What It Is and Why It MattersUnderstanding PostgreSQL Array FunctionsUnderstanding PostgreSQL's COALESCE FunctionUnderstanding the rank() and dense_rank() Functions in PostgreSQLWhat Is a PostgreSQL Left Join? And a Right Join?Strategies for Improving Postgres JOIN PerformanceUnderstanding Foreign Keys in PostgreSQLUnderstanding PostgreSQL User-Defined FunctionsUnderstanding SQL Aggregate FunctionsUsing PostgreSQL UPDATE With JOINHow to Install PostgreSQL on LinuxUnderstanding HAVING in PostgreSQL (With Examples)How to Fix No Partition of Relation Found for Row in Postgres DatabasesHow to Fix Transaction ID Wraparound ExhaustionUnderstanding WHERE in PostgreSQL (With Examples)Understanding OFFSET in PostgreSQL (With Examples)What Is a PostgreSQL Inner Join?Understanding PostgreSQL SELECTWhat Is Data Compression and How Does It Work?What Is Data Transformation, and Why Is It Important?What Characters Are Allowed in PostgreSQL Strings?Understanding the Postgres string_agg FunctionWhat Is a PostgreSQL Full Outer Join?Self-Hosted or Cloud Database? A Countryside Reflection on Infrastructure ChoicesUnderstanding the Postgres extract() Function
AWS Timestream for InfluxDB Alternative: When You Need to Look FurtherHow to Migrate from AWS Timestream to PostgreSQL: A Technical GuideHow to Choose a Database: A Decision Framework for Modern ApplicationsPostgreSQL Performance Tuning: Key ParametersA Guide to Scaling PostgreSQLHandling Large Objects in PostgresGuide to PostgreSQL PerformanceDetermining the Optimal Postgres Partition SizeNavigating Growing PostgreSQL Tables With Partitioning (and More)SQL/JSON Data Model and JSON in SQL: A PostgreSQL PerspectiveHow to Use PostgreSQL for Data TransformationPostgreSQL Performance Tuning: Designing and Implementing Your Database SchemaPostgreSQL Performance Tuning: Optimizing Database IndexesWhen to Consider Postgres PartitioningDesigning Your Database Schema: Wide vs. Narrow Postgres TablesBest Practices for Time-Series Data Modeling: Single or Multiple Partitioned Table(s) a.k.a. Hypertables What Is a PostgreSQL Temporary View?PostgreSQL Performance Tuning: How to Size Your DatabaseHow to Compute Standard Deviation With PostgreSQLRecursive Query in SQL: What It Is, and How to Write OneHow to Query JSON Metadata in PostgreSQLHow to Query JSONB in PostgreSQLHow to Reduce Bloat in Large PostgreSQL TablesBest Practices for (Time-)Series Metadata Tables A Guide to Data Analysis on PostgreSQLGuide to PostgreSQL SecurityOptimizing Array Queries With GIN Indexes in PostgreSQLPg_partman vs. Hypertables for Postgres PartitioningTop PostgreSQL Drivers for PythonAn Intro to Data Modeling on PostgreSQLGuide to PostgreSQL Database OperationsUnderstanding PostgreSQL TablespacesWhat Is Audit Logging and How to Enable It in PostgreSQLGuide to Postgres Data ManagementHow to Index JSONB Columns in PostgreSQLHow to Monitor and Optimize PostgreSQL Index PerformanceA Guide to pg_restore (and pg_restore Example)Explaining PostgreSQL EXPLAINA PostgreSQL Database Replication GuideHow PostgreSQL Data Aggregation WorksHow to Use Psycopg2: The PostgreSQL Adapter for PythonBuilding a Scalable DatabaseGuide to PostgreSQL Database Design
PostgreSQL Compression: Every Option, When To Use Each, and What To ExpectBest Practices for Postgres Data ManagementHow to Store Video in PostgreSQL Using BYTEABest Practices for Postgres PerformanceHow to Design Your PostgreSQL Database: Two Schema ExamplesBest Practices for Scaling PostgreSQLHow to Handle High-Cardinality Data in PostgreSQLBest Practices for PostgreSQL AggregationBest Practices for Postgres Database ReplicationHow to Use a Common Table Expression (CTE) in SQLBest Practices for Postgres SecurityBest Practices for PostgreSQL Database OperationsBest Practices for PostgreSQL Data AnalysisTesting Postgres Ingest: INSERT vs. Batch INSERT vs. COPYHow to Manage Your Data With Data Retention PoliciesHow to Use PostgreSQL for Data Normalization
PostgreSQL Extensions: amcheckPostgreSQL Extensions: Turning PostgreSQL Into a Vector Database With pgvectorPostgreSQL Extensions: Unlocking Multidimensional Points With Cube PostgreSQL Extensions: hstorePostgreSQL Extensions: ltreePostgreSQL Extensions: Secure Your Time-Series Data With pgcryptoPostgreSQL Extensions: pg_prewarmPostgreSQL Extensions: pgRoutingPostgreSQL Extensions: pg_stat_statementsPostgreSQL Extensions: Database Testing With pgTAPPostgreSQL Extensions: Install pg_trgm for Data MatchingPostgreSQL Extensions: PL/pgSQLPostgreSQL Extensions: Using PostGIS and Timescale for Advanced Geospatial InsightsPostgreSQL Extensions: Intro to uuid-ossp
What Is ClickHouse and How Does It Compare to PostgreSQL and TimescaleDB for Time Series?Timescale vs. Amazon RDS PostgreSQL: Up to 350x Faster Queries, 44 % Faster Ingest, 95 % Storage Savings for Time-Series DataWhat We Learned From Benchmarking Amazon Aurora PostgreSQL ServerlessTimescaleDB vs. Amazon Timestream: 6,000x Higher Inserts, 5-175x Faster Queries, 150-220x CheaperHow to Store Time-Series Data in MongoDB and Why That’s a Bad IdeaPostgreSQL + TimescaleDB: 1,000x Faster Queries, 90 % Data Compression, and Much MoreEye or the Tiger: Benchmarking Cassandra vs. TimescaleDB for Time-Series Data
Manufacturing Analytics Database: Architecture for Real-Time Production DataRobot Fleet Telemetry: Database Architecture for AMR, Industrial Robot, and Service Robot DataData Center Monitoring: What Database Stores Your Telemetry?Fleet Telemetry Database: How to Store and Query Vehicle Sensor Data at ScaleEV Charging Management System: Architecture, OCPP Data, and the Right DatabaseIIoT Database Requirements: Six Things Your Database Must DoWater Utilities Database: How to Store and Query SCADA, AMI, and Quality Data at ScaleWhat Is an Edge Database? On-Device Storage, Sync Patterns, and Choosing the Right StackA Beginner’s Guide to IIoT and Industry 4.0Data Historian vs. Time-Series Database: How to Choose and When to SwitchWhat Is a Data Historian?The Best Databases for IoT in 2026: A Practical ComparisonHow Hopthru Powers Real-Time Transit Analytics From a 1 TB TableUnderstanding IoT (Internet of Things)Storing IoT Data: 8 Reasons Why You Should Use PostgreSQLHow to Simulate a Basic IoT Sensor Dataset on PostgreSQLFrom Ingest to Insights in Milliseconds: Everactive's Tech Transformation With TimescaleHow Ndustrial Is Providing Fast Real-Time Queries and Safely Storing Client Data With 97 % CompressionWhy You Should Use PostgreSQL for Industrial IoT Data Migrating a Low-Code IoT Platform Storing 20M Records/DayHow United Manufacturing Hub Is Introducing Open Source to ManufacturingBuilding IoT Pipelines for Faster Analytics With IoT CoreVisualizing IoT Data at Scale With Hopara and TimescaleDB
A Brief History of AI: How Did We Get Here, and What's Next?A Beginner’s Guide to Vector EmbeddingsPostgreSQL as a Vector Database: A Pgvector TutorialUsing Pgvector With PythonHow to Choose a Vector DatabaseVector Databases Are the Wrong AbstractionUnderstanding DiskANNA Guide to Cosine SimilarityStreaming DiskANN: How We Made PostgreSQL as Fast as Pinecone for Vector DataImplementing Cosine Similarity in PythonVector Database Basics: HNSWVector Database Options for AWSVector Store vs. Vector Database: Understanding the ConnectionPgvector vs. Pinecone: Vector Database Performance and Cost ComparisonHow to Build LLM Applications With Pgvector Vector Store in LangChainHow to Implement RAG With Amazon Bedrock and LangChainRAG Is More Than Just Vector SearchRefining Vector Search Queries With Time Filters in Pgvector: A TutorialUnderstanding Semantic SearchVector Search vs Semantic SearchHNSW vs. DiskANNWhen Should You Use Full-Text Search vs. Vector Search?Building AI Agents with Persistent Memory: A Unified Database ApproachWhat Is Vector Search? Text-to-SQL: A Developer’s Zero-to-Hero GuideNearest Neighbor Indexes: What Are IVFFlat Indexes in Pgvector and How Do They WorkPostgreSQL Hybrid Search Using Pgvector and CohereBuilding an AI Image Gallery With OpenAI CLIP, Claude Sonnet 3.5, and Pgvector
Understanding OLTPUnderstanding OLAP: What It Is, How It Differs From OLTP, and Running It on PostgreSQLColumnar Databases vs. Row-Oriented Databases: Which to Choose?How to Choose an OLAP DatabaseHow to Choose a Real-Time Analytics DatabaseData Analytics vs. Real-Time Analytics: How to Pick Your Database (and Why It Should Be PostgreSQL)PostgreSQL as a Real-Time Analytics DatabaseWhat Is the Best Database for Real-Time AnalyticsHow to Build an IoT Pipeline for Real-Time Analytics in PostgreSQL
Alternatives to RDSWhy Is RDS so Expensive? Understanding RDS Pricing and CostsEstimating RDS CostsHow to Migrate From AWS RDS for PostgreSQL to TimescaleAmazon Aurora vs. RDS: Understanding the Difference
5 InfluxDB Alternatives for Your Time-Series Data8 Reasons to Choose Timescale as Your InfluxDB Alternative InfluxQL, Flux, and SQL: Which Query Language Is Best? (With Cheatsheet)What InfluxDB Got WrongTimescaleDB vs. InfluxDB: Purpose Built Differently for Time-Series Data
Time-Series Downsampling: The Complete Guide to Tiered Data Resolution in SQLContinuous Aggregates: Incremental Materialized Views for Time-Series DataHow to Migrate Your Data to Timescale (3 Ways)Is Postgres Partitioning Really That Hard? An Introduction To HypertablesComplete Guide: Migrating from MongoDB to Tiger Data (Step-by-Step)Postgres TOAST vs. Timescale CompressionBuilding Python Apps With PostgreSQL: A Developer's GuideMore Time-Series Data Analysis, Fewer Lines of Code: Meet HyperfunctionsPostgreSQL Materialized Views and Where to Find Them5 Ways to Monitor Your PostgreSQL DatabaseTimescale Tips: Testing Your Chunk SizeData Visualization in PostgreSQL With Apache Superset
Postgres cheat sheet
HomeData Center & Infrastructure TelemetryTime series basicsPostgres basicsPostgres guidesPostgres best practicesPostgres extensions
Home
What Is DCIM Software, and What Database Does It Use?Data Center Power Monitoring: The Database Layer Behind PUE, PDU, and Sustainability MetricsPrometheus Long-Term Storage: Thanos, Mimir, VictoriaMetrics, and PostgreSQL Compared
Time Series Forecasting with PostgreSQL: Methods, SQL Examples, and When to Use PythonThe Best Time-Series Databases Compared (2026)Time Series Anomaly Detection: Methods, SQL, and Real-Time ImplementationAWS Timestream Alternatives: Your Migration Options After LiveAnalyticsWhat Is Temporal Data?Time-Series Database: What It Is, How It Works, and When You Need OneIs Your Data Time Series? Data Types Supported by PostgreSQL and TimescaleUnderstanding Database Workloads: Variable, Bursty, and Uniform PatternsTime-Series Analysis and Forecasting With Python What Are Open-Source Time-Series Databases—Understanding Your OptionsStationary Time-Series AnalysisAlternatives to TimescaleWhy Consider Using PostgreSQL for Time-Series Data?Time-Series Analysis in RWhat Is a Time Series and How Is It Used?How to Work With Time Series in Python?Tools for Working With Time-Series Analysis in PythonGuide to Time-Series Analysis in PythonUnderstanding Autoregressive Time-Series ModelingCreating a Fast Time-Series Graph With Postgres Materialized Views
PostgreSQL vs. Cassandra: The Decision Framework for Time-Series and Write-Heavy WorkloadsUnderstanding PostgreSQLOptimizing Your Database: A Deep Dive into PostgreSQL Data TypesUnderstanding FROM in PostgreSQL (With Examples)How to Address ‘Error: Could Not Resize Shared Memory Segment’ Understanding FILTER in PostgreSQL (With Examples)How to Install PostgreSQL on MacOSUnderstanding GROUP BY in PostgreSQL (With Examples)Understanding LIMIT in PostgreSQL (With Examples)Understanding PostgreSQL FunctionsUnderstanding ORDER BY in PostgreSQL (With Examples)PostgreSQL Mathematical Functions: Enhancing Coding EfficiencyUnderstanding PostgreSQL WITHIN GROUPUnderstanding WINDOW in PostgreSQL (With Examples)Using PostgreSQL String Functions for Improved Data AnalysisUnderstanding DISTINCT in PostgreSQL (With Examples)PostgreSQL Joins : A SummaryUnderstanding PostgreSQL Date and Time FunctionsWhat Is a PostgreSQL Cross Join?Understanding ACID Compliance Understanding PostgreSQL Conditional FunctionsStructured vs. Semi-Structured vs. Unstructured Data in PostgreSQLUnderstanding percentile_cont() and percentile_disc() in PostgreSQL5 Common Connection Errors in PostgreSQL and How to Solve ThemData Processing With PostgreSQL Window FunctionsPostgreSQL Join Type TheoryA Guide to PostgreSQL ViewsData Partitioning: What It Is and Why It MattersUnderstanding PostgreSQL Array FunctionsUnderstanding PostgreSQL's COALESCE FunctionUnderstanding the rank() and dense_rank() Functions in PostgreSQLWhat Is a PostgreSQL Left Join? And a Right Join?Strategies for Improving Postgres JOIN PerformanceUnderstanding Foreign Keys in PostgreSQLUnderstanding PostgreSQL User-Defined FunctionsUnderstanding SQL Aggregate FunctionsUsing PostgreSQL UPDATE With JOINHow to Install PostgreSQL on LinuxUnderstanding HAVING in PostgreSQL (With Examples)How to Fix No Partition of Relation Found for Row in Postgres DatabasesHow to Fix Transaction ID Wraparound ExhaustionUnderstanding WHERE in PostgreSQL (With Examples)Understanding OFFSET in PostgreSQL (With Examples)What Is a PostgreSQL Inner Join?Understanding PostgreSQL SELECTWhat Is Data Compression and How Does It Work?What Is Data Transformation, and Why Is It Important?What Characters Are Allowed in PostgreSQL Strings?Understanding the Postgres string_agg FunctionWhat Is a PostgreSQL Full Outer Join?Self-Hosted or Cloud Database? A Countryside Reflection on Infrastructure ChoicesUnderstanding the Postgres extract() Function
AWS Timestream for InfluxDB Alternative: When You Need to Look FurtherHow to Migrate from AWS Timestream to PostgreSQL: A Technical GuideHow to Choose a Database: A Decision Framework for Modern ApplicationsPostgreSQL Performance Tuning: Key ParametersA Guide to Scaling PostgreSQLHandling Large Objects in PostgresGuide to PostgreSQL PerformanceDetermining the Optimal Postgres Partition SizeNavigating Growing PostgreSQL Tables With Partitioning (and More)SQL/JSON Data Model and JSON in SQL: A PostgreSQL PerspectiveHow to Use PostgreSQL for Data TransformationPostgreSQL Performance Tuning: Designing and Implementing Your Database SchemaPostgreSQL Performance Tuning: Optimizing Database IndexesWhen to Consider Postgres PartitioningDesigning Your Database Schema: Wide vs. Narrow Postgres TablesBest Practices for Time-Series Data Modeling: Single or Multiple Partitioned Table(s) a.k.a. Hypertables What Is a PostgreSQL Temporary View?PostgreSQL Performance Tuning: How to Size Your DatabaseHow to Compute Standard Deviation With PostgreSQLRecursive Query in SQL: What It Is, and How to Write OneHow to Query JSON Metadata in PostgreSQLHow to Query JSONB in PostgreSQLHow to Reduce Bloat in Large PostgreSQL TablesBest Practices for (Time-)Series Metadata Tables A Guide to Data Analysis on PostgreSQLGuide to PostgreSQL SecurityOptimizing Array Queries With GIN Indexes in PostgreSQLPg_partman vs. Hypertables for Postgres PartitioningTop PostgreSQL Drivers for PythonAn Intro to Data Modeling on PostgreSQLGuide to PostgreSQL Database OperationsUnderstanding PostgreSQL TablespacesWhat Is Audit Logging and How to Enable It in PostgreSQLGuide to Postgres Data ManagementHow to Index JSONB Columns in PostgreSQLHow to Monitor and Optimize PostgreSQL Index PerformanceA Guide to pg_restore (and pg_restore Example)Explaining PostgreSQL EXPLAINA PostgreSQL Database Replication GuideHow PostgreSQL Data Aggregation WorksHow to Use Psycopg2: The PostgreSQL Adapter for PythonBuilding a Scalable DatabaseGuide to PostgreSQL Database Design
PostgreSQL Compression: Every Option, When To Use Each, and What To ExpectBest Practices for Postgres Data ManagementHow to Store Video in PostgreSQL Using BYTEABest Practices for Postgres PerformanceHow to Design Your PostgreSQL Database: Two Schema ExamplesBest Practices for Scaling PostgreSQLHow to Handle High-Cardinality Data in PostgreSQLBest Practices for PostgreSQL AggregationBest Practices for Postgres Database ReplicationHow to Use a Common Table Expression (CTE) in SQLBest Practices for Postgres SecurityBest Practices for PostgreSQL Database OperationsBest Practices for PostgreSQL Data AnalysisTesting Postgres Ingest: INSERT vs. Batch INSERT vs. COPYHow to Manage Your Data With Data Retention PoliciesHow to Use PostgreSQL for Data Normalization
PostgreSQL Extensions: amcheckPostgreSQL Extensions: Turning PostgreSQL Into a Vector Database With pgvectorPostgreSQL Extensions: Unlocking Multidimensional Points With Cube PostgreSQL Extensions: hstorePostgreSQL Extensions: ltreePostgreSQL Extensions: Secure Your Time-Series Data With pgcryptoPostgreSQL Extensions: pg_prewarmPostgreSQL Extensions: pgRoutingPostgreSQL Extensions: pg_stat_statementsPostgreSQL Extensions: Database Testing With pgTAPPostgreSQL Extensions: Install pg_trgm for Data MatchingPostgreSQL Extensions: PL/pgSQLPostgreSQL Extensions: Using PostGIS and Timescale for Advanced Geospatial InsightsPostgreSQL Extensions: Intro to uuid-ossp
What Is ClickHouse and How Does It Compare to PostgreSQL and TimescaleDB for Time Series?Timescale vs. Amazon RDS PostgreSQL: Up to 350x Faster Queries, 44 % Faster Ingest, 95 % Storage Savings for Time-Series DataWhat We Learned From Benchmarking Amazon Aurora PostgreSQL ServerlessTimescaleDB vs. Amazon Timestream: 6,000x Higher Inserts, 5-175x Faster Queries, 150-220x CheaperHow to Store Time-Series Data in MongoDB and Why That’s a Bad IdeaPostgreSQL + TimescaleDB: 1,000x Faster Queries, 90 % Data Compression, and Much MoreEye or the Tiger: Benchmarking Cassandra vs. TimescaleDB for Time-Series Data
Manufacturing Analytics Database: Architecture for Real-Time Production DataRobot Fleet Telemetry: Database Architecture for AMR, Industrial Robot, and Service Robot DataData Center Monitoring: What Database Stores Your Telemetry?Fleet Telemetry Database: How to Store and Query Vehicle Sensor Data at ScaleEV Charging Management System: Architecture, OCPP Data, and the Right DatabaseIIoT Database Requirements: Six Things Your Database Must DoWater Utilities Database: How to Store and Query SCADA, AMI, and Quality Data at ScaleWhat Is an Edge Database? On-Device Storage, Sync Patterns, and Choosing the Right StackA Beginner’s Guide to IIoT and Industry 4.0Data Historian vs. Time-Series Database: How to Choose and When to SwitchWhat Is a Data Historian?The Best Databases for IoT in 2026: A Practical ComparisonHow Hopthru Powers Real-Time Transit Analytics From a 1 TB TableUnderstanding IoT (Internet of Things)Storing IoT Data: 8 Reasons Why You Should Use PostgreSQLHow to Simulate a Basic IoT Sensor Dataset on PostgreSQLFrom Ingest to Insights in Milliseconds: Everactive's Tech Transformation With TimescaleHow Ndustrial Is Providing Fast Real-Time Queries and Safely Storing Client Data With 97 % CompressionWhy You Should Use PostgreSQL for Industrial IoT Data Migrating a Low-Code IoT Platform Storing 20M Records/DayHow United Manufacturing Hub Is Introducing Open Source to ManufacturingBuilding IoT Pipelines for Faster Analytics With IoT CoreVisualizing IoT Data at Scale With Hopara and TimescaleDB
A Brief History of AI: How Did We Get Here, and What's Next?A Beginner’s Guide to Vector EmbeddingsPostgreSQL as a Vector Database: A Pgvector TutorialUsing Pgvector With PythonHow to Choose a Vector DatabaseVector Databases Are the Wrong AbstractionUnderstanding DiskANNA Guide to Cosine SimilarityStreaming DiskANN: How We Made PostgreSQL as Fast as Pinecone for Vector DataImplementing Cosine Similarity in PythonVector Database Basics: HNSWVector Database Options for AWSVector Store vs. Vector Database: Understanding the ConnectionPgvector vs. Pinecone: Vector Database Performance and Cost ComparisonHow to Build LLM Applications With Pgvector Vector Store in LangChainHow to Implement RAG With Amazon Bedrock and LangChainRAG Is More Than Just Vector SearchRefining Vector Search Queries With Time Filters in Pgvector: A TutorialUnderstanding Semantic SearchVector Search vs Semantic SearchHNSW vs. DiskANNWhen Should You Use Full-Text Search vs. Vector Search?Building AI Agents with Persistent Memory: A Unified Database ApproachWhat Is Vector Search? Text-to-SQL: A Developer’s Zero-to-Hero GuideNearest Neighbor Indexes: What Are IVFFlat Indexes in Pgvector and How Do They WorkPostgreSQL Hybrid Search Using Pgvector and CohereBuilding an AI Image Gallery With OpenAI CLIP, Claude Sonnet 3.5, and Pgvector
Understanding OLTPUnderstanding OLAP: What It Is, How It Differs From OLTP, and Running It on PostgreSQLColumnar Databases vs. Row-Oriented Databases: Which to Choose?How to Choose an OLAP DatabaseHow to Choose a Real-Time Analytics DatabaseData Analytics vs. Real-Time Analytics: How to Pick Your Database (and Why It Should Be PostgreSQL)PostgreSQL as a Real-Time Analytics DatabaseWhat Is the Best Database for Real-Time AnalyticsHow to Build an IoT Pipeline for Real-Time Analytics in PostgreSQL
Alternatives to RDSWhy Is RDS so Expensive? Understanding RDS Pricing and CostsEstimating RDS CostsHow to Migrate From AWS RDS for PostgreSQL to TimescaleAmazon Aurora vs. RDS: Understanding the Difference
5 InfluxDB Alternatives for Your Time-Series Data8 Reasons to Choose Timescale as Your InfluxDB Alternative InfluxQL, Flux, and SQL: Which Query Language Is Best? (With Cheatsheet)What InfluxDB Got WrongTimescaleDB vs. InfluxDB: Purpose Built Differently for Time-Series Data
Time-Series Downsampling: The Complete Guide to Tiered Data Resolution in SQLContinuous Aggregates: Incremental Materialized Views for Time-Series DataHow to Migrate Your Data to Timescale (3 Ways)Is Postgres Partitioning Really That Hard? An Introduction To HypertablesComplete Guide: Migrating from MongoDB to Tiger Data (Step-by-Step)Postgres TOAST vs. Timescale CompressionBuilding Python Apps With PostgreSQL: A Developer's GuideMore Time-Series Data Analysis, Fewer Lines of Code: Meet HyperfunctionsPostgreSQL Materialized Views and Where to Find Them5 Ways to Monitor Your PostgreSQL DatabaseTimescale Tips: Testing Your Chunk SizeData Visualization in PostgreSQL With Apache Superset
Postgres cheat sheet
Tiger Data

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events
Privacy preferencesLegalPrivacySitemap

Subscribe to the Tiger Data newsletter

Gold Partner with Inductive Automation — Ignition

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Tiger Data
GOLD PARTNER WITHINDUCTIVE AUTOMATION

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Privacy preferencesLegalPrivacySitemap

By Tiger Data Team

Updated at Jun 10, 2026

Table of contents

    Continuous Aggregates: Incremental Materialized Views for Time-Series Data

    Continuous Aggregates: Incremental Materialized Views for Time-Series Data

    By Tiger Data Team

    Updated at Jun 10, 2026

    If you run aggregate queries over months of time-series data on standard PostgreSQL, you already know what happens when the dataset gets large. PostgreSQL’s native function, date_trunc, has limitations; for example, you can only aggregate in the units of "hour, day, week, or month". Even grouping in 15 minutes is quite poorly readable. A query that finishes in under a second at 10 million rows can take tens of seconds at 500 million rows. The query isn't wrong. It's doing exactly what PostgreSQL asks: scanning the entire table, recalculating every bucket, from the first timestamp to the last. A continuous aggregate on the same dataset can reduce that to single-digit seconds. A hierarchical continuous aggregate can drop it to sub-second response times. (Exact figures vary by schema, hardware, and query pattern.)

    There's no native PostgreSQL mechanism to change this. REFRESH MATERIALIZED VIEW performs a full-table recompute every time it runs. A cron job calling it every hour doesn't make it faster; it just makes it run more often. This results in increased operational overhead: setting up the functionality, testing it, monitoring it, and maintaining it. For growing datasets, this doesn't scale.

    Continuous aggregates are TimescaleDB's answer. Let’s explore them below. 

    What are continuous aggregates?

    A continuous aggregate is a TimescaleDB materialized view that refreshes incrementally over a hypertable. When new data arrives, only the affected time buckets are recalculated. Historical data that hasn't changed is never touched. The result is a pre-computed aggregate store that stays current without full-table rescans. For context on how this compares to standard views, see our PostgreSQL views guide.

    Three properties define how they work:

    1. Automatic background refresh via add_continuous_aggregate_policy(). No cron jobs, no manual REFRESH calls.

    2. Real-time aggregation as an opt-in: pre-computed data combined with the most recent raw data at query time, so results stay current.

    3. time_bucket() as the required grouping dimension. This is what makes continuous aggregates time-series-aware rather than a general-purpose incremental view. See the documentation for more details on time_bucket.

    Continuous aggregates are a feature of TimescaleDB, the open-source PostgreSQL extension maintained by Tiger Data, and are available in both the self-hosted and managed versions. Tiger Cloud, Tiger Data's fully managed service, handles the underlying infrastructure automatically, so there's no server configuration, extension upgrades, or background worker management to worry about. 

    Here's the minimal syntax to create one. This example buckets raw sensor readings into hourly averages, per device:

    CREATE MATERIALIZED VIEW sensor_hourly WITH (timescaledb.continuous) AS SELECT time_bucket('1 hour', recorded_at) AS bucket, device_id, AVG(temperature) AS avg_temp FROM sensor_readings GROUP BY bucket, device_id WITH NO DATA;

    WITH NO DATA creates the view immediately without waiting for an initial backfill. The refresh policy picks it up from there: 

    SELECT add_continuous_aggregate_policy('sensor_hourly', start_offset => INTERVAL '3 hours', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour' );

    Once the policy is in place, TimescaleDB refreshes the aggregate automatically on the defined schedule — no manual REFRESH calls needed. 

    For the full DDL reference, see the TimescaleDB continuous aggregates documentation.

    Continuous aggregates vs. PostgreSQL materialized views

    Developers who know PostgreSQL materialized views will immediately ask why a standard CREATE MATERIALIZED VIEW plus a cron job doesn't work. The answer is in how refresh works.

    Feature

    PostgreSQL Materialized View

    TimescaleDB Continuous Aggregate

    Refresh mechanism

    Full table recompute

    Incremental (only changed time buckets)

    Triggering refresh

    Manual (REFRESH MATERIALIZED VIEW) or cron job

    Automatic via add_continuous_aggregate_policy()

    Query freshness

    Stale until manually refreshed

    Real-time available (pre-computed + raw data combined)

    Storage

    Stores full result set

    Stores partial aggregation state; supports columnstore compression

    Time-series awareness

    None

    time_bucket() required; optimized for time-range queries

    Maintenance overhead

    High (full recompute on any schema change or data update)

    Low (background worker refreshes only invalidated ranges)

    Requires hypertable

    No

    Yes

    Columnstore

    N/A

    A CAgg can be on columnstore, saving significant storage space and return results even faster with the Hypercore engine.

    Historical data rarely changes. Only recent data does. A full-table refresh on a two-year sensor dataset to incorporate five minutes of new readings wastes significant compute. Continuous aggregates track a materialization watermark, a timestamp representing the upper bound of what has been pre-computed, and only recalculate the time buckets where the underlying data has changed.

    One trade-off: continuous aggregates require TimescaleDB. They're not a vanilla PostgreSQL feature. If you're not using TimescaleDB, a scheduled REFRESH MATERIALIZED VIEW is still your best option. For a deeper look at how continuous aggregates compare to materialized views and when to use each approach, see our guide on the topic.

    How continuous aggregates work

    TimescaleDB tracks a materialization watermark per continuous aggregate: a timestamp representing the upper bound of what has been pre-computed. Data older than the watermark is served from the pre-computed store. Data newer than the watermark can be computed from the raw hypertable chunks at query time when real-time aggregation is enabled.

    You configure when and how often the background job refreshes via add_continuous_aggregate_policy():

    SELECT add_continuous_aggregate_policy('sensor_hourly', start_offset => INTERVAL '3 hours', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour' );
    • start_offset: how far back in time to look for data to refresh

    • end_offset: a buffer before the current time, to avoid refreshing chunks that may still be receiving writes

    • schedule_interval: how frequently the background job runs

    The policy runs automatically. You do not trigger it manually.

    Real-time aggregation behavior is the most common point of confusion. Tiger Docs is the source of truth here:

    • In TimescaleDB v2.13 and later, real-time aggregates are disabled by default. Queries return only pre-computed data up to the materialization watermark. Data newer than the watermark is not visible in the aggregate until the next refresh.

    • To enable real-time aggregation, set materialized_only = false. With real-time on, queries combine pre-computed data for older time ranges with on-the-fly computation for data newer than the watermark. The result is always current.

    • Use materialized_only = true (the v2.13+ default) when you need deterministic, time-bounded results. Use materialized_only = false when dashboard freshness matters more than strict consistency.

    For the full implementation walkthrough, see create a continuous aggregate in the docs.

    Downsampling time-series data with continuous aggregates

    As data ages, per-second granularity becomes unnecessary and expensive to store. A monitoring system needs 1-second metrics for the last hour, 1-minute rollups for the last week, and hourly averages for the last year. Continuous aggregates handle this pattern natively.

    Hierarchical continuous aggregates are the mechanism: a continuous aggregate built on top of another continuous aggregate rather than directly on the raw hypertable. A 15-minute CAGG feeds a 4-hour CAGG, which feeds a daily CAGG. Each tier refreshes from the tier below, not from the full raw dataset. The performance difference is real: queries that scan raw data at hundreds of millions of rows can go from tens of seconds on the raw table to single-digit seconds on a single-tier CAGG, and to sub-second on a hierarchical CAGG at the appropriate granularity. Exact numbers vary by schema and hardware.

    Tiger Data has published examples showing continuous aggregate tables with columnstore compression achieving 80%+ storage reduction compared to the raw hypertable. Verify the specific figures for your schema in the docs.

    Pair this with data retention policies and you get a full data lifecycle: keep raw high-frequency data for 30 days, hourly rollups for one year, daily aggregates indefinitely. For more on how retention policies fit this pattern, see our guide on data retention policies.

    Hierarchical downsampling is built into TimescaleDB, not a separate feature or API. The Tiger Data docs on hierarchical continuous aggregates have worked examples.

    When to use continuous aggregates

    Continuous aggregates are a strong fit for these workloads:

    Real-time monitoring and observability dashboards. Grafana panels and similar tools run aggregate queries over rolling time windows, often on refresh intervals measured in seconds. Pre-computing the aggregates keeps dashboards fast as datasets grow into the hundreds of millions of rows. This is one of the strongest arguments for using PostgreSQL as a real-time analytics database: the same database that ingests your data serves fast, pre-computed aggregate results without a separate OLAP layer. The FlightAware engineering team found that continuous aggregates dropped one of their query times from 6.4 seconds to 30 milliseconds.

    Financial data: OHLC candlesticks from tick data. Generating open/high/low/close values per time interval is a canonical continuous aggregate use case. Continuous aggregates handle the aggregation continuously; queries read the pre-computed result.

    IoT and sensor rollups. Per-device or per-site averages, min, and max at configurable intervals from high-frequency raw data. This covers industrial telemetry, energy monitoring, and logistics tracking.

    Long-term trend analysis. Pre-computing daily or weekly aggregates over two or more years of data for historical analytics workloads. Without continuous aggregates, these queries scan the full raw table on every execution.

    Dashboard query load reduction. If expensive GROUP BY queries are hitting your raw hypertable on every dashboard refresh, continuous aggregates move that work to a background job. Query the pre-computed result instead.

    On the competitive landscape: continuous aggregates are a TimescaleDB-specific feature in the managed PostgreSQL ecosystem. InfluxDB 3.0 does not have native continuous aggregates. Earlier InfluxDB versions (1.x) had "Continuous Queries," which were deprecated in InfluxDB 2.x and are not present in InfluxDB 3.0. QuestDB does not support automatic incremental rollups or continuously-refreshed materialized views; it offers query-time downsampling via SAMPLE BY, but no built-in mechanism for pre-computing and auto-refreshing aggregate results. CrateDB has no equivalent feature.

    For a broader comparison, see the best time-series databases compared.

    Limitations to know

    Window functions. Window functions inside a continuous aggregate view definition are experimental as of TimescaleDB v2.20.0 (disabled by default; enable with timescaledb.enable_cagg_window_functions). In earlier versions, window functions inside a CAGG definition are not supported. The workaround: define the continuous aggregate using standard aggregates, then apply window functions at query time against the CAGG result.

    time_bucket() is required. The primary grouping dimension must be a time_bucket() call on the time column. You cannot use an arbitrary non-time GROUP BY as the primary bucket. Additional grouping dimensions (device_id, symbol, etc.) are supported as secondary dimensions alongside time_bucket().

    Join support. As of TimescaleDB v2.10+, inner joins between a hypertable and a non-hypertable (a regular PostgreSQL table) are supported inside a continuous aggregate definition. As of v2.16+, left joins and lateral joins are also supported. Joins between two hypertables remain unsupported. If your continuous aggregate query needs to join two time-series tables, this is a current hard limit.

    Hypertable requirement. The source table must be a TimescaleDB hypertable. Continuous aggregates cannot be created over standard PostgreSQL tables.

    Most time-series workloads (monitoring, IoT, financial data) aren't affected by the window function or join limitations. For the authoritative, version-specific list, see the TimescaleDB continuous aggregates documentation.

    For related context on PostgreSQL aggregation best practices and when standard aggregation is sufficient, that guide covers the decision points in more depth.

    Getting started with continuous aggregates on Tiger Cloud

    Tiger Cloud includes a built-in console with guided UX for creating and managing continuous aggregates - no SQL required to get started. Refresh policies, compression, and retention are all configurable from the UI, and the console provides built-in visualizations so you can inspect aggregate output directly.

    For teams with existing observability stacks, Tiger Cloud ships with metrics exporters that let you pipe database and policy performance data into Prometheus, Grafana, or whatever tooling you already use.

    To get hands-on, follow the create a continuous aggregate guide in the docs. To try Tiger Cloud, start a free trial. No credit card required.

    FAQ

    What is a continuous aggregate in PostgreSQL?

    A continuous aggregate is a TimescaleDB feature that creates an incrementally-refreshed materialized view over aggregate queries on a hypertable. Unlike standard PostgreSQL materialized views, which require a full-table recompute on each refresh, continuous aggregates only reprocess time buckets where the underlying data has changed.

    How is a continuous aggregate different from a PostgreSQL materialized view?

    The primary difference is the refresh model. A PostgreSQL materialized view refreshes by recomputing the entire result set. A continuous aggregate tracks a watermark and only recalculates time buckets that have changed. For large time-series datasets, this makes continuous aggregates significantly faster to refresh and cheaper to maintain.

    Are continuous aggregates real-time or delayed?

    By default in TimescaleDB v2.13 and later, continuous aggregates are delayed: they return only pre-computed data up to the materialization watermark. In earlier versions, real-time aggregation was enabled by default. You can enable real-time aggregation by setting materialized_only = false. With real-time on, queries combine pre-computed data for older time ranges with on-the-fly computation for data newer than the watermark.

    Does InfluxDB support continuous aggregates?

    InfluxDB 3.0 does not have native continuous aggregates. Earlier versions of InfluxDB (1.x) had Continuous Queries, which were deprecated in InfluxDB 2.x and are absent from InfluxDB 3.0. As of 2026, TimescaleDB is the primary open-source time-series database that supports incremental, automatically-refreshed aggregate views natively in PostgreSQL.

    Does QuestDB have continuous aggregates?

    QuestDB does not support automatic incremental rollups or continuously-refreshed materialized views. It offers query-time downsampling via SAMPLE BY, but no built-in mechanism for pre-computing and auto-refreshing aggregate results.

    What are the limitations of TimescaleDB continuous aggregates?

    The main limitations are: (1) window functions inside a continuous aggregate definition are experimental since v2.20.0, disabled by default; apply window functions at query time instead; (2) the primary grouping dimension must use time_bucket(); (3) as of v2.10+, inner joins are supported; as of v2.16+, left and lateral joins are also supported, but joins between two hypertables remain unsupported. These constraints affect a minority of time-series workloads.

    What is a hierarchical continuous aggregate?

    A hierarchical continuous aggregate is a continuous aggregate built on top of another continuous aggregate rather than directly on the raw hypertable. This enables multi-tier rollup pipelines: a 15-minute rollup feeds a 4-hour rollup, which feeds a daily rollup. Each tier refreshes from the tier below, not from the full raw dataset.

    How does a continuous aggregate refresh policy work?

    You configure a refresh policy with add_continuous_aggregate_policy(). The key parameters are start_offset (how far back to look for data), end_offset (a buffer before current time), and schedule_interval (how often the background job runs). The policy runs automatically.

    Can I use continuous aggregates with compression?

    Yes. Continuous aggregates store data in their own internal tables, which can be compressed using TimescaleDB's columnstore compression. The compression does not affect query behavior; the continuous aggregate remains queryable as normal.

    What happens to a continuous aggregate if I insert data into old time ranges?

    TimescaleDB's invalidation log tracks inserts, updates, and deletes to the raw hypertable. When data is inserted into an already-materialized time range, the affected time buckets are marked as invalid and recalculated on the next refresh. You can also trigger a manual refresh with CALL refresh_continuous_aggregate() for a specific time range.

    Do I need TimescaleDB to use continuous aggregates?

    Yes. Continuous aggregates are a TimescaleDB extension feature and require a hypertable as the source. They are available in the open-source TimescaleDB extension and fully managed in Tiger Cloud. Standard PostgreSQL's closest analog is REFRESH MATERIALIZED VIEW, which performs a full-table recompute with no incremental behavior.

    What is the difference between materialized_only = true and materialized_only = false?

    materialized_only = true (the default in TimescaleDB v2.13+) returns only pre-computed data; data newer than the watermark is not visible until the next refresh. materialized_only = false enables real-time aggregation: queries combine pre-computed data with on-the-fly computation for the most recent data. Use false when you need fresh results; use true when you need deterministic, time-bounded results.