TigerData logo
TigerData logo
  • Product

    Tiger Cloud

    Robust elastic cloud platform for startups and enterprises

    Agentic Postgres

    Postgres for Agents

    TimescaleDB

    Postgres for time-series, real-time analytics and events

  • Docs
  • Pricing

    Pricing

    Enterprise Tier

  • Developer Hub

    Changelog

    Benchmarks

    Blog

    Community

    Customer Stories

    Events

    Support

    Integrations

    Launch Hub

  • Company

    Contact us

    About

    Timescale

    Partners

    Security

    Careers

Log InTry for free
Home
AWS Time-Series Database: Understanding Your OptionsStationary Time-Series AnalysisThe Best Time-Series Databases ComparedTime-Series Analysis and Forecasting With Python Alternatives to TimescaleWhat Are Open-Source Time-Series Databases—Understanding Your OptionsWhy Consider Using PostgreSQL for Time-Series Data?Time-Series Analysis in RWhat Is Temporal Data?What Is a Time Series and How Is It Used?Is Your Data Time Series? Data Types Supported by PostgreSQL and TimescaleUnderstanding Database Workloads: Variable, Bursty, and Uniform PatternsHow 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
Understanding 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’ How to Install PostgreSQL on MacOSUnderstanding FILTER in PostgreSQL (With Examples)Understanding GROUP BY in PostgreSQL (With Examples)PostgreSQL Join Type TheoryA Guide to PostgreSQL ViewsStructured vs. Semi-Structured vs. Unstructured Data in PostgreSQLUnderstanding Foreign Keys in PostgreSQLUnderstanding PostgreSQL User-Defined FunctionsUnderstanding PostgreSQL's COALESCE FunctionUnderstanding SQL Aggregate FunctionsUsing PostgreSQL UPDATE With JOINHow to Install PostgreSQL on Linux5 Common Connection Errors in PostgreSQL and How to Solve ThemUnderstanding HAVING in PostgreSQL (With Examples)How to Fix No Partition of Relation Found for Row in Postgres DatabasesHow to Fix Transaction ID Wraparound ExhaustionUnderstanding LIMIT in PostgreSQL (With Examples)Understanding PostgreSQL FunctionsUnderstanding ORDER BY in PostgreSQL (With Examples)Understanding WINDOW in PostgreSQL (With Examples)Understanding PostgreSQL WITHIN GROUPPostgreSQL Mathematical Functions: Enhancing Coding EfficiencyUnderstanding DISTINCT in PostgreSQL (With Examples)Using PostgreSQL String Functions for Improved Data AnalysisData Processing With PostgreSQL Window FunctionsPostgreSQL Joins : A SummaryUnderstanding OFFSET in PostgreSQL (With Examples)Understanding PostgreSQL Date and Time FunctionsWhat Is Data Compression and How Does It Work?What Is Data Transformation, and Why Is It Important?Understanding the Postgres string_agg FunctionWhat Is a PostgreSQL Left Join? And a Right Join?Understanding PostgreSQL SELECTSelf-Hosted or Cloud Database? A Countryside Reflection on Infrastructure ChoicesUnderstanding ACID Compliance Understanding percentile_cont() and percentile_disc() in PostgreSQLUnderstanding PostgreSQL Conditional FunctionsUnderstanding PostgreSQL Array FunctionsWhat Characters Are Allowed in PostgreSQL Strings?Understanding WHERE in PostgreSQL (With Examples)What Is a PostgreSQL Full Outer Join?What Is a PostgreSQL Cross Join?What Is a PostgreSQL Inner Join?Data Partitioning: What It Is and Why It MattersStrategies for Improving Postgres JOIN PerformanceUnderstanding the Postgres extract() FunctionUnderstanding the rank() and dense_rank() Functions in PostgreSQL
How to Choose a Database: A Decision Framework for Modern ApplicationsRecursive Query in SQL: What It Is, and How to Write OneGuide to PostgreSQL PerformancePostgreSQL Performance Tuning: Designing and Implementing Your Database SchemaPostgreSQL Performance Tuning: Key ParametersPostgreSQL Performance Tuning: Optimizing Database IndexesHow to Reduce Bloat in Large PostgreSQL TablesDetermining the Optimal Postgres Partition SizeNavigating Growing PostgreSQL Tables With Partitioning (and More)When to Consider Postgres PartitioningAn Intro to Data Modeling on PostgreSQLDesigning Your Database Schema: Wide vs. Narrow Postgres TablesGuide to PostgreSQL Database OperationsBest Practices for Time-Series Data Modeling: Single or Multiple Partitioned Table(s) a.k.a. Hypertables Explaining PostgreSQL EXPLAINBest Practices for (Time-)Series Metadata Tables What Is a PostgreSQL Temporary View?A PostgreSQL Database Replication GuideGuide to Postgres Data ManagementA Guide to Data Analysis on PostgreSQLHow to Compute Standard Deviation With PostgreSQLHow PostgreSQL Data Aggregation WorksA Guide to Scaling PostgreSQLGuide to PostgreSQL SecurityHandling Large Objects in PostgresHow to Query JSON Metadata in PostgreSQLHow to Query JSONB in PostgreSQLHow to Use PostgreSQL for Data TransformationOptimizing Array Queries With GIN Indexes in PostgreSQLPg_partman vs. Hypertables for Postgres PartitioningTop PostgreSQL Drivers for PythonUnderstanding PostgreSQL TablespacesWhat Is Audit Logging and How to Enable It in PostgreSQLHow to Index JSONB Columns in PostgreSQLHow to Monitor and Optimize PostgreSQL Index PerformanceSQL/JSON Data Model and JSON in SQL: A PostgreSQL PerspectiveA Guide to pg_restore (and pg_restore Example)PostgreSQL Performance Tuning: How to Size Your DatabaseHow to Use Psycopg2: The PostgreSQL Adapter for PythonBuilding a Scalable DatabaseGuide to PostgreSQL Database Design
Best Practices for Scaling PostgreSQLHow to Design Your PostgreSQL Database: Two Schema ExamplesHow to Handle High-Cardinality Data in PostgreSQLHow to Store Video in PostgreSQL Using BYTEABest Practices for PostgreSQL Database OperationsHow to Manage Your Data With Data Retention PoliciesBest Practices for PostgreSQL AggregationBest Practices for Postgres Database ReplicationHow to Use a Common Table Expression (CTE) in SQLBest Practices for Postgres Data ManagementBest Practices for Postgres PerformanceBest Practices for Postgres SecurityBest Practices for PostgreSQL Data AnalysisTesting Postgres Ingest: INSERT vs. Batch INSERT vs. COPYHow to Use PostgreSQL for Data Normalization
PostgreSQL Extensions: amcheckPostgreSQL 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: Install pg_trgm for Data MatchingPostgreSQL Extensions: Turning PostgreSQL Into a Vector Database With pgvectorPostgreSQL Extensions: Database Testing With pgTAPPostgreSQL Extensions: PL/pgSQLPostgreSQL Extensions: Using PostGIS and Timescale for Advanced Geospatial InsightsPostgreSQL Extensions: Intro to uuid-ossp
Columnar Databases vs. Row-Oriented Databases: Which to Choose?Data Analytics vs. Real-Time Analytics: How to Pick Your Database (and Why It Should Be PostgreSQL)How to Choose a Real-Time Analytics DatabaseUnderstanding OLTPOLAP Workloads on PostgreSQL: A GuideHow to Choose an OLAP DatabasePostgreSQL 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
Building AI Agents with Persistent Memory: A Unified Database ApproachWhen Should You Use Full-Text Search vs. Vector Search?HNSW vs. DiskANNA 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 LangChainRetrieval-Augmented Generation With Claude Sonnet 3.5 and PgvectorRAG Is More Than Just Vector SearchPostgreSQL Hybrid Search Using Pgvector and CohereImplementing Filtered Semantic Search Using Pgvector and JavaScriptRefining Vector Search Queries With Time Filters in Pgvector: A TutorialUnderstanding Semantic SearchWhat Is Vector Search? Vector Search vs Semantic SearchText-to-SQL: A Developer’s Zero-to-Hero GuideNearest Neighbor Indexes: What Are IVFFlat Indexes in Pgvector and How Do They WorkBuilding an AI Image Gallery With OpenAI CLIP, Claude Sonnet 3.5, and Pgvector
Understanding IoT (Internet of Things)A Beginner’s Guide to IIoT and Industry 4.0Storing IoT Data: 8 Reasons Why You Should Use PostgreSQLMoving Past Legacy Systems: Data Historian vs. Time-Series DatabaseWhy You Should Use PostgreSQL for Industrial IoT DataHow to Choose an IoT DatabaseHow 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 % CompressionHow Hopthru Powers Real-Time Transit Analytics From a 1 TB Table 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
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
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
Complete Guide: Migrating from MongoDB to Tiger Data (Step-by-Step)How to Migrate Your Data to Timescale (3 Ways)Postgres TOAST vs. Timescale CompressionBuilding Python Apps With PostgreSQL: A Developer's Guide5 Ways to Monitor Your PostgreSQL DatabaseData Visualization in PostgreSQL With Apache SupersetMore Time-Series Data Analysis, Fewer Lines of Code: Meet HyperfunctionsIs Postgres Partitioning Really That Hard? An Introduction To HypertablesPostgreSQL Materialized Views and Where to Find ThemTimescale Tips: Testing Your Chunk Size
Postgres cheat sheet
HomeTime series basicsPostgres basicsPostgres guidesPostgres best practicesPostgres extensionsPostgres for real-time analytics
Sections

