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

Table of contents

    Time Series Forecasting with PostgreSQL: Methods, SQL Examples, and When to Use Python

    Time Series Forecasting

    By Tiger Data Team

    Updated at Jul 7, 2026

    Time-series forecasting is the process of using historical time-indexed observations to estimate future values of a variable. It differs from time-series analysis, which examines patterns in past data, in that forecasting is specifically predictive and forward-looking. The methods range from a 7-day moving average in a single SQL query to a zero-shot foundation model trained on billions of time points.

    Most time-series forecasting guides assume Python from line one. The imports come first, then the DataFrame setup, then statsmodels or Prophet. If your data lives in PostgreSQL, you're left figuring out the connection layer yourself.

    This guide works the other way. It maps what's achievable directly in the database against what genuinely requires a Python layer, and explains the practical criteria for drawing that line. Because Tiger Data builds on PostgreSQL, there's a natural bias worth naming: the in-database examples use TimescaleDB hyperfunctions where they add value. But the SQL methods here also apply to standard PostgreSQL, and the guide includes cases where Python is clearly the right call.

    Two myths come up repeatedly in developer communities. The first: you need Python for any real forecasting. The second: ARIMA is the default or standard model for time-series work. Both are wrong in ways that matter, and this guide addresses them directly.

    For the conceptual breakdown of time-series components (trend, seasonality, noise decomposition), see the foundational overview. This article picks up where that one leaves off: implementation.

    The framework used throughout: each method is classified as in-database (pure SQL), Python-required, or a reasonable approximation in SQL with Python as the cleaner alternative. The goal is deliberate choice over reflexive defaults.

    The in-database vs. Python decision

    Methods are classified below by what they require, not what's theoretically possible. A recursive CTE can approximate exponential smoothing, but whether it should depends on dataset size, refresh requirements, and team familiarity.

    Method

    SQL native

    Python required

    When to use

    Simple moving average

    Yes

    No

    Trend smoothing, dashboards, alerting baselines

    Time-weighted average

    Yes (time_weight())

    No

    Irregular timestamps, IoT sensor data

    Linear regression (trend extrapolation)

    Yes (regr_slope(), regr_intercept())

    No

    Short-horizon, near-linear trend projection

    Exponential smoothing (simple)

    SQL via recursive CTE

    No, but slow at scale

    When recent data should outweigh older observations

    Holt-Winters (double/triple)

    SQL approximation possible

    Recommended for seasonal variants

    Stable seasonal patterns; use Python for seasonal tuning

    ARIMA / SARIMA

    No

    Yes (statsmodels)

    Strong autocorrelation structure, irregular seasonality

    Prophet

    No

    Yes

    Human-driven seasonality, trend changepoints, holiday effects

    ML-based (LSTM, XGBoost)

    No

    Yes

    Non-linear patterns, many input features

    Foundation models (Chronos-2, TimesFM, MOIRAI-2)

    No

    Yes

    Zero-shot forecasting; emerging, not yet production-standard

    For most Tiger Data setups, PostgreSQL is the source of truth and query engine, Python is the model layer for complex forecasting, and results write back to Postgres for serving. That's not a limitation of the database stack; it's a sensible division of responsibilities. Postgres handles high-throughput ingestion, time-range queries, and result serving at scale. Python handles iterative model fitting and the statistical machinery that SQL was never designed for.

    Myth 1: "You need Python for any real forecasting." Moving averages, time-weighted averages, and linear regression-based trend extrapolation are all production-viable in SQL for monitoring, alerting, and short-horizon projection. The threshold for "you need Python" is iterative model fitting and parameter optimization, not forecasting in general.

    Myth 2: "ARIMA is the standard model." For short-horizon, trend-following use cases, simpler methods often match ARIMA's accuracy with far less complexity. The broader community has moved toward foundation models and tree-based ML for structured business data. ARIMA remains useful when autocorrelation structure is strong, but it stopped being a default years ago.

    Time series forecasting methods: what runs in PostgreSQL vs. Python

    These methods are implementable entirely in SQL, without a Python process or external model server. All examples assume a table with a timestamp column and a numeric value column. time_bucket() requires TimescaleDB and time_weight() requires the TimescaleDB Toolkit extension (bundled on Tiger Cloud); regr_slope() and regr_intercept() are native PostgreSQL aggregates. 

    Simple moving average with time_bucket()

    A simple moving average smooths short-term noise by averaging values over a rolling window. The result is a lag-adjusted trend signal, not a point forecast of a specific future value. For dashboards, alerting thresholds, and short-horizon projection on well-behaved series, this is often enough.

    time_bucket() groups data into consistent hourly intervals; after averaging to one row per hour, a window over 168 of those hourly rows covers 7 days: 

    WITH hourly AS ( SELECT time_bucket('1 hour', recorded_at) AS bucket, AVG(value) AS hourly_avg FROM sensor_readings GROUP BY bucket ) SELECT bucket, AVG(hourly_avg) OVER ( ORDER BY bucket ROWS BETWEEN 167 PRECEDING AND CURRENT ROW ) AS moving_avg_7d FROM hourly ORDER BY bucket;

    The limitation matters: standard SQL window functions treat rows equally regardless of timestamp gaps. If data is irregular (missing hours, variable reporting intervals), the window spans the wrong duration and produces incorrect averages. For irregular data, time_weight() is the correct tool.

    For a deeper implementation guide including SMA variants and edge case handling, see moving averages in SQL.

    Time-weighted averages for irregular timestamps

    Real sensor data often arrives with gaps or variable reporting intervals. A row-based window average double-counts dense periods and under-weights sparse ones. time_weight() weights each observation by the duration it represents, so a reading held for 10 minutes contributes proportionally more than one held for 30 seconds.

    SELECT time_bucket('1 hour', recorded_at) AS bucket, average(time_weight('Linear', recorded_at, value)) AS time_weighted_avg FROM sensor_readings GROUP BY bucket ORDER BY bucket;

    Use this for IoT sensor data, financial tick data, and any series where data arrival rate is not constant. It's a TimescaleDB Toolkit function with no direct equivalent in standard PostgreSQL.

    Linear regression for trend extrapolation

    regr_slope() and regr_intercept() are native PostgreSQL aggregate functions that fit a least-squares regression line over a time window. No extension required. The slope and intercept project the trend forward in a single query with no external dependencies.

    Computing a regression-based 24-hour-ahead forecast from the past 7 days of hourly data:

    SELECT regr_slope(value, EXTRACT(EPOCH FROM recorded_at)) AS slope, regr_intercept(value, EXTRACT(EPOCH FROM recorded_at)) AS intercept, regr_slope(value, EXTRACT(EPOCH FROM recorded_at)) * EXTRACT(EPOCH FROM NOW() + INTERVAL '24 hours') + regr_intercept(value, EXTRACT(EPOCH FROM recorded_at)) AS forecast_24h FROM sensor_readings WHERE recorded_at > NOW() - INTERVAL '7 days';

    This approach assumes a linear trend, so it degrades quickly on seasonal or cyclical data and becomes unreliable beyond short forecast horizons. Use it when the trend is genuinely near-linear over the recent window. For longer horizons or non-linear patterns, the next tier of methods applies.

    Exponential smoothing via recursive CTE

    Exponential smoothing assigns decreasing weights to older observations, with a smoothing factor alpha (0 < alpha < 1). Higher alpha means more weight on recent data; lower alpha means more weight on history. It's computationally simple and performs well on trend-following series without seasonal components.

    WITH ordered AS ( SELECT recorded_at, value, row_number() OVER (ORDER BY recorded_at) AS rn FROM sensor_readings ) -- , then recurse over the row index (no ORDER BY / LIMIT in the recursion) , ema AS ( SELECT recorded_at, value, value AS ema_value, rn FROM ordered WHERE rn = 1 UNION ALL SELECT o.recorded_at, o.value, 0.2 * o.value + 0.8 * e.ema_value, o.rn FROM ordered o JOIN ema e ON o.rn = e.rn + 1 ) SELECT recorded_at, value, ema_value FROM ema ORDER BY recorded_at;

    Recursive CTEs in PostgreSQL process rows one at a time and slow down on large datasets. For production use at scale, pre-compute via continuous aggregates or move the EMA computation to a Python layer. That's the real boundary: when the recursive CTE becomes a bottleneck, you've crossed into Python territory.

    Holt-Winters extends exponential smoothing with trend and seasonality components. A double-exponential version (Holt's linear method) is approximable in SQL using two-pass recursive CTEs, but the triple-exponential seasonal variant requires iterative optimization. At that point, Python's statsmodels is the right tool. The SQL approximation works as a prototype or low-volume implementation; production seasonal forecasting belongs in Python.

    Pre-computing trend inputs with continuous aggregates

    If your moving average or regression scans the full historical table on every query, performance degrades as data grows. A query that took 100ms against 30 days of data may take seconds against 18 months.

    Continuous aggregates solve this by pre-computing and incrementally refreshing rolled-up statistics on a schedule. Forecasting queries hit the materialized view, not the raw hypertable.

    CREATE MATERIALIZED VIEW hourly_sensor_averages WITH (timescaledb.continuous) AS SELECT time_bucket('1 hour', recorded_at) AS bucket, AVG(value) AS avg_value, COUNT(*) AS reading_count, STDDEV(value) AS stddev_value FROM sensor_readings GROUP BY bucket WITH NO DATA; SELECT add_continuous_aggregate_policy('hourly_sensor_averages', start_offset => INTERVAL '3 hours', end_offset => INTERVAL '1 hour', schedule_interval => INTERVAL '5 minutes');

    Continuous aggregates refresh only changed time buckets, not the full dataset. A 5-minute refresh cycle on hourly buckets keeps your forecasting inputs within 5-10 minutes of current without a full-table scan on every query.

    This is the practical answer to the batch vs. real-time tradeoff. Pre-aggregation work is incremental, so near-real-time forecasting inputs are tractable without sacrificing query performance. For implementation detail and refresh policy options, see continuous aggregates in TimescaleDB.

    When to reach for Python: ARIMA, Prophet, and beyond

    There's no penalty for using Python for forecasting. The point is to choose deliberately. Python is the right layer when the model requires iterative fitting, parameter optimization, or non-linear pattern capture that SQL was not designed to handle.

    All methods in this section use PostgreSQL as the data source: connect via psycopg2 or SQLAlchemy, pull pre-aggregated data from the database, fit the model, and write results back to Postgres for serving.

    ARIMA and SARIMA with statsmodels

    ARIMA (Autoregressive Integrated Moving Average) models the relationship between an observation and its lagged values, applies differencing to achieve stationarity, and models residual error as a moving average. SARIMA adds seasonal terms. The model requires iterative parameter estimation (selecting p, d, q values) that is not tractable in SQL.

    A minimal implementation pulling pre-aggregated hourly data from PostgreSQL and fitting an ARIMA model:

    import psycopg2 import pandas as pd from statsmodels.tsa.arima.model import ARIMA conn = psycopg2.connect("host=localhost dbname=mydb user=postgres") df = pd.read_sql( "SELECT bucket, avg_value FROM hourly_sensor_averages " "WHERE bucket > NOW() - INTERVAL '90 days' " "ORDER BY bucket", conn ) model = ARIMA(df['avg_value'], order=(2, 1, 2)) result = model.fit() forecast = result.forecast(steps=24)

    The query pulls from the continuous aggregate view, not the raw hypertable. This keeps the data pull fast regardless of how much raw data has accumulated.

    ARIMA tends to outperform simpler methods when autocorrelation structure is strong and the series is stationary or made stationary via differencing. For series with many external factors or non-linear patterns, tree-based ML often outperforms ARIMA on structured business data with less tuning overhead.

    On stationarity: ARIMA assumes the statistical properties of the series (mean, variance, autocorrelation) do not change over time. Non-stationary series violate this assumption and produce unreliable forecasts. The Augmented Dickey-Fuller (ADF) test in Python's statsmodels.tsa.stattools is the standard check. The "I" component in ARIMA applies differencing to remove trends and achieve stationarity before fitting.

    For deeper coverage of AR modeling concepts, see autoregressive time-series modeling.

    Prophet for trend changepoints and holiday effects

    Prophet (Meta open source) is designed for business time-series data with trend changepoints, seasonality, and known holiday or event effects. It handles missing data and outliers more gracefully than ARIMA, and requires less manual parameter selection. The trade-off is that it needs more history for reliable changepoint detection, typically at least one year.

    A minimal Prophet implementation with a PostgreSQL data pull:

    import psycopg2

    import psycopg2 import pandas as pd from prophet import Prophet conn = psycopg2.connect("host=localhost dbname=mydb user=postgres") df = pd.read_sql( "SELECT bucket AS ds, avg_value AS y " "FROM hourly_sensor_averages " "WHERE bucket > NOW() - INTERVAL '365 days' " "ORDER BY bucket", conn ) model = Prophet(yearly_seasonality=True, weekly_seasonality=True) model.fit(df) future = model.make_future_dataframe(periods=24, freq='H') forecast = model.predict(future)

    Prophet makes sense for demand series, web traffic, sales, and other business metrics with clear weekly and seasonal patterns and identifiable event effects. For univariate series without human-driven seasonality, ARIMA or a moving average is often more appropriate and faster to run.

    Multi-variate and multi-series forecasting at scale

    For IoT fleets with thousands of sensor series, or any use case requiring parallelized forecasting across many series, the Python ecosystem has purpose-built libraries. Nixtla's StatsForecast and NeuralForecast, Darts, and sktime all treat forecasting as a batch-parallelizable operation. They handle cross-learning across series, multiple input features, and batch inference at a scale that single-series ARIMA cannot match.

    The architectural pattern stays the same: Tiger Data as the ingestion and query layer, Python as the forecasting engine, results written back to a forecasts table in PostgreSQL for downstream serving and alerting. What changes is the scale of the batch export and the parallelism in the Python layer.

    For the Python-specific tutorial including data pre-processing and model assessment, see time-series analysis and forecasting with Python.

    Foundation models: the emerging option

    Time-series foundation models are large models pre-trained on diverse time-series datasets, ranging from hundreds of millions to billions of time points. They can forecast new series zero-shot, without per-series training. The analogy to LLMs for text is reasonable: instead of training on tokens, they train on numerical sequences and generalize to unseen domains. This is emerging technology, not yet production-standard for most teams, but worth understanding for where the field is moving.

    Three models have established themselves as benchmarks in this space:

    Chronos-2 (Amazon Science): Pre-trained on a large corpus of diverse time-series data producing probabilistic (quantile) forecasts. Extends beyond univariate to multivariate and covariate-informed forecasting in a single model, zero-shot via in-context learning. Available via HuggingFace. Practical for teams with short history per series or many distinct series to forecast.

    TimesFM (Google Research): The original TimesFM was trained on roughly 100 billion time points from Google-internal and public sources. The current release, TimesFM 2.5 (200M parameters, 16k context), shows strong long-horizon performance and is available as an open-weights model. 

    MOIRAI-2 (Salesforce): Universal time-series forecasting model with strong zero-shot performance across diverse domains including energy, retail, and financial data. Available via HuggingFace.

    For all three, the integration path is the same: a Python script pulls data from PostgreSQL, runs inference using the model's API, and returns a forecast. TimescaleDB handles the data pipeline; the foundation model handles the compute.

    Worth watching on the in-database side: tspDB (MIT) is a PostgreSQL extension that builds a prediction index on top of a standard table, enabling in-database predictive queries - forecasting, imputation, and confidence bounds - through a prediction index created with create_pindex(). It's experimental and not production-ready as of June 2026, but it represents the research direction toward natively integrated forecasting without a Python layer.

    Building a simple forecasting pipeline in PostgreSQL

    Here's how the pieces wire together in production. The two-layer architecture below covers most SQL forecasting use cases.

    Raw time-series data ingests into a hypertable. A continuous aggregate pre-computes hourly averages on a 5-minute refresh cycle. A retention policy drops raw data older than 90 days while preserving the aggregates. On top of that: a scheduled job (cron, Airflow, or another workflow orchestrator) pulls the pre-aggregated data via SQLAlchemy, fits ARIMA or Prophet, and writes forecast rows back to a forecasts table.

    The schema for the forecasts table:

    CREATE TABLE forecasts ( series_id TEXT NOT NULL, forecast_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), horizon_hours INTEGER NOT NULL, forecast_value DOUBLE PRECISION NOT NULL, confidence_lower DOUBLE PRECISION, confidence_upper DOUBLE PRECISION, model_name TEXT, PRIMARY KEY (series_id, forecast_at, horizon_hours) );

    Writing forecasts back to Postgres matters for three reasons. First, downstream dashboards (Grafana, Metabase) query the forecasts table with standard SQL, no specialized tooling required. Second, alerting queries can join actual vs. forecast to detect deviation from expected trajectory. Third, the forecast audit trail stays in the same system as the source data, which simplifies debugging and model versioning.

    For context on retention policies and tiered data resolution that feed the pre-aggregation layer, see time-series downsampling. For how to combine forecasting signals with anomaly alerts, see time-series anomaly detection.

    Choosing the right method: a decision framework

    Choose SQL-native moving averages if:

    • You need trend smoothing or rolling baselines for dashboards or alerting

    • Your forecast horizon is short (hours to a few days)

    • Your data is regular, or you can tolerate a simple row-based average

    • Speed and simplicity matter more than model precision

    Choose SQL linear regression if:

    • The series has a near-linear trend over the recent window

    • You're extrapolating 24 to 72 hours ahead

    • You want a one-query implementation with no external dependencies

    Choose SQL exponential smoothing if:

    • Recent observations should outweigh older ones

    • There is no seasonal component, or the seasonal period is handled elsewhere

    • Dataset is small enough that recursive CTE performance is acceptable

    Choose Python (ARIMA / SARIMA) if:

    • Autocorrelation structure is strong and you need proper parameter selection

    • Seasonality is a factor and a Holt-Winters SQL approximation is not accurate enough

    • You need confidence intervals from a statistically rigorous model

    Choose Python (Prophet) if:

    • Your data has human-driven seasonality (weekly, holiday, business cycle patterns)

    • Trend changepoints matter (sales, traffic, demand series with promotion events)

    • You have enough history for changepoint detection (typically 1+ year)

    Choose Python with foundation models if:

    • You have many short series without enough per-series history for ARIMA or Prophet

    • You want zero-shot forecasting without per-series training

    • You're evaluating state-of-the-art options and can tolerate experimental tooling

    In production, hybrid combinations are common: SQL moving averages for real-time dashboards running alongside ARIMA or Prophet in a nightly batch for medium-horizon forecasts. The two layers complement each other without conflict.

    Start building

    TimescaleDB runs on PostgreSQL. If you're already on Postgres and want to add time-series primitives (hypertables, continuous aggregates, time_weight()) to your forecasting stack, start a Tiger Cloud trial or explore the TimescaleDB docs to get started with self-hosted deployment.

    FAQ

    What is time-series forecasting?

    Time-series forecasting is the process of using historical time-indexed observations to estimate future values of a variable. It differs from time-series analysis, which focuses on understanding patterns in past data; forecasting is specifically predictive and forward-looking. The main method families include statistical models (ARIMA, exponential smoothing), machine learning (tree-based models, LSTM), and emerging foundation models such as Chronos-2 and TimesFM.

    What are the main types of time-series forecasting models?

    The four main categories are: naive and statistical methods (moving average, exponential smoothing), classical statistical models (ARIMA, SARIMA, Holt-Winters), machine learning models (XGBoost on time-indexed features, LSTM), and foundation models (Chronos-2, TimesFM, MOIRAI-2). Simpler models often match or outperform complex ones on short-horizon, well-behaved series.

    Can you do time-series forecasting in PostgreSQL without Python?

    Yes. Moving averages, time-weighted averages, and linear regression are all implementable in standard SQL using window functions and aggregate functions such as regr_slope() and regr_intercept(). TimescaleDB extends this with time_bucket() for consistent bucketing and time_weight() for irregular timestamps. For models that require iterative fitting (ARIMA, Prophet, ML models), Python is the appropriate layer on top of PostgreSQL.

    What is the difference between ARIMA and exponential smoothing?

    Exponential smoothing assigns decreasing weights to older observations and is computationally simple, making it a good baseline for trend-following series. ARIMA explicitly models autocorrelation structure and applies differencing to achieve stationarity. For short-horizon, trend-following series, exponential smoothing often performs comparably to ARIMA with less complexity. ARIMA tends to offer an advantage when autocorrelation patterns are strong and irregular.

    Why is stationarity important in time-series forecasting?

    ARIMA and related statistical models assume that the statistical properties of the series (mean, variance, and autocorrelation) do not change over time. Non-stationary series with trends or changing variance violate this assumption and produce unreliable forecasts. Differencing, the 'I' component in ARIMA, is the standard technique for removing trends and achieving stationarity before fitting the model.

    Is Holt-Winters better than ARIMA for seasonal data?

    Not categorically. Holt-Winters is simpler and interpretable, making it a strong baseline for series with stable seasonal patterns. SARIMA can model more complex seasonal structures and handles non-stationarity more explicitly. In practice, both should be benchmarked. For many short-horizon business forecasting problems, Holt-Winters performs comparably to SARIMA with less tuning overhead.

    When should I use Prophet instead of ARIMA?

    Prophet is designed for business time-series with human-driven seasonality (weekly patterns, holiday effects, promotional events) and trend changepoints. It handles missing data and outliers well. ARIMA is better suited to stationary series with strong autocorrelation structure where a formal statistical model with confidence intervals is required. Prophet generally needs at least one year of history for reliable changepoint detection.

    How do I use moving averages for time-series forecasting in SQL?

    Use a window function with AVG() over a ROWS BETWEEN N PRECEDING AND CURRENT ROW clause, combined with time_bucket() in TimescaleDB to group data into consistent time intervals. The result is a smoothed estimate of the current trend, useful for dashboards, anomaly detection baselines, and short-horizon projection when the trend is stable. For irregular timestamps, use time_weight() instead of a simple row-based window.

    What are foundation models for time-series forecasting?

    Foundation models such as Chronos-2, TimesFM, and MOIRAI-2 are large models pre-trained on diverse time-series datasets that can forecast new series zero-shot without per-series training. They use a Python API and connect to PostgreSQL data via standard database connectors. They are an emerging option showing strong benchmark performance, but are not yet production-standard for most teams.

    How do real-world events affect time-series forecasting accuracy?

    External events (promotions, outages, weather, economic shocks) create structural breaks that purely statistical models miss. Prophet handles known events via explicit holiday and event regressors. ARIMA requires manual intervention analysis for structural breaks. The practical recommendation is to flag known events in your data and evaluate model performance separately for event and non-event periods before deploying a forecast.

    What is the difference between time-series analysis and time-series forecasting?

    Time-series analysis is retrospective: it identifies patterns, trends, seasonality, and anomalies in historical data. Time-series forecasting is prospective: it uses those patterns to estimate future values. In practice, analysis informs forecasting. You identify the trend and seasonal structure through analysis before selecting a forecasting model that can replicate that structure.

    How do I build a simple forecasting pipeline with PostgreSQL?

    The standard pattern is to ingest raw time-series data into a hypertable, use a continuous aggregate to pre-compute hourly or daily averages on a refresh schedule, then run a scheduled Python job that pulls the pre-aggregated data, fits a forecasting model, and writes results back to a forecasts table in PostgreSQL. Downstream dashboards and alerting queries join the forecasts table against actuals using standard SQL.