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

Table of contents

    PostgreSQL Compression: Every Option, When To Use Each, and What To Expect

    PostgreSQL Compression: Every Option, When To Use Each, and What To Expect

    By Tiger Data Team

    Updated at Jun 4, 2026

    PostgreSQL ships with TOAST, which compresses individual large values automatically - and most teams stop there. For workloads storing millions of rows of time-series, IoT, or analytical data, TOAST's 20-40% storage reduction on eligible values is rarely enough, because TOAST never fires on the rows where it's needed most: narrow rows with small scalar values.

    This page maps every PostgreSQL compression option, when to use each, and what real-world storage reduction to expect. It covers the full range from built-in TOAST to filesystem-level compression to TimescaleDB's columnar engine via Hypercore. Tiger Data builds TimescaleDB, so that option gets the most depth - it's the only approach that extends PostgreSQL's compression into the columnar tier. The others are covered because most teams will reach for them first, and they're the right choice for many workloads.

    By the end of this page, you should be able to choose a compression strategy for your workload, write the SQL to enable it, and know what storage reduction to expect. For data compression concepts more broadly, see What is data compression and how does it work?.

    The four PostgreSQL compression tiers

    PostgreSQL compression operates at four distinct levels. Each solves a different problem for a different scope of data.

    Tier

    Scope

    Best for

    Expected reduction

    Extension required?

    TOAST (built-in)

    Individual large column values (>2 KB)

    Variable-length text, JSONB, arrays

    20-40% on eligible values

    No

    Column-level COMPRESSION setting (PG14+)

    Per-column, still row-stored

    Tuning pglz vs LZ4 per column type

    Marginal vs default TOAST

    No

    Filesystem compression (ZFS/Btrfs)

    All files on the storage volume

    Ops-level compression, no SQL changes

    30-60% depending on data

    No (OS/infra level)

    TimescaleDB columnar via Hypercore

    Chunks of time-partitioned data

    Time-series, IoT, append-heavy workloads

    Up to 98%; typical 90-97%

    Yes (TimescaleDB extension)

    The sections below cover each tier in order, with SQL and expected ratios. Jump to the decision framework if you already know which tier fits your workload.

    Tier 1: TOAST - PostgreSQL's built-in compression

    TOAST stands for The Oversized Attribute Storage Technique. When a row's stored value exceeds roughly 2 KB, PostgreSQL automatically moves it to a separate TOAST table and optionally compresses it. This is transparent to queries - you read and write the table normally and decompression happens automatically.

    TOAST storage strategies

    Each column has one of four storage strategies:

    • PLAIN - No compression, no out-of-line storage. Data always stays in the main table. Used for fixed-width types like integers and timestamps.

    • EXTENDED - Compress first, then store out-of-line if still too large. This is the default for text, bytea, and jsonb.

    • EXTERNAL - Store out-of-line without compression. Useful when you need fast access to substrings without decompression overhead.

    • MAIN - Compress if possible, prefer inline storage. A middle ground between PLAIN and EXTENDED.

    pglz vs LZ4 for TOAST

    Two algorithms are available for TOAST compression:

    • pglz - PostgreSQL's native algorithm, the default prior to PG14. Slower to compress but built-in with no configuration needed.

    • LZ4 - Available from PG14+. Faster compression and decompression than pglz, with slightly lower compression ratio in benchmarks (pglz achieves roughly 2.23x, LZ4 roughly 2.07x for typical TOAST workloads). For most workloads on PG14+, LZ4 is the better default.

    To inspect and change TOAST settings:

    -- Check TOAST storage strategy for all columns in a table SELECT attname, attstorage FROM pg_attribute WHERE attrelid = 'your_table'::regclass AND attnum > 0; -- Change TOAST storage strategy ALTER TABLE your_table ALTER COLUMN your_column SET STORAGE EXTENDED; -- Set default TOAST compression to LZ4 (PG14+) ALTER TABLE your_table SET (toast_compression = lz4);

    The core TOAST limitation

    TOAST compresses individual column values, not entire rows or the table as a whole. If you have a table with millions of narrow rows - a sensor reading schema like (device_id INT, time TIMESTAMPTZ, value FLOAT) - where no single value exceeds 2 KB, TOAST does nothing. Every value is too small to trigger TOAST, so all those rows sit uncompressed regardless of how many billions of them accumulate.

    This is the fundamental limitation for time-series workloads. For a full breakdown of TOAST mechanics and its limits, see What Is TOAST and Why It Isn't Enough for Data Compression in Postgres.

    Tier 2: Column-level COMPRESSION settings (PostgreSQL 14+)

    PostgreSQL 14 introduced the ability to set a per-column compression algorithm - pglz or lz4 - at the DDL level. This controls which algorithm TOAST uses for that column when it does compress.

    -- Set LZ4 compression for a specific column at table creation CREATE TABLE metrics ( time TIMESTAMPTZ NOT NULL, device_id INT, payload JSONB COMPRESSION lz4 ); -- Change compression algorithm on an existing column ALTER TABLE metrics ALTER COLUMN payload SET COMPRESSION lz4; -- Check compression setting per column SELECT attname, compression FROM pg_attribute WHERE attrelid = 'metrics'::regclass AND attnum > 0;

    You can also set the database-wide default using the default_toast_compression GUC parameter:

    -- Set LZ4 as the default for all new toast-eligible columns ALTER DATABASE mydb SET default_toast_compression = lz4;

    This setting controls the algorithm used within TOAST compression - it does not enable row-level or table-level compression. It's a tuning lever, not a compression strategy. For JSONB and large text columns, switching from pglz to LZ4 typically yields faster compression with a marginally lower ratio.

    When to use this tier: teams running PG14+ on workloads with large variable-length columns (JSONB payloads, text blobs) who want to tune pglz vs LZ4 without adding extensions. Not useful for time-series tables with small float or integer values. For ratio and speed data, see our benchmark of pglz vs. LZ4 compression in PostgreSQL.

    Tier 3: Filesystem compression

    Filesystem compression is real, but it operates outside PostgreSQL entirely. ZFS and Btrfs support transparent compression at the storage layer. PostgreSQL data files are compressed on disk by the OS, with no SQL-level configuration needed. ZFS compression=lz4 and compression=zstd are common configurations for Postgres data directories.

    Expected reduction is typically 30-60% depending on data type and compressibility. This complements TOAST rather than replacing it - the two operate at different layers and stack.

    This option applies to teams managing their own Postgres infrastructure on Linux with control over the storage layer. Managed cloud databases (Tiger Cloud, RDS, Cloud SQL) handle storage-level optimization at the infrastructure level - it is not user-configurable.

    One practical note: Btrfs has a known regression with PostgreSQL where fallocate() calls cause Btrfs to skip compression on PostgreSQL data files under normal database I/O patterns; the compression that appears to work on bulk restores does not apply during regular operations. This became especially pronounced in PostgreSQL 17, which introduced FileFallocate(): any file touched by this call is permanently marked NOCOW by Btrfs, disabling compression regardless of mount options. 

    The limitation: filesystem compression applies uniformly to all files, including indexes and WAL. It has no awareness of data structure or column types. It cannot achieve the column-aware ratios that TimescaleDB's Hypercore delivers for numeric time-series, because the filesystem sees bytes, not database columns.

    Tier 4: TimescaleDB columnar compression via Hypercore

    This is where the first three tiers run out for time-series workloads, and why a fourth tier exists.

    TOAST compresses column values, not rows. A sensor reading of (timestamp, device_id, value) has no individual value over 2 KB - TOAST never fires. Filesystem compression is blunt - it applies the same algorithm regardless of whether it's compressing a float column, a timestamp sequence, or a WAL segment. The problem requires a fundamentally different approach: storing data by column rather than by row, then applying type-aware algorithms to each column.

    That's what TimescaleDB's Hypercore does. For background on why columnar storage enables better compression, see columnar databases vs. row-oriented databases.

    How Hypercore columnar compression works

    TimescaleDB automatically partitions time-series data into fixed-time chunks via hypertables. When a chunk ages past a configurable threshold, Hypercore converts it from row-oriented storage to columnar format, then applies type-aware compression algorithms per column:

    • XOR-based compression (Gorilla-style) - For floating-point values (sensor readings, metrics). XOR-encodes consecutive float values; when values change gradually between timestamps, the XOR result contains many leading zeros that can be stripped. This achieves very high compression for slowly-varying float series - the dominant data type in IoT and monitoring workloads.

    • Delta-of-delta encoding - For timestamps and integer-like types. Stores the second derivative of the data: the difference of differences. For regular-interval time-series (one reading every 5 seconds), the delta-of-delta reduces to a series of zeroes. This compresses an 8-byte timestamp down to a single bit in the ideal case - 64x compression on the time column alone.

    • Simple-8b - For low-cardinality integer sequences (device IDs, status codes). Packs multiple values into 64-bit integers.

    • Dictionary compression - For all other types, and for columns with high repeated-value counts.

    These algorithms are not available in vanilla PostgreSQL - they are part of the TimescaleDB extension's Hypercore storage engine. The compression methods in hypercore docs cover each algorithm in depth.

    Enabling Hypercore compression

    The current API uses timescaledb.enable_columnstore to convert chunks to the columnar format and add_columnstore_policy() to automate it:

    -- Step 1: Create a hypertable (time-based partitioning) CREATE TABLE metrics ( time TIMESTAMPTZ NOT NULL, device_id INT, value FLOAT ) WITH (tsdb.hypertable); -- Step 2: Enable the columnstore on an existing hypertable ALTER TABLE metrics SET ( timescaledb.enable_columnstore, timescaledb.segmentby = 'device_id', timescaledb.orderby = 'time DESC' ); -- Step 3: Add an automated columnstore policy (convert chunks older than 7 days) CALL add_columnstore_policy('metrics', after => INTERVAL '7 days'); -- Manually convert a specific chunk to the columnstore SELECT convert_to_columnstore(c) FROM show_chunks('metrics', older_than => INTERVAL '7 days') c;

    The segmentby column controls how rows are grouped within a chunk for compression. Grouping by device_id means all readings from a single device are stored together - improving both compression ratios and query performance for per-device queries.

    Expected compression ratios

    Data type

    TOAST (pglz)

    TOAST (LZ4)

    TimescaleDB columnar

    Float time-series (sensor data)

    0-5% (no compression if < 2 KB per value)

    0-5%

    90-97% storage reduction

    Integer sequences

    0-5%

    0-5%

    85-95% storage reduction

    JSONB payloads

    40-60%

    35-55%

    70-90% (varies by key cardinality)

    Text / log data

    50-70%

    45-65%

    60-80%

    The real-world numbers match the theory. Ndustrial achieved 97% storage reduction on industrial energy data using TimescaleDB compression. Cloudflare uses TimescaleDB's columnar engine for analytics at scale - see How TimescaleDB Helped Cloudflare Scale Analytics and Reporting. Across Tiger Data's case studies, 90-97% reduction is typical for regular-interval float time-series. Current docs indicate chunks can be compressed by up to 98%.

    For the engineering backstory on how this was built, see Building Columnar Compression in a Row-Oriented Database.

    Direct Compress: write-path compression (tech preview)

    Traditionally, compression ran as a background job that converted older chunks to the columnstore asynchronously. Direct Compress changes this: data is compressed in memory during insertion and written directly to the columnstore, eliminating the write-amplification of compressing already-written data.

    -- For COPY operations SET timescaledb.enable_direct_compress_copy = on;

    The result is significantly reduced I/O footprint at ingest time. This removes the operational trade-off between ingestion speed and compression - previously, teams had to decide between writing data fast (uncompressed) and managing a background compression lag. 

    Note that this feature is a tech preview and is not yet production-ready; it works best for batch ingestion of 1,000 or more rows per segmentby value, and does not work on tables with unique constraints, triggers, or continuous aggregates. For the announcement details, see Introducing Direct Compress.

    Querying compressed data: indexes and DML

    Two objections come up consistently when teams evaluate columnar compression. Both have been resolved.

    "I can't query compressed chunks efficiently." Hypercore supports B-tree and hash indexes on compressed data. Lookup queries on compressed data are up to 1,185x faster than unindexed scans. Compressed data is fully indexable. See PostgreSQL Indexes for Columnstore: 1,185x Faster Lookup Queries.

    "I can't UPDATE or DELETE compressed rows." Compression tuple filtering resolved this. UPDATEs and DELETEs on compressed chunks are supported without decompressing the entire chunk. Only batches matching the query filter are decompressed, delivering up to 500x faster updates and deletes and up to 10x faster upserts. See Bridging the Gap: Introducing Compression Tuple Filtering.

    Decision framework: which compression option is right for your workload?

    Choose TOAST (with LZ4) if:

    • You are on PostgreSQL 14+ and have not yet set default_toast_compression = lz4 - this is a free, zero-risk upgrade

    • Your tables include large variable-length columns: JSONB, text, bytea, xml

    • You want zero additional dependencies - TOAST is built in and always on

    • Your workload is mixed OLTP (reads and writes with large values, not narrow time-series rows)

    Choose column-level COMPRESSION settings if:

    • You are on PG14+ and want to tune the algorithm per column without changing storage strategy

    • You have specific columns where LZ4 is the right trade-off (faster, slightly lower ratio) vs. pglz (slower, slightly higher ratio)

    • You are not adding extensions and need to stay within the vanilla PostgreSQL feature set

    Choose filesystem compression if:

    • You control the storage layer (self-managed Linux deployment with ZFS or Btrfs)

    • You want database-agnostic compression that applies to all files, not just data that triggers TOAST

    • Your primary goal is reducing infrastructure cost without any application or schema changes

    • You understand the limitation: no data-type awareness, applies uniformly to all files including indexes and WAL

    Choose TimescaleDB columnar compression (Hypercore) if:

    • Your data is time-series: sensor readings, metrics, events, logs - anything with a timestamp as the primary partitioning key

    • You need 90%+ storage reduction and TOAST gives you 0-5% on your narrow rows

    • You want to keep full SQL semantics and stay in PostgreSQL - not migrate to a specialized columnar database

    • You need to run analytical queries on compressed data without decompressing to a separate system

    • You are on Tiger Cloud or running the TimescaleDB extension on self-managed Postgres

    When columnar compression is not the right choice:

    • Pure OLTP workloads with many point-row UPDATEs and DELETEs (though compression tuple filtering has substantially reduced this constraint)

    • Tables where rows are not time-ordered and do not benefit from time-partitioned chunks

    • Teams who cannot or will not add a PostgreSQL extension to their deployment

    For implementation details, the TimescaleDB compression documentation covers setup, segmentby/orderby optimization, and policy configuration.

    FAQ

    How does PostgreSQL compression work?

    PostgreSQL compresses data primarily through TOAST (Oversized Attribute Storage Technique). When a column value exceeds roughly 2 KB, PostgreSQL automatically compresses it using pglz (default) or LZ4 (PG14+). The compression is transparent - queries return decompressed data automatically. For time-series or analytical data, the TimescaleDB extension adds columnar compression at the chunk level, applying type-aware algorithms (XOR-based for floats, delta-of-delta for timestamps, simple-8b for integers) and delivering 90-97% storage reduction.

    What compression options does PostgreSQL have?

    Vanilla PostgreSQL offers three levels: TOAST (automatic compression for large column values), column-level COMPRESSION settings that choose between pglz and LZ4 per column (PG14+), and no native table-level compression. At the infrastructure level, filesystem compression (ZFS/Btrfs) can be applied transparently. The TimescaleDB extension adds a fourth tier - columnar compression via Hypercore - which is the only PostgreSQL-native option that achieves 90%+ storage reduction on time-series data.

    How do I compress a PostgreSQL table?

    For standard PostgreSQL, TOAST compression activates automatically for columns with the EXTENDED storage strategy (the default for text, jsonb, bytea). On PG14+, run ALTER TABLE t ALTER COLUMN c SET COMPRESSION lz4 to use LZ4 instead of pglz. For time-series tables, enable TimescaleDB hypertables, configure the columnstore with ALTER TABLE t SET (timescaledb.enable_columnstore = true), then add CALL add_columnstore_policy('t', after => INTERVAL '7 days') to convert chunks automatically.

    What's the difference between TOAST and TimescaleDB compression?

    TOAST compresses individual column values that exceed roughly 2 KB - it fires on a per-value basis and is transparent. It delivers 20-60% reduction on large variable-length values but does nothing for narrow rows with small scalar values (the typical time-series schema). TimescaleDB columnar compression works at the chunk level: it converts entire time-partitioned chunks from row to columnar format, then applies type-aware algorithms. The result is 90-97% reduction for time-series data regardless of row width.

    How do I compress time-series data in PostgreSQL?

    The most effective approach is TimescaleDB's columnar compression via Hypercore. Steps: (1) create a hypertable with CREATE TABLE ... WITH (tsdb.hypertable), (2) configure the columnstore with ALTER TABLE your_table SET (timescaledb.enable_columnstore, timescaledb.segmentby = 'device_id'), (3) add an automated policy with CALL add_columnstore_policy('your_table', after => INTERVAL '7 days'). Chunks older than the policy interval are converted to the columnstore automatically. Typical results for sensor and IoT data: 90-97% storage reduction.

    What is columnar compression in PostgreSQL?

    Columnar compression stores data by column rather than by row, enabling far higher compression ratios for repeated or slowly-changing values across many rows - the pattern typical in time-series and analytical data. Vanilla PostgreSQL is row-oriented and does not support columnar storage natively. The TimescaleDB extension adds columnar storage (via Hypercore) to PostgreSQL through time-partitioned chunks. Each chunk is converted to columnar format and compressed with type-aware algorithms, distinct from TOAST which compresses individual column values within row-oriented storage.

    How does TimescaleDB achieve 90% storage reduction?

    TimescaleDB's Hypercore engine applies type-aware compression algorithms: XOR-based compression for floating-point values, delta-of-delta encoding for timestamps and integer-like types, and simple-8b for low-cardinality integer sequences. Because time-series data is stored in ordered chunks by time, consecutive values in the same column are highly correlated - producing very high compression ratios. Ndustrial achieved 97% storage reduction on industrial energy data.

    What is Gorilla compression in databases?

    Gorilla compression is an XOR-based encoding algorithm originally developed by Facebook for their Gorilla time-series database (published 2015). It compresses floating-point values by XOR-encoding consecutive readings. When a float value changes by a small amount between timestamps - as is typical for sensor data - the XOR result contains many leading zeros that are stripped to store only the changing bits. TimescaleDB implements XOR-based compression for float columns in Hypercore following the same approach.