Performance

Guide to PostgreSQL Performance

Schema design

PostgreSQL Performance Tuning: Designing and Implementing Your Database Schema

Performance tuning

PostgreSQL Performance Tuning: Key ParametersPostgreSQL Performance Tuning: Optimizing Database IndexesHow to Reduce Bloat in Large PostgreSQL TablesPostgreSQL Performance Tuning: How to Size Your Database

Partitioning

Determining the Optimal Postgres Partition SizeNavigating Growing PostgreSQL Tables With Partitioning (and More)When to Consider Postgres PartitioningPg_partman vs. Hypertables for Postgres Partitioning

Database design and modeling

An Intro to Data Modeling on PostgreSQLDesigning Your Database Schema: Wide vs. Narrow Postgres TablesBest Practices for Time-Series Data Modeling: Single or Multiple Partitioned Table(s) a.k.a. Hypertables Best Practices for (Time-)Series Metadata Tables Guide to PostgreSQL Database Design

Database replication

A PostgreSQL Database Replication Guide

Data analysis

A Guide to Data Analysis on PostgreSQLHow to Compute Standard Deviation With PostgreSQL

Data transformation

How to Use PostgreSQL for Data Transformation

Data aggregation

How PostgreSQL Data Aggregation Works

Scaling postgres

A Guide to Scaling PostgreSQLBuilding a Scalable Database

