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 12, 2026

Table of contents

    Time-Series Downsampling: The Complete Guide to Tiered Data Resolution in SQL

    Time-Series Downsampling

    By Tiger Data Team

    Updated at Jun 12, 2026

    Most teams that downsample time-series data do it in Python. A batch job summarizes rows into a DataFrame, writes aggregates back to a table, and runs on a schedule. This works until it doesn't: the job falls behind, raw data bloats storage, and dashboards show stale curves with missing peaks. Moving downsampling into the database fixes all three problems. It runs continuously, scales with your data, and preserves curve shape through the entire data lifecycle.

    This guide covers when to downsample, which method to use, and how to build the full tiered resolution ladder in SQL. Tiger Data builds a database purpose-built for time-series data, so the examples here use our toolset. Alternatives are noted where relevant.

    What Is Time-Series Downsampling?

    Time-series downsampling is the process of reducing the temporal resolution of time-series data by replacing multiple raw data points within a time window with a single representative value.

    A sensor emitting readings every second produces 86,400 data points per day. Over a year, querying that raw data for dashboard rendering or long-term trend analysis becomes slow and expensive. Downsampling solves this by trading resolution for performance and cost.

    Engineers downsample for three reasons:

    1. Storage cost reduction: fewer rows stored means lower storage bills, especially for high-frequency IoT and infrastructure data

    2. Query performance: pre-aggregated data returns results orders of magnitude faster than scanning raw rows

    3. Visualization readability: a chart renderer displays 500 points identically to 50,000; the human eye cannot distinguish them at dashboard scale

    Downsampling is not the same as data compression. Compression reduces the storage footprint of raw data without altering its resolution. Downsampling reduces resolution itself. Both are complementary strategies for long-term time-series data management.

    When Do You Need to Downsample?

    Three signals indicate it is time to downsample:

    1. Query latency is growing as your hypertable ages past 30-90 days of raw data

    2. Storage costs are scaling linearly with data volume, and your long-term analysis can tolerate lower granularity

    3. Grafana (or equivalent) renders identically whether it receives 10,000 or 1,000 data points for a given time range

    One situation where downsampling is not appropriate: forensic replay of raw events. Security event logs, compliance audit trails, and medical device records must retain full raw resolution. Downsampling here creates gaps that can invalidate investigations or violate regulatory requirements.

    Downsample

    Keep raw

    IoT sensor telemetry (temperature, humidity, vibration)

    Security event logs

    Infrastructure metrics (CPU, memory, network)

    Financial transaction records

    Energy and utility consumption readings

    Medical device event records

    Dashboards aggregating more than 1 week of data

    Data with regulatory retention requirements

    The Four Downsampling Methods in Tiger Data

    Tiger Data provides four approaches to downsampling, each suited to a different context. This section covers all four; the decision framework appears at the end of the article.

    1. time_bucket() + aggregate: general-purpose, standard SQL

    2. lttb() hyperfunction: visualization-optimized, shape-preserving

    3. asap_smooth() hyperfunction: smoothing-optimized, noise-reducing

    4. Continuous aggregates: database-level automation of any of the above

    time_bucket() Averaging

    time_bucket() divides a time-series into equal-width intervals. Aggregate functions (AVG, MAX, MIN, SUM) collapse each interval to a single row.

    Given a sensor readings table:

    CREATE TABLE sensor_readings ( time TIMESTAMPTZ NOT NULL, sensor_id INT, temperature FLOAT ) WITH (timescaledb.hypertable);

    A 1-hour average downsampled query looks like this:

    SELECT time_bucket('1 hour', time) AS hour, sensor_id, AVG(temperature) AS avg_temp FROM sensor_readings GROUP BY 1, 2 ORDER BY 1, 2;

    Strengths: Simple, requires no extension beyond TimescaleDB, works with any column type, and is compatible with all aggregate functions including SUM, COUNT, MIN, and MAX.

    Limitation: Averaging destroys the shape of the time-series. A sensor that spikes to 95°C for 10 seconds will show only a fraction of a degree above baseline in a 1-hour average; the spike is effectively invisible. For anomaly detection or alerting use cases, this matters.

    Best for: Storage reduction and long-term trend queries where the general trajectory matters more than the exact curve shape.

    Learn more about time_bucket in the Tiger Data docs.

    lttb(): Largest Triangle Three Buckets

    LTTB selects a fixed number of representative points from a larger dataset such that the resulting line chart is visually indistinguishable from the original.

    The algorithm was developed by Sveinn Steinarsson and validated by the tsdownsample benchmark study published in ScienceDirect in January 2025, which benchmarks leading downsampling algorithms for visualization. Tiger Data's lttb() hyperfunction is the SQL-native implementation.

    SELECT time, value FROM unnest( (SELECT lttb(time, temperature, 200) FROM sensor_readings WHERE time > NOW() - INTERVAL '7 days') );

    This returns 200 representative (time, value) pairs drawn from the original dataset. The output must be unnested before use in a SELECT list.

    Strengths: Preserves curve shape including peaks, valleys, and inflection points. Output is visually lossless for dashboard rendering.

    Limitation: lttb() selects original data points rather than computing new aggregate values. It cannot be used for SUM or running totals. It is primarily a read-time function for visualization, not a write-time storage reduction tool.

    Best for: Grafana panels and chart rendering where visual fidelity is required, and when you want to downsample for display without altering stored data.

    See the full lttb() API reference for complete syntax.

    asap_smooth(): Automated Smoothing and Predictability

    asap_smooth() returns a smoothed version of the time-series that removes high-frequency noise while preserving the overall trend shape. It automatically selects the degree of smoothing.

    SELECT time, value FROM unnest( (SELECT asap_smooth(time, temperature, 100) FROM sensor_readings WHERE time > NOW() - INTERVAL '30 days') );

    Contrast with LTTB: lttb() selects original data points from the dataset. asap_smooth() computes new smoothed values that were not present in the raw data. Use lttb() when you want to show actual data with fewer points. Use asap_smooth() when you want to present the trend signal without noise.

    Best for: Dashboards where high-frequency noise obscures the trend, and executive-level summaries of sensor telemetry where a clean signal matters more than individual data points.

    Limitation: ASAP output is computed values rather than original data points. The smoothed series is not suitable for anomaly detection or alerting thresholds, since it removes the very spikes those systems need to detect.

    See the asap_smooth() API reference for full options.

    Continuous Aggregates: Database-Level Automation

    time_bucket(), lttb(), and asap_smooth() all operate at query time. Continuous aggregates operate at write time: they precompute aggregations incrementally as new data arrives, so queries hit precomputed results rather than raw rows.

    A continuous aggregate is a materialized view defined with a time_bucket() group, refreshed automatically on a schedule (or in real time as data lands). This makes continuous aggregates the production-grade implementation of time_bucket() downsampling, not a separate concept but an automated wrapper around it.

    Continuous aggregates can also be stacked hierarchically. An hourly CAGG built on top of a 10-minute CAGG is the mechanism behind the tiered resolution ladder described in the next section.

    For the full guide on creating and managing continuous aggregates, see Continuous Aggregates in Tiger Data. For refresh policy syntax, see the continuous aggregates documentation.

    The Tiered Resolution Ladder: A Complete SQL Pattern

    This is the production pattern most practitioners are searching for: raw data at full resolution for 1 day, 10-minute averages for 1 week, hourly averages for 1 month, daily averages for 1 year or longer. All of it is maintained automatically by the database. It is the most-requested pattern in community forums, and no existing guide implements it end-to-end in SQL.

    Step 1: Create the Base Hypertable

    CREATE TABLE sensor_readings ( time TIMESTAMPTZ NOT NULL, sensor_id INT, temperature FLOAT ) WITH (timescaledb.hypertable);

    Step 2: Create the 10-Minute Continuous Aggregate

    CREATE MATERIALIZED VIEW readings_10min WITH (timescaledb.continuous) AS SELECT time_bucket('10 minutes', time) AS bucket, sensor_id, AVG(temperature) AS avg_temp FROM sensor_readings GROUP BY 1, 2; SELECT add_continuous_aggregate_policy('readings_10min', start_offset => INTERVAL '1 hour', end_offset => INTERVAL '10 minutes', schedule_interval => INTERVAL '10 minutes' );

    Step 3: Create the Hourly CAGG on Top of the 10-Minute CAGG

    This is the pattern that surprises practitioners: you can aggregate an aggregate. The hourly CAGG reads from readings_10min, not from the raw table.

    CREATE MATERIALIZED VIEW readings_hourly WITH (timescaledb.continuous) AS SELECT time_bucket('1 hour', bucket) AS bucket, sensor_id, AVG(avg_temp) AS avg_temp FROM readings_10min GROUP BY 1, 2; SELECT add_continuous_aggregate_policy('readings_hourly', start_offset => INTERVAL '1 day', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '1 hour' );

    Step 4: Add Retention Policies

    Retention policies drop the raw data and lower-resolution CAGGs once they are no longer needed.

    -- Drop raw data older than 1 day SELECT add_retention_policy('sensor_readings', INTERVAL '1 day'); -- Drop 10-minute rollups older than 1 week SELECT add_retention_policy('readings_10min', INTERVAL '1 week'); -- Drop hourly rollups older than 1 month SELECT add_retention_policy('readings_hourly', INTERVAL '1 month');

    Order of operations matters. Apply the retention policy on raw data only after confirming the CAGG is fully refreshed. Dropping raw data before the CAGG has processed it creates permanent data loss. Verify CAGG population before enabling raw data retention.

    For more on data retention policies, including how to check policy status and handle edge cases, see the dedicated guide.

    The result: this pattern gives you queryable daily averages going back years, while keeping the last day of raw data available for forensic queries. You do not have to choose between raw access and historical coverage.

    Five Common Downsampling Myths

    Myth 1: "Downsampling permanently destroys your data."

    Downsampling with continuous aggregates is non-destructive. The CAGG is a separate materialized view. Raw data stays exactly where it is until a retention policy explicitly drops it. You control whether and when raw data is deleted. Adding a CAGG alone changes nothing about the raw table.

    Myth 2: "Just use averaging. It's good enough."

    Averaging destroys the shape of the time-series. A sensor that spikes to 95°C for 10 seconds will show only a fraction of a degree above baseline in a 10-minute average; the spike is effectively invisible. Peaks, valleys, and inflection points disappear. For visualization, lttb() selects actual data points that preserve curve shape. Use averaging for storage reduction when the trend matters; use lttb() when visual accuracy matters.

    Myth 3: "Downsampling is only for Grafana dashboards."

    Visualization is one use case. Storage cost reduction and long-term analytics are equally valid and often more impactful. A hypertable growing at 1M rows per day generates roughly 365M rows per year at raw resolution. Daily averages per sensor reduce that to 365 rows per day per sensor, a reduction of several orders of magnitude for high-cardinality device fleets.

    Myth 4: "Downsampling belongs in Python, not the database."

    Downsampling in Python requires extracting data from the database, transforming it in a DataFrame, and writing results back. That adds latency, network overhead, and ETL complexity. Doing it in the database, where the data already lives, eliminates the round-trip, runs continuously without a scheduler to maintain, and scales with the database rather than with application servers.

    Myth 5: "You must choose between raw data access and long-term historical coverage."

    The tiered resolution ladder gives you both. Raw data is available for the most recent window (for example, 1 day). Lower-resolution aggregates cover longer history. Queries route to the appropriate layer automatically. You get forensic access to recent data and fast long-range analytics over historical data without managing two separate storage systems.

    Decision Framework: Which Method Should You Use?

    For hyperfunctions for time-series analysis beyond downsampling, see the overview of all available Tiger Data hyperfunctions.

    Choose time_bucket() averaging if:

    • You need storage reduction and trend accuracy matters more than shape preservation

    • You are running a one-off query or exploratory analysis rather than building production automation

    • Your aggregate function is SUM, COUNT, or MIN/MAX rather than AVG

    Choose lttb() if:

    • You are rendering a Grafana panel or chart and need visual fidelity with fewer data points

    • You want to downsample for display without altering stored data

    • Visualization latency is the problem (too many points to render smoothly)

    Choose asap_smooth() if:

    • High-frequency noise is obscuring the underlying trend in charts

    • Your audience is non-technical and needs a clean signal without manual smoothing configuration

    Choose continuous aggregates if:

    • You need automated, production-grade downsampling that runs without manual queries

    • You are building the tiered resolution ladder

    • Query performance on historical data is degrading as the hypertable grows

    • You want to combine downsampling with a retention policy for full lifecycle management

    FAQ

    What is time-series downsampling?

    Time-series downsampling is the process of reducing the temporal resolution of time-series data by replacing multiple raw data points within a time window with a single representative value: an average, a selected point, or a smoothed value. Engineers downsample to reduce storage cost, improve query performance, and produce cleaner visualizations.

    How do I downsample time-series data in SQL or PostgreSQL?

    The primary tool is time_bucket() combined with an aggregate function such as AVG, MAX, or MIN. For automated downsampling, define a continuous aggregate, a materialized view that refreshes incrementally as data arrives.

    What is the difference between downsampling and continuous aggregates?

    Downsampling is the goal: reducing data resolution. Continuous aggregates are one mechanism for achieving it automatically. A time_bucket() + AVG query at read time is manual downsampling. A continuous aggregate is the same operation precomputed and stored, refreshed on a schedule.

    How do I set up a tiered retention and downsampling policy?

    Create the base hypertable, then create a continuous aggregate at each resolution tier (10-minute, hourly, daily), with each tier built on the previous one. Add a retention policy to each tier that drops data older than its window.

    What is the best downsampling algorithm for time-series visualization?

    LTTB (Largest Triangle Three Buckets) is the standard for visualization downsampling. It selects original data points that preserve the visual shape of the line. Use asap_smooth() when you want to reduce noise. Use averaging when computing aggregate metrics where the shape of the curve is not the goal.

    How do I handle data downsampling for IoT or sensor data at scale?

    Ingest raw readings into a hypertable, create a hierarchical set of continuous aggregates (10-minute, hourly, daily), and apply a retention policy to the raw table after the first CAGG tier is consistently populated.

    Does downsampling lose data? What are the tradeoffs?

    Downsampling reduces resolution. With continuous aggregates, aggregate values at each tier are preserved permanently. The tradeoff is that you lose the ability to reconstruct individual raw readings older than the raw retention window.

    How do I downsample in TimescaleDB without losing the ability to query the raw data?

    Do not attach a retention policy to the raw hypertable. A continuous aggregate stores the downsampled data independently. Raw data persists until retention is applied. You can query raw data and downsampled data simultaneously at any time.

    What is LTTB downsampling and when should I use it vs. simple averaging?

    LTTB selects representative data points that preserve visual shape including peaks and valleys. Simple averaging collapses a time window to a single computed value, potentially losing short spikes entirely. Use lttb() for visualization. Use averaging for storage and analytics where the trend matters more than individual events.

    How does downsampling work with data retention policies?

    They work as a pair: continuous aggregates create lower-resolution copies of your data; retention policies drop the higher-resolution source after a defined window. Always verify CAGG population before enabling retention on raw data to avoid permanent data loss.