General how to

Fundamentals

How to Choose a Database: A Decision Framework for Modern Applications

Query optimization

Explaining PostgreSQL EXPLAINWhat Is a PostgreSQL Temporary View?Recursive Query in SQL: What It Is, and How to Write OneOptimizing Array Queries With GIN Indexes in PostgreSQL

Database security

Guide to PostgreSQL SecurityWhat Is Audit Logging and How to Enable It in PostgreSQL

Data management

Understanding PostgreSQL TablespacesGuide to Postgres Data ManagementHandling Large Objects in Postgres

Database operations

Guide to PostgreSQL Database Operations

JSON

How to Query JSON Metadata in PostgreSQLHow to Query JSONB in PostgreSQLHow to Index JSONB Columns in PostgreSQLSQL/JSON Data Model and JSON in SQL: A PostgreSQL Perspective

Database tools and libraries

How to Use Psycopg2: The PostgreSQL Adapter for PythonTop PostgreSQL Drivers for Python

Database indexes

How to Monitor and Optimize PostgreSQL Index Performance

Database backups and restore

A Guide to pg_restore (and pg_restore Example)
TigerData logo

Products

Time-series and Analytics AI and Vector Enterprise Plan Cloud Status Support Security Cloud Terms of Service

Learn

Documentation Blog Forum Tutorials Changelog Success Stories Time-series Database

Company

Contact Us Careers About Brand Community Code Of Conduct Events

Subscribe to the Tiger Data Newsletter

By submitting, you acknowledge Tiger Data's Privacy Policy

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

Privacy preferences
LegalPrivacySitemap

Published at Dec 15, 2023

High Availability

A PostgreSQL Database Replication Guide

A Guide to Database Replication in PostgreSQL—two elephants side by side.

Written by Carlo Mencarelli

When scaling PostgreSQL in production, there may come a time when you’ll face two problems:

  1. You need a mechanism to ensure your production database stays up when there’s trouble so your users don’t face downtime.

  2. Your workload is getting so heavy that you must diversify your reads and writes to avoid exhausting your machine and creating issues. 

The good news is that replication in PostgreSQL can help you with both these problems. In this guide, we’ll review database replication, strategies for making your database highly available, and how Timescale makes it easy for you.

PostgreSQL Database Replication Types

PostgreSQL replication is available in two distinct flavors: logical and physical. Both of these have pros and cons, as well as best practices. Let’s dive in.

Logical replication

Logical replication copies the data objects in the database and the changes that happen to them. It starts with a snapshot of the data on the source (publisher) and copies it to the destination (subscriber). After the snapshot is completed, changes are sent to the subscriber in real time and applied in the same order as the publisher—this guarantees transactional consistency.

The PostgreSQL documentation lists some typical use cases for logical replication. Some common ones in my experience include:

  • Replicating data between databases running different major versions of PostgreSQL

  • Consolidating multiple databases into a single database

  • Providing access to subsets of the data to different user groups

The benefit of using logical replication is that it can be used to replicate very granular pieces of data from the database. It’s also suitable for cascading replication or using a subscriber database as a publisher database, which might be relevant if you want to maintain geographically based read replicas for improved performance. Finally, as mentioned above, logical replication is a great way to migrate between major versions of PostgreSQL. One negative related to logical replication is that it is typically slower set up in larger datasets. On write-capable subscriber databases, there is a potential for a conflict to occur, which will end up stopping the replication and require manual intervention before it can be restarted.

Timescale uses logical replication when migrating from PostgreSQL to Timescale databases. Using pgcopydb, a logical decoding tool, Timescale can migrate databases with terabytes of data with almost no downtime, as we show in our blog: “Migrating a Terabyte-Scale PostgreSQL Database to Timescale With (Almost) Zero Downtime.”

Physical replication

Physical replication operates in two ways: file-based log shipping and streaming replication. Both approaches use the Write-Ahead-Logs (WAL) to achieve the replication.

File-based log shipping waits for the WAL file to be filled before sending it to the subscriber database. There is typically a lag due to the wait for a full WAL file, which leads to a window of potential data loss.

Streaming replication sends the WAL records to the subscriber as they are generated. This approach has a reduced window of data loss. However, it is more complex to set up. You also need to be aware of potential delays or stoppages in replication if the streaming connection is broken.

Timescale allows users to configure streaming replication easily and provides in-depth documentation on how to do so.

High Availability With PostgreSQL Replication

Replication plays a pivotal role in having a highly available PostgreSQL database—ensuring it stays online is likely critical to your success. The core concept for high availability (HA) involves maintaining a replica of your primary database on a separate server within your infrastructure. 

In our docs, we discuss the need for backups, redundancies, replication, and failover. We also addressed the issues of database backups and disaster recovery in PostgreSQL in our blog, so if you have any questions on how this works in Timescale, I strongly recommend you read that post.

Now, turning the lens a bit more to achieving high availability, we need to talk about failover. In the case of a problem with the primary database, the system should move requests to a replica database or failover. In the event of a planned failover, the primary is gracefully shut down, and the replica seamlessly takes over as the new primary. In the case of an unplanned failover, the architecture will need to account for various failure scenarios to minimize downtime for the application. This is something that Timescale handles automatically for you any time any type of failure is detected.

While the concept seems straightforward, there are several intricacies to consider:

  • Lack of native failover: PostgreSQL lacks a built-in failover system. As a result, administrators must select and implement an external solution to handle failover scenarios effectively.

  • Reestablishing HA after failure: To maintain the high-availability system's integrity, it must be reestablished after a primary database failure. While this can be automated, it requires additional implementation time and ongoing maintenance to ensure its effectiveness. In the case of a true failover event, this can often be overlooked as well.

  • Automated failover and replication: Automation plays a crucial role in HA. When combined with regular backups, replicas can ensure minimal to no downtime, even in the case of a severe error. Automation guarantees that the failover process happens swiftly and accurately, reducing human intervention and potential errors.

Timescale offers an elegant solution for creating replicas and setting up failover mechanisms. It simplifies the process by providing an automated failover that automatically resets in the event of a primary switch. This feature greatly reduces the complexity associated with manual failover management.

Read Replicas and Distributing Workload

We briefly discuss read replicas in an earlier article on logical and physical backups. Given the focus on replication and how it is related to the use of read replicas, this is a great opportunity to discuss the feature in more depth. While read replicas are often associated with HA, they are equally useful for distributing the workload of read queries. This means that as write queries are directed to the Write-Ahead Log (WAL) in the primary database, read queries can fetch data just as efficiently from a streaming replica.

Sending read requests to a replica server is akin to spreading the load across multiple shoulders. This distribution of the query load helps enhance the overall speed and responsiveness of your database. It acts as a safeguard against overloading the primary database server, ensuring that it remains available for critical write operations.

Another compelling reason to utilize read replicas is security. Read replicas are inherently read-only, which makes them perfect for delegating tasks to utilities that shouldn't have write permissions. They are also great for granting read access to users who may not ever need to write data to the database, such as business intelligence teams. By sending these requests to read replicas, the security and integrity of the database is maintained.

In PostgreSQL, creating a "hot standby" server is a straightforward process. The official PostgreSQL documentation provides clear guidance on setting up a hot standby server with a replica. The primary step is just to set the hot_standby parameter to true. Once this is done, the server becomes ready to handle read requests.

To fully leverage the potential of read replicas, you can manage which queries are directed to which server. This behavior can increase performance when combined with tuning aspects of the engine to improve the fetching of certain data types.

It's essential to monitor connections to ensure that responses are up-to-date and consistent. Additionally, any potential conflicts between the primary and standby servers must be addressed promptly to maintain data integrity. Read more about read scaling in Timescale.

Timescale Replicas: The Automated Solution

If this looks like a time-consuming process, that’s because it is—and that’s when a managed database comes in handy. So, for those seeking a seamless solution, Timescale offers a more convenient approach, handling all the work under the hood required to switch to the replica when there is a failure in the primary database.

Let’s explain this in more detail. In Timescale, you’ll find two types of replicas:

  1. High-availability replicas, whose main goal is to provide increased availability in case of failover, though reads can also be served from them. As mentioned, they are automatically promoted in the event of a failure.

  2. Read replicas, whose main goal is read scaling. Depending on your workload needs, they can be different configuration sizes than the primary, and you can have multiple.

Our commitment to building a dependable and highly available database starts in our architecture: in the face of failures, Timescale automatically spins up a new compute node and reconnects it to the existing decoupled database storage, which itself is independently replicated for high availability and durability.

Even without a replica enabled, this cloud-native architecture can provide full recovery for many types of failures within 30-60 seconds, with more severe physical server failures often taking no more than several minutes of downtime to recover your database.

And database replication in Timescale is as easy as pressing a few buttons. Here’s how you can create a high-availability replica in Timescale:

  • Log in to your Timescale account and click the service you want to replicate.

  • Navigate to the ‘Operations’ tab and select ‘High availability.’

  • Check the pricing of the replica, and click ‘Add a replica.’ Confirm the action by clicking ‘Add replica.’

  • You can see the replicas for each service by clicking on the service name, navigating to the ‘Operations’ tab, and selecting ‘High availability.’ Replicas are not shown in the main ‘Services’ section, as they are not independent.

You can see connection information for the replica by navigating to the ‘Overview’ tab. In the ‘Connection info’ section, select the replica from the ‘Role’ drop-down menu to populate the section with the replica's connection details.

image

All set!

Timescale: Making PostgreSQL Replication Simple

In this write-up, we delved into the world of database replication with PostgreSQL, uncovering its vital role in ensuring high availability, load distribution, and security. Armed with this knowledge, you can now make informed decisions about which replication systems align with your specific needs and requirements.

Whether you're looking to implement manual replication solutions or seeking the simplicity of automated management, PostgreSQL offers a versatile framework to cater to your database replication needs.

Timescale simplifies PostgreSQL replication, offering a seamless and automated approach that not only ensures high availability but also provides hot standbys for read operations. With Timescale, you can focus on optimizing your database's query distribution and performance, allowing you to harness the full potential of PostgreSQL without the complexities of manual management.

Sign up for Timescale's replication services here and discover how effortless database replication can be. Create a free account to elevate your PostgreSQL experience and enjoy the peace of mind that comes with enhanced high availability and workload distribution.

On this page