<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[Tiger Data Blog]]></title>
        <description><![CDATA[Insights, product updates, and tips from TigerData (Creators of TimescaleDB) engineers on Postgres, time series & AI. IoT, crypto, and analytics tutorials & use cases.]]></description>
        <link>https://www.tigerdata.com/blog</link>
        <image>
            <url>https://www.tigerdata.com/icon.ico</url>
            <title>Tiger Data Blog</title>
            <link>https://www.tigerdata.com/blog</link>
        </image>
        <generator>RSS for Node</generator>
        <lastBuildDate>Tue, 07 Apr 2026 09:51:55 GMT</lastBuildDate>
        <atom:link href="https://www.tigerdata.com/blog" rel="self" type="application/rss+xml"/>
        <ttl>60</ttl>
        <item>
            <title><![CDATA[Best Practices for Query Optimization on PostgreSQL]]></title>
            <description><![CDATA[Explore the optimization of PostgreSQL queries using tactics such as efficient indexing and partitioning, and judicious use of data types.]]></description>
            <link>https://www.tigerdata.com/blog/best-practices-for-query-optimization-in-postgresql</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/best-practices-for-query-optimization-in-postgresql</guid>
            <category><![CDATA[Product & Engineering]]></category>
            <category><![CDATA[PostgreSQL]]></category>
            <category><![CDATA[PostgreSQL Performance]]></category>
            <category><![CDATA[PostgreSQL Tips]]></category>
            <dc:creator><![CDATA[Team Tiger Data]]></dc:creator>
            <pubDate>Fri, 08 Dec 2023 15:18:00 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL-1.png">
            </media:content>
            <content:encoded><![CDATA[<p>The demands of modern applications and the exponential growth of data in today’s data-driven world have put immense pressure on databases. Traditional relational databases, including PostgreSQL, are increasingly being pushed to their limits as they struggle to cope with the sheer scale of data that needs to be processed and analyzed, requiring constant query optimization practices and performance tweaks.</p><p>Having built our product on PostgreSQL, at Timescale we’ve written extensively on the topic of tweaking your PostgreSQL database performance, from <a href="https://www.timescale.com/learn/postgresql-performance-tuning-how-to-size-your-database"><u>how to size your database</u></a>, <a href="https://www.timescale.com/learn/postgresql-performance-tuning-key-parameters"><u>key PostgreSQL parameters</u></a>, <a href="https://www.timescale.com/learn/postgresql-performance-tuning-optimizing-database-indexes"><u>database indexes</u></a>, and <a href="https://www.timescale.com/learn/postgresql-performance-tuning-designing-and-implementing-database-schema"><u>designing your schema</u></a> to <a href="https://www.timescale.com/learn/when-to-consider-postgres-partitioning"><u>PostgreSQL partitioning</u></a>.</p><p>In this article, we aim to explore best practices for enhancing query optimization in PostgreSQL. We’ll offer insights into optimizing queries, the importance of indexing, data type selection, and the implications of fluctuating data volumes and high transaction rates.</p><p>Let’s jump right in.</p><h2 id="why-is-postgresql-query-optimization-necessary">Why Is PostgreSQL Query Optimization Necessary?</h2>
<p>Optimizing your PostgreSQL queries becomes a necessity when performance issues significantly impact the efficiency and functionality of your PostgreSQL database, making your application sluggish and impacting the user experience. Before we dive into the solutions, let’s look at some of the key contributors to performance issues in PostgreSQL:</p>
<p><strong>Inefficient queries</strong>: The impact of poorly optimized or complex queries on PostgreSQL's performance is profound. These queries act as significant bottlenecks, impeding data processing efficiency and overall database throughput. Regular analysis and refinement of these query structures are not just beneficial but crucial for maintaining optimal database performance. <a href="https://www.postgresql.org/docs/current/queries.html">Understanding and optimizing SQL queries</a> is essential for efficient database operations. This knowledge is pivotal for developing efficient and responsive database operations, ensuring the database's capability to handle complex <a href="https://www.tigerdata.com/learn/understanding-database-workloads-variable-bursty-and-uniform-patterns">data workloads</a> effectively.</p>
<p><strong>Insufficient indexes</strong>: Inadequate indexing can significantly slow down query execution in PostgreSQL. Strategically implementing indexes, particularly on columns that are frequently accessed, can drastically enhance performance and optimize database responsiveness. <a href="https://timescale.ghost.io/blog/use-composite-indexes-to-speed-up-time-series-queries-sql-8ca2df6b3aaa/">Effective indexing strategies</a> are not only crucial for accelerating query speeds but also play a main role in optimizing the efficiency of complex queries and large-scale data operations, ensuring a more responsive and robust database environment.</p>
<p><strong>Over-indexing</strong>: While it's true that insufficient indexing can hurt your <a href="https://www.tigerdata.com/learn/postgres-performance-best-practices">PostgreSQL performance</a>, it's equally important not to overdo it. Excessive indexes can lead to their own set of challenges: each additional index introduces overhead during your <code>INSERT</code>s, <code>UPDATE</code>s, and <code>DELETE</code>s, they consume disk space and can make database maintenance tasks (such as vacuuming) more time-consuming.</p>
<p><strong>Inappropriate data types</strong>: Using unsuitable data types in PostgreSQL can lead to increased storage usage and slower query execution, as inappropriate types may need additional processing and can occupy more storage space than necessary. Carefully <a href="https://timescale.ghost.io/blog/best-practices-for-picking-postgresql-data-types/">selecting and optimizing data types</a> to align with the specific characteristics of the data is a critical aspect of database optimization. The right choice of data types not only influences overall database performance but also contributes to storage efficiency. Additionally, it helps in avoiding costly type conversions during <a href="https://www.tigerdata.com/learn/guide-to-postgresql-database-operations">database operations</a>, thereby streamlining data processing and retrieval.</p>
<p><strong>Fluctuating data volume</strong>: PostgreSQL's query planner relies on up-to-date data statistics to formulate efficient execution plans. Fluctuations in data volume can significantly impact these plans, potentially leading to suboptimal performance if the planner operates on outdated information. As data volumes change, it becomes crucial to regularly assess and adapt execution plans to these new conditions. Keeping the database statistics current is essential, as it enables the query planner to accurately assess the data landscape and make informed decisions, thereby optimizing query performance and ensuring the database responds effectively to varying data loads.</p>
<p><strong>High transaction volumes</strong>: Large numbers of transactions can significantly strain PostgreSQL's resources, especially in high-traffic or data-intensive environments. Effectively leveraging <a href="https://docs.timescale.com/use-timescale/latest/ha-replicas/read-scaling/#read-replicas">read replicas</a> in PostgreSQL can substantially mitigate the impact of high transaction volumes, ensuring a more efficient and robust database environment.</p>
<p><strong>Hardware limitations</strong>: Constraints in CPU, memory, or storage can create significant bottlenecks in PostgreSQL's performance, as these hardware limitations directly affect the database's ability to process queries, handle concurrent operations, and store data efficiently. Upgrading hardware components, such as increasing CPU speed, expanding memory capacity, or adding more storage, can provide immediate improvements in performance. Additionally, optimizing resource allocation, like adjusting memory distribution for different database processes or balancing load across storage devices, can also effectively alleviate these hardware limitations.</p>
<p><strong>Lock contention</strong>: Excessive locking on tables or rows in PostgreSQL, particularly in environments that handle parallel queries, can lead to significant slowdowns, inconsistent data, and locking issues. This is because row-level or table-level locks can restrict data access, leading to increased waiting times for other operations and potentially causing queuing delays. Therefore, <a href="https://timescale.ghost.io/blog/how-timescaledb-solves-common-postgresql-problems-in-database-operations-with-data-retention-management/">judicious use of locks</a> is crucial in maintaining database concurrency and ensuring smooth operation. Strategies such as using less restrictive lock types, designing transactions to minimize locked periods, and optimizing query execution plans can help reduce lock contention.</p>
<p><strong>Lack of maintenance</strong>: Routine maintenance tasks such as vacuuming, reindexing, and updating statistics are fundamental to sustaining optimal performance in PostgreSQL databases. Vacuuming is essential for reclaiming storage space and preventing <a href="https://timescale.ghost.io/blog/how-to-fix-transaction-id-wraparound/">transaction ID wraparound issues</a>, ensuring the database remains efficient and responsive. Regular reindexing is crucial for maintaining the speed and efficiency of index-based query operations, as indexes can become fragmented over time. Additionally, keeping statistics up-to-date is vital for the query planner to make well-informed decisions, as outdated statistics can lead to suboptimal query plans. Ignoring these tasks can lead to a gradual but significant deterioration in database efficiency and reliability.</p>
<h2 id="how-to-measure-query-performance-in-postgresql">How to Measure Query Performance in PostgreSQL</h2>
<h3 id="pgstatstatements">pg_stat_statements</h3>
<p>To optimize your queries, you must first identify your PostgreSQL performance bottlenecks. A simple way to do this is using <code>pg_stat_statements</code>, a <a href="https://www.tigerdata.com/blog/top-8-postgresql-extensions">PostgreSQL extension</a> that provides essential information about query performance. It records data about running queries, helping to identify performance slowdowns caused by inefficient queries, index changes, or ORM query generators. Notably, <code>pg_stat_statements</code> is enabled by default in TimescaleDB, enhancing its capability to monitor and optimize database performance out of the box.</p>
<p>You can query <code>pg_stat_statements</code> to gather various statistics such as the number of times a query has been called, total execution time, rows retrieved, and cache hit ratios:</p>
<ul>
<li>
<p><strong>Identifying long-running queries</strong>: Focus on queries with high average total times, adjusting the <code>calls</code> value based on specific application needs.</p>
</li>
<li>
<p><strong>Hit cache ratio</strong>: This metric measures how often data needed for a query was available in memory, which can affect query performance.</p>
</li>
<li>
<p><strong>Standard deviation in query execution time</strong>: Analyzing the standard deviation can reveal the consistency of query execution times, helping to identify queries with significant performance variability.</p>
</li>
</ul>
<h3 id="insights-by-timescale">Insights by Timescale</h3>
<p>Timescale’s Insights (available to Timescale users at no extra cost) is a tool providing in-depth observation of PostgreSQL queries over time. It offers detailed statistics on query timing, latency, and memory and storage I/O usage, enabling users to comprehensively monitor and analyze their query and database performance.</p>
<ul>
<li>
<p><strong>Scalable query collection system</strong>: Insights is built on a scalable system that collects sanitized statistics on every query stored in Timescale, facilitating comprehensive analysis and optimization. <a href="https://timescale.ghost.io/blog/how-we-scaled-postgresql-to-350-tb-with-10b-new-records-day/">And the best part is that the team is dogfooding its own product to enable this tool</a>, expanding PostgreSQL to accommodate hundreds of TBs of data (and growing).</p>
</li>
<li>
<p><strong>Insights interface</strong>: The tool presents a graph showing the relationship between system resources (CPU, memory, disk I/O) and query latency.</p>
</li>
</ul>
<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://timescale.ghost.io/blog/content/images/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL_Insights.png" class="kg-image" alt="Insights offers a drill-down view with finer-grain metrics for quick query optimization" loading="lazy" width="2000" height="1564" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL_Insights.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL_Insights.png 1000w, https://timescale.ghost.io/blog/content/images/size/w1600/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL_Insights.png 1600w, https://timescale.ghost.io/blog/content/images/size/w2400/2023/12/Best-Practices-for-Query-Optimization-on-PostgreSQL_Insights.png 2400w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Insights offers a drill-down view with finer-grain metrics for quick query optimization</span></figcaption></figure><ul>
<li>
<p><strong>Detailed query information</strong>: Insights provides a table of the top 50 queries based on chosen criteria, offering insights into query frequency, affected rows, and usage of Timescale features like hypertables and continuous aggregates.</p>
</li>
<li>
<p><strong>Drill-down view</strong>: Insights offers a drill-down view with finer-grain metrics, including trends in latency, buffer usage, and cache utilization.</p>
</li>
<li>
<p><strong>Real-world application</strong>: Check out the <a href="https://twitter.com/gooddaymax/status/1717573289285996889?s=20&amp;ref=timescale.com">Humblytics</a> story, which demonstrates Insights' practical application in identifying and resolving performance issues.</p>
</li>
</ul>
<h2 id="best-practices-for-query-optimization-in-postgresql">Best Practices for Query Optimization in PostgreSQL</h2>
<h3 id="understand-common-performance-bottlenecks">Understand common performance bottlenecks</h3>
<p>To effectively identify inefficient queries so you can optimize them, analyze query execution plans using PostgreSQL's <code>EXPLAIN</code> command. This tool provides a breakdown of how your queries are executed, revealing critical details such as execution paths and the use of indexes. Look specifically for patterns like full table scans, which suggest missing indexes or queries consuming high CPU or memory, indicating potential optimizations. By understanding the intricacies of the execution plan, you can pinpoint exactly where performance issues are occurring.</p>
<p>For example, you could run the following code to view the execution plan of a query:</p>
<pre><code class="language-sql">EXPLAIN SELECT * FROM your_table WHERE your_column = 'value';
</code></pre>
<p>To identify full table scans, you would look for “Seq Scan” in the output. This suggests that the query is scanning the entire table, which is often a sign that an index is missing or not being used effectively:</p>
<pre><code class="language-SQL">Seq Scan on large_table  (cost=0.00..1445.00 rows=50000 width=1024)
</code></pre>
<div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">📚</div><div class="kg-callout-text"><a href="https://www.postgresql.org/docs/current/using-explain.html"><u>Check out the PostgreSQL documentation for more examples of what to look for when using </u><u><code spellcheck="false" style="white-space: pre-wrap;">EXPLAIN</code></u></a><u>.</u></div></div><h3 id="partition-your-data">Partition your data</h3>
<p>Partitioning large PostgreSQL tables is a powerful strategy to enhance their speed and efficiency. However, the process of setting up and maintaining partitioned tables can be burdensome, often requiring countless hours of manual configurations, testing, and maintenance. But, there's a more efficient solution: hypertables. Available through the TimescaleDB extension and on AWS via the Timescale platform, hypertables simplify the PostgreSQL partition creation process significantly by automating the generation and management of <a href="https://www.tigerdata.com/learn/data-partitioning-what-it-is-and-why-it-matters">data partitions</a> without altering your user experience. Behind the scenes, however, hypertables work their magic, accelerating your queries and ingest operations.</p>
<p>To create a <a href="https://www.tigerdata.com/blog/database-indexes-in-postgresql-and-timescale-cloud-your-questions-answered">hypertable</a>, create a regular PostgreSQL table:</p>
<pre><code class="language-SQL">CREATE TABLE conditions (
   time        TIMESTAMPTZ       NOT NULL,
   location    TEXT              NOT NULL,
   device      TEXT              NOT NULL,
   temperature DOUBLE PRECISION  NULL,
   humidity    DOUBLE PRECISION  NULL
);
</code></pre>
<p>Then, convert the table to a hypertable. Specify the name of the table you want to convert and the column that holds its time values.</p>
<pre><code class="language-SQL">SELECT create_hypertable('conditions', by_range('time'));
</code></pre>
<div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">📚</div><div class="kg-callout-text">Want to learn more about hypertables? <a href="https://www.timescale.com/learn/pg_partman-vs-hypertables-for-postgres-partitioning"><u>Check out this comparison of pg_partman vs. hypertables.</u></a></div></div><p></p><p><br></p><p></p><h3 id="employ-partial-aggregation-for-complex-queries">Employ partial aggregation for complex queries</h3>
<p><a href="https://docs.timescale.com/use-timescale/latest/continuous-aggregates/about-continuous-aggregates/">Continuous aggregates</a> in TimescaleDB are a powerful tool to improve the performance of commonly accessed aggregate queries over large volumes. Continuous aggregates are based on PostgreSQL materialized views but incorporate incremental and automatic refreshes so they are always up-to-date and remain performant as the underlying dataset grows.</p>
<p>In the example below, we’re setting up a continuous aggregate for daily average temperatures, which is remarkably simple.</p>
<pre><code class="language-sql">CREATE VIEW daily_temp_avg
WITH (timescaledb.continuous)
AS
SELECT time_bucket('1 day', time) as bucket, AVG(temperature)
FROM hypertable
GROUP BY bucket;
</code></pre>
<p>Learn how continuous aggregates can help you get real-time analytics or create a time-series graph.</p>
<h3 id="continuously-update-and-educate">Continuously update and educate</h3>
<p><a href="https://timescale.ghost.io/blog/read-before-you-upgrade-best-practices-for-choosing-your-postgresql-version/">Regularly updating PostgreSQL and TimescaleDB</a> is vital for performance and security. The upgrade process involves assessing changes, performance gains, security patches, and extension compatibility. Focus on best practices, which include upgrading major versions at minor version .2 for stability, consistently updating minor versions, and upgrading major versions when needed for functionality or security. Timescale further eases this process by handling minor updates automatically with no downtime and providing tools for testing major version upgrades, ensuring smooth transitions with minimal disruption.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Optimizing your queries in PostgreSQL doesn’t have to be a daunting task. While it involves understanding and addressing various factors, there is much you can do by adopting best practices, such as efficient indexing, judicious use of data types, regular database maintenance, and staying up-to-date with the latest PostgreSQL releases.</p>
<p>If you really want to extend PostgreSQL’s capabilities, <a href="https://console.cloud.timescale.com/signup">create a free Timescale account today</a>. Features such as hypertables, continuous aggregates, and advanced data management techniques significantly enhance PostgreSQL's ability to manage your demanding workloads effectively.</p>
<p>Written by <a href="https://pt.w3d.community/paulogio">Paulinho Giovannini</a></p>
]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What Is TOAST (and Why It Isn’t Enough for Data Compression in Postgres)]]></title>
            <description><![CDATA[Postgres TOAST is often seen as a data compression mechanism in PostgreSQL, but it falls short of that task. Learn how TOAST really works and why there is a better alternative.]]></description>
            <link>https://www.tigerdata.com/blog/what-is-toast-and-why-it-isnt-enough-for-data-compression-in-postgres</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/what-is-toast-and-why-it-isnt-enough-for-data-compression-in-postgres</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <dc:creator><![CDATA[Team Tiger Data]]></dc:creator>
            <pubDate>Wed, 25 Oct 2023 18:48:16 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2023/10/What-Is-TOAST--and-Why-It-Isn-t-Enough-for-Data-Compression-in-Postgres-.png">
            </media:content>
            <content:encoded><![CDATA[<p>If you’re working with large databases in Postgres, this story will sound familiar. As your Postgres database keeps growing, your performance starts to decline, and you begin to worry about storage space—or, to be precise, how much you’ll pay for it. You love PostgreSQL, but there’s something you wish you had: a highly effective data compression mechanism.</p><p>PostgreSQL does have somewhat of a compression mechanism: <a href="https://www.postgresql.org/docs/current/storage-toast.html">TOAST</a> 🍞. In this post, we’ll walk you through how Postgres TOAST works and the different TOASTing strategies. <br><br>As much as we enjoy a good TOAST, we’ll discuss why this is not the kind of compression feature you need for reducing the storage footprint of modern large databases—and how, as the PostgreSQL enthusiasts that we are here at Timescale, we decided to build a more suitable compression mechanism for PostgreSQL, inspired by the columnar design of NoSQL databases.&nbsp;</p><h2 id="what-is-postgres-toast">What Is Postgres TOAST?</h2><p>Even if it might reduce the size of datasets, TOAST (The Oversized Attribute Storage Technique) is not your traditional data compression mechanism. To understand  TOAST, we have to start by understanding <a href="https://www.timescale.com/blog/how-to-reduce-your-postgresql-database-size" rel="noreferrer">how PostgreSQL stores data</a>.&nbsp;</p><p>Postgres’ storage units are called pages, and pages have a fixed size (8 kB by default). Having a fixed page size gives Postgres many advantages: <a href="https://www.timescale.com/blog/guide-to-postgres-data-management" rel="noreferrer">data management simplicity, efficiency, and consistency</a>. But there is a downside: some data values might not fit within that page.&nbsp;</p><p>This is where TOAST comes in. TOAST refers to the automatic mechanism that PostgreSQL uses to efficiently store and manage values in Postgres that do not fit within a page. To handle such values, Postgres TOAST will, by default, compress them using an internal algorithm. If, after compression, the values are still too large, Postgres will move them to a separate table (called the TOAST table), leaving pointers in the original table.&nbsp;</p><p>(As we’ll see later in this article, you can modify this strategy as a user, for example, by telling&nbsp;Postgres to avoid compressing data in a particular column.)</p><h2 id="toast-able-data-types">TOAST-able Data Types&nbsp;</h2><p>The data types subject to TOAST are primarily variable-length ones that have the potential to exceed the size limits of a standard PostgreSQL page. On the other hand, fixed-length data types, like <code>integer</code>, <code>float</code>, or&nbsp; <code>timestamp</code>, are not subjected to TOAST since they fit comfortably within a page.&nbsp;</p><p>Some examples of these data types are:&nbsp;</p><ul><li><code>json</code> and <code>jsonb</code></li><li>Large <code>text</code> strings</li><li><code>varchar</code> and <code>varchar(n)</code> (If the length specified in <code>varchar(n)</code> is small enough, then values of that column might always stay below the TOAST threshold.)</li><li><code>bytea</code> storing binary data</li><li>Geometric data like <code>path</code> and <code>polygon</code> and PostGIS types like&nbsp; <code>geometry</code> or <code>geography</code></li></ul><h2 id="how-does-postgres-toast-work">How Does Postgres TOAST Work?&nbsp;</h2><p>Understanding TOAST relates not only to page size but also to another Postgres storage concept: tuples. Tuples are rows in a PostgreSQL table. Typically, the TOAST mechanism kicks in if all fields within a tuple have a total size of over 2 kB approx.</p><p>If you’ve been paying attention, you might wonder, “Wait, but the page size is around 8&nbsp;kB—why is there overhead?” That’s because PostgreSQL likes to ensure it can store multiple tuples on a single page: if tuples are too large, fewer tuples fit on each page, leading to increased I/O operations and reduced performance. </p><p>Postgres also needs to keep free space to fit additional operational data: each page stores the tuple data <em>and</em> additional information for managing the data, such as item identifiers, headers, and transaction information.&nbsp;</p><p>So, when the combined size of all fields in a tuple exceeds approximately 2&nbsp;kB (or the TOAST threshold parameter, as we’ll see later), PostgreSQL takes action to ensure that the data is stored efficiently. TOAST handles this in two primary ways:</p><ol><li><strong>Compression.</strong> PostgreSQL can compress the large field values within the tuple to reduce their size using a <a href="https://www.tigerdata.com/blog/time-series-compression-algorithms-explained" rel="noreferrer">compression algorithm</a>. By default, if compression is sufficient to bring the tuple's total size below the threshold, the data will remain in the main table, albeit in a compressed format.</li><li><strong>Out-of-line storage.</strong> If compression alone isn't effective enough to reduce the size of the large field values, Postgres moves them to a separate TOAST table. This process is known as "out-of-line" storage because the original tuple in the main table doesn’t hold the large field values anymore. Instead, it contains a "pointer" or reference to the location of the large data in the TOAST table.&nbsp;</li></ol><p>(We’re simplifying things slightly for the purpose of this article—<a href="https://www.postgresql.org/docs/current/storage-toast.html">read the PostgreSQL documentation for a full detailed view.</a>)&nbsp;</p><h2 id="the-postgres-compression-algorithm-pglz">The Postgres Compression Algorithm: <code>pglz</code>&nbsp;</h2><p>We’ve mentioned that TOAST can compress large values in PostgreSQL. But which compression algorithm is PostgreSQL using, and how effective is it?&nbsp;</p><p>The <code>pglz</code> (PostgreSQL Lempel-Ziv) is the default internal compression algorithm used by PostgreSQL specifically tailored for TOAST. Here’s how it works in simple terms:</p><ul><li><code>pglz</code> tries to avoid repeated data. When it sees repeated data, instead of writing the same thing again, it just points back to where it wrote it before. This "avoiding repetition" helps in saving space.</li><li>As <code>pglz</code> reads through data, it remembers a bit of the recent data it has seen. This recent memory is the "sliding window."</li><li>As new data comes in, <code>pglz</code> checks if it has seen this data recently (within its sliding window). If yes, it writes a short reference instead of repeating the data.</li><li>If the data is new or not repeated enough times to make a reference shorter than the actual data, <code>pglz</code> just writes it down as it is.</li><li>When it's time to read the compressed data, <code>pglz</code> uses its references to fetch the original data. This process is quite direct, as it looks up the referred data and places it where it belongs.</li><li><code>pglz</code> doesn't need separate storage for its memory (the sliding window); it builds it on the go while compressing and does the same when decompressing.</li></ul><p>This implementation balances compression efficiency and speed within the TOAST mechanism. The compression rate effectiveness of <code>pglz</code> will largely depend on the nature of the data. </p><p>For example, highly repetitive data will compress much better than high entropy data (like random data). You might see compression ratios in the range of 25 to 50 percent, but this is a very general estimate—results will vary widely based on the exact nature of the data.</p><h2 id="configuring-toast">Configuring TOAST&nbsp;<br></h2><h3 id="toast-strategies">TOAST strategies&nbsp;</h3><p>By default, PostgreSQL will go through the TOAST mechanism according to the procedure explained earlier (compression first and out-of-line storage next, if compression is not enough). Still, there might be scenarios where you might want to fine-tune this behavior on a per-column basis. PostgreSQL allows you to do this using the TOAST strategies <code>EXTENDED</code>, <code>EXTERNAL</code>, <code>MAIN</code>, and&nbsp; <code>PLAIN</code>.</p><ul><li><strong><code>EXTENDED</code>: </strong>This is the default strategy. Data will be stored out of line in a separate TOAST table if it’s too large for a regular table page. Data will be compressed to save space before being moved to the TOAST table.</li><li><strong><code>EXTERNAL</code>: </strong>This strategy tells PostgreSQL to store the data for this column out of line if the data is too large to fit in a regular table page, and we’re asking PostgreSQL not to compress the data—the value will be moved to the TOAST table as-is.</li><li><strong><code>MAIN</code>: </strong>This strategy is a middle ground. It tries to keep data in line in the main table through compression; if the data is definitely too large, it will move the data to the TOAST table to avoid an error, but PostgreSQL won't move the compressed data. Instead, it will store the value in the TOAST table in its original form.&nbsp;</li><li><strong><code>PLAIN</code>: </strong>Using <code>PLAIN</code> in a column tells PostgreSQL to always store the column's data in line in the main table, ensuring it isn't moved to an out-of-line TOAST table. Take into account that if the data grows beyond the page size, the <code>INSERT</code> will fail because the data won’t fit.&nbsp;</li></ul><p>If you want to inspect the current strategies of a particular table, you can run the following:&nbsp;</p><pre><code class="language-SQL">\d+ your_table_name&nbsp;
</code></pre>
<p>You'll get an output like this: </p><pre><code class="language-sql">=&gt; \d+ example_table
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Table "public.example_table"
&nbsp;Column&nbsp; | &nbsp; &nbsp; &nbsp; Data Type &nbsp; | Modifiers | Storage&nbsp; | Stats target | Description&nbsp;
---------+------------------+-----------+----------+--------------+-------------
&nbsp;&nbsp;bar&nbsp; &nbsp; | varchar(100000)&nbsp; | &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | extended |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |&nbsp;
  ```</code></pre><p>If you wish to modify the storage setting, you can do so using the following command:&nbsp;</p><pre><code class="language-SQL">-- Sets EXTENDED as the TOAST strategy for bar_column&nbsp;
ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;
</code></pre>
<h3 id="key-parameters">Key parameters&nbsp;</h3><p>Apart from the strategies above, these two parameters are also important to control TOAST behavior: &nbsp;</p><p><strong><code>TOAST_TUPLE_THRESHOLD</code></strong></p><p>This is the parameter that sets the size threshold for when TOASTing operations (compression and out-of-line storage) are considered for oversized tuples.</p><p>As previously mentioned, <code>TOAST_TUPLE_THRESHOLD</code> is set to approximately 2&nbsp;kB by default.</p><p><strong><code>TOAST_COMPRESSION_THRESHOLD</code></strong></p><p>This parameter specifies the minimum size of a value before Postgres considers compressing it during the TOASTing process.</p><p>If a value surpasses this threshold, PostgreSQL will attempt to compress it. However, just because a value is above the compression threshold, it doesn't automatically mean it will be compressed: the TOAST strategies will guide PostgreSQL on how to handle the data based on whether it was compressed and its resultant size relative to the tuple and page limits, as we’ll see in the next section.&nbsp;</p><h3 id="bringing-it-all-together">Bringing it all together</h3><p><code>TOAST_TUPLE_THRESHOLD</code> is the trigger point. When the size of a tuple's data fields combined exceeds this threshold, PostgreSQL will evaluate how to manage it based on the set TOAST strategy for its columns, considering compression and out-of-line storage. The exact actions taken will also depend on whether column data surpasses the <code>TOAST_COMPRESSION_THRESHOLD</code>.</p>
<!--kg-card-begin: html-->
<table style="border:none;border-collapse:collapse;"><colgroup><col width="160"><col width="307"><col width="233"><col width="233"></colgroup><tbody><tr style="height:0pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;background-color:#f3f3f3;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Strategy&nbsp;</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;background-color:#f3f3f3;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Compress if tuple &gt; TOAST_COMPRESSION_THRESHOLD</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;background-color:#f3f3f3;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Store out-of-line if tuple &gt; TOAST_TUPLE_THRESHOLD</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;background-color:#f3f3f3;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Description&nbsp;</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">EXTENDED</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Default strategy. Compresses first, then checks if out-of-line storage is needed.&nbsp;</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">MAIN</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Only in uncompressed form&nbsp;</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Compresses first, and if still oversized, moves to TOAST table without compression.&nbsp;</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">EXTERNAL</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">No</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Yes</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Always moves to TOAST if oversized, without compression.</span></p></td></tr><tr style="height:0pt"><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">PLAIN</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">No</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">No</span></p></td><td style="border-left:solid #000000 1pt;border-right:solid #000000 1pt;border-bottom:solid #000000 1pt;border-top:solid #000000 1pt;vertical-align:top;padding:5pt 5pt 5pt 5pt;overflow:hidden;overflow-wrap:break-word;"><p dir="ltr" style="line-height:1.2;margin-top:0pt;margin-bottom:0pt;"><span style="font-size:11pt;font-family:Arial,sans-serif;color:#000000;background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">Data always stays in the main table. If a tuple exceeds the page size, an error occurs.&nbsp;</span></p></td></tr></tbody></table>
<!--kg-card-end: html-->
<p></p><h2 id="why-toast-isnt-enough-as-a-data-compression-mechanism-in-postgresql">Why TOAST Isn't Enough as a Data Compression Mechanism in PostgreSQL&nbsp;</h2><p>By now, you’ll probably understand why TOAST is not the data compression mechanism you wish you had in PostgreSQL. Modern applications imply large volumes of data ingested daily, meaning databases (over)grow quickly. </p><p>Such a problem was not as prominent when our beloved Postgres was built decades ago, but today’s developers need compression solutions for reducing the storage footprint of their datasets.&nbsp;</p><p>While TOAST incorporates compression as one of its techniques, it's crucial to understand that its primary role isn't to serve as a database compression mechanism in the traditional sense. TOAST is mainly a solution to one problem: managing large values within the structural confines of a Postgres page.&nbsp;</p><p>While this approach can lead to some storage space savings due to the compression of specific large values, its primary purpose is not to optimize storage space across the board. </p><p>For example, if you have a 5 TB database made up of small tuples, TOAST won’t help you turn those 5 TB into 1 TB. While there are parameters within TOAST that can be adjusted, this won't transform TOAST into a generalized storage-saving solution. </p><p>And there are other inherent problems with using TOAST as a traditional compression mechanism in PostgreSQL; for example:  </p><ul><li>Accessing TOASTed data can add overhead, especially when the data is stored out of line. This overhead becomes more evident when many large text or other TOAST-able data types are frequently accessed.</li><li>TOAST lacks a high-level, user-friendly mechanism for dictating compression policies. It’s not built to optimize storage costs or facilitate storage management.</li><li>TOAST's compression is not designed to provide high compression ratios. It only uses one algorithm  (<code>pglz</code>) with compression rates varying typically from 25-50 percent.&nbsp;</li></ul><h2 id="adding-columnar-compression-to-postgresql-with-timescale">Adding Columnar Compression to PostgreSQL With Timescale&nbsp;</h2><p><a href="https://docs.timescale.com/self-hosted/latest/install/" rel="noreferrer">Via the TimescaleDB extension</a>, PostgreSQL users have a better alternative. Inspired by the compression design of NoSQL databases, <a href="https://www.timescale.com/blog/building-columnar-compression-in-a-row-oriented-database" rel="noreferrer">we added columnar compression functionality to PostgreSQL</a>. This transformative approach transcends PostgreSQL’s conventional row-based storage paradigm, introducing the efficiency and performance of columnar storage. </p><p>By adding a compression policy to your large tables, <a href="https://www.timescale.com/blog/how-ndustrial-is-providing-fast-real-time-queries-and-safely-storing-client-data-with-97-compression/" rel="noreferrer"><strong>you can reduce your PostgreSQL database size by up to 10x (achieving +90 percent compression rates)</strong></a>. &nbsp;</p><div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">💪</div><div class="kg-callout-text">Ready for a compression faceoff? Read our <a href="https://www.timescale.com/blog/postgres-toast-vs-timescale-compression/" rel="noreferrer">PostgreSQL TOAST vs. Timescale Compression</a> comparison and see the numbers for yourself!</div></div><p><br></p><p>By defining a time-based compression policy, you indicate when data should be compressed. For instance, you might choose to compress data older than seven (7) days automatically: &nbsp;</p><pre><code class="language-SQL">-- Compress data older than 7 days
SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');
</code></pre>
<p>Via this compression policy, Timescale will transform the table <a href="https://www.timescale.com/learn/when-to-consider-postgres-partitioning" rel="noreferrer">partitions</a> (<a href="https://www.timescale.com/learn/is-postgres-partitioning-really-that-hard-introducing-hypertables" rel="noreferrer">which in Timescale are <em>also created automatically</em></a>) into a <a href="https://www.tigerdata.com/blog/building-columnar-compression-in-a-row-oriented-database" rel="noreferrer">columnar</a> format behind the scenes, combining many rows (1,000) into an array. To boost compressibility,  Timescale will apply different compression algorithms depending on the data type:&nbsp;</p><ul><li><a href="http://www.vldb.org/pvldb/vol8/p1816-teller.pdf?ref=timescale.com">Gorilla compression</a> for floats</li><li>Delta-of-delta + <a href="https://arxiv.org/abs/1209.2137?ref=timescale.com">Simple-8b</a> with <a href="https://github.com/lemire/FastPFor/tree/c69935a1b507ea58c4cbd2f5e32d997e2c7402e9?ref=timescale.com">run-length encoding</a> compression for timestamps and other integer-like types</li><li>Whole-row dictionary compression for columns with a few repeating values (+ LZ compression on top)</li><li>LZ-based array compression for all other types</li></ul><p>This columnar compression design offers an efficient and scalable solution to the problem of large datasets in PostgreSQL. It allows you to use less storage to store more data without hurting your query performance (it actually improves it). <a href="https://docs.timescale.com/about/latest/release-notes/#timescaledb-2110-on-2023-05-22" rel="noreferrer">And in the latest versions of TimescaleDB, you can also <code>INSERT</code>, <code>DELETE</code>, and <code>UPDATE</code> directly over compressed data.&nbsp;</a></p><h2 id="keep-reading">Keep Reading</h2><p>Have we piqued your curiosity? Read the following blog posts to learn more about compression in Timescale: </p><ul><li><a href="https://www.timescale.com/blog/building-columnar-compression-in-a-row-oriented-database" rel="noreferrer">Building Columnar Compression in a Row-Oriented Database&nbsp;</a></li><li><a href="https://www.timescale.com/blog/how-ndustrial-is-providing-fast-real-time-queries-and-safely-storing-client-data-with-97-compression" rel="noreferrer">How Ndustrial Is Providing Fast Real-Time Queries and Safely Storing Client Data With 97 % Compression</a></li><li><a href="https://www.timescale.com/blog/allowing-dml-operations-in-highly-compressed-time-series-data-in-postgresql" rel="noreferrer">Allowing DML Operations in Highly Compressed Time-Series Data in PostgreSQL</a></li><li><a href="https://www.timescale.com/blog/time-series-compression-algorithms-explained" rel="noreferrer">Time-Series Compression Algorithms, Explained</a></li></ul><h2 id="wrap-up">Wrap-Up&nbsp;</h2><p>We hope this article helped you understand that while TOAST is a well-thought-out mechanism to manage large values within a PostgreSQL page, it’s not effective for optimizing database storage within the realm of modern applications. </p><p>If you’re looking for effective data compression that can move the needle on your storage savings, give Timescale a go. You can try our cloud platform <a href="https://www.timescale.com/blog/postgresql-timescaledb-1000x-faster-queries-90-data-compression-and-much-more" rel="noreferrer">that propels PostgreSQL to new performance heights</a>, making it faster and fiercer—<a href="https://console.cloud.timescale.com/signup">it’s free, and no credit card is required</a>—or you can add<a href="https://docs.timescale.com/self-hosted/latest/install/"> the TimescaleDB extension</a> to your self-hosted PostgreSQL database. </p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Database Backups and Disaster Recovery in PostgreSQL: Your Questions, Answered]]></title>
            <description><![CDATA[Database backups are one of the biggest pain points for developers. Use our guide to PostgreSQL backup to help you navigate your way.]]></description>
            <link>https://www.tigerdata.com/blog/database-backups-and-disaster-recovery-in-postgresql-your-questions-answered</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/database-backups-and-disaster-recovery-in-postgresql-your-questions-answered</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <dc:creator><![CDATA[Team Tiger Data]]></dc:creator>
            <pubDate>Tue, 24 Oct 2023 14:12:07 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2023/10/Database-Backups-and-Disaster-Recovery-in-PostgreSQL.png">
            </media:content>
            <content:encoded><![CDATA[<p>When we ask our community about the elementary challenges they face with their PostgreSQL production databases, we often hear about three pain points: query speed, optimizing large tables, and managing database backups. We’ve covered the first two topics in articles about <a href="https://www.timescale.com/learn/is-postgres-partitioning-really-that-hard-introducing-hypertables?ref=timescale.com"><u>partitioning</u></a><a href="https://www.timescale.com/learn/postgresql-performance-tuning-key-parameters?ref=timescale.com"> <u>and fine-tuning your database</u></a>. We’ve also discussed<a href="https://timescale.ghost.io/blog/how-to-reduce-your-postgresql-database-size/"> <u>how to reduce your database size</u></a> to better manage large tables. </p><p>In this guide, we’ll answer some of the most frequently asked questions about database backup and recovery in PostgreSQL. We’ll also discuss how we handle things in the<a href="https://www.timescale.com/?ref=timescale.com"> <u>Timescale platform</u></a>.</p><h2 id="why-are-postgresql-database-backups-important">Why Are PostgreSQL Database Backups Important?</h2><p>When we discuss backup and recovery, we’re referring to a set of processes and protocols established to safeguard your data from loss or corruption and restore it to a usable state:</p><ul><li><strong>Backups</strong> involve creating copies of your data at regular intervals, copies that encapsulate the state of your PostgreSQL database at a specific point in time.&nbsp;</li><li><strong>Recovery</strong>, on the other hand, is the process of restoring data from these backups. If both things are taken care of (i.e., you always have up-to-date backups and a good recovery strategy in place), your PostgreSQL database will be resilient against failure, and you’ll be protected against data loss.&nbsp;&nbsp;</li></ul><p>Effective backup management is not only about creating copies of data. It’s also about ensuring those copies are healthy, accurate, and up-to-date.&nbsp;</p><p>To define a good backup strategy for your production PostgreSQL database, you need to consider several aspects. This includes how frequently you will back up your database, where these backups will be stored, and how often you will audit them.&nbsp;</p><p>But your job isn’t finished once you get up-to-date and healthy database backups. You must also establish an effective disaster recovery protocol. No matter how careful you are, it’s a fact of database management that failures will happen sooner or later. They can be caused by outages, failed upgrades, corrupted hardware, or human error—you name it.</p><p>Your disaster recovery plan must encompass all the steps to restore data as quickly as possible after an incident. This ensures that your database is not just backed up but also recoverable in a timely and efficient manner.</p><h2 id="what-is-the-difference-between-a-physical-backup-and-a-logical-backup-in-postgresql">What Is the Difference Between a Physical Backup and a Logical Backup in PostgreSQL?&nbsp;</h2><p>In PostgreSQL, there are two main types of database backups: physical backups and logical backups.&nbsp;</p><ul><li><strong>Physical backups</strong> capture the database's state at a specific point in time. They involve copying the actual PostgreSQL database data at the file system level.&nbsp;</li><li><strong>Logical backups </strong>involve exporting specific database objects or the entire database into a human-readable SQL file format. A logical backup contains SQL statements to recreate the database objects and insert data.</li></ul><p>Logical backups can be highly granular, allowing for the backup of specific database objects like tables, schemas, or databases. They are also portable and can be used across different database systems or versions, making them popular for migrating small to medium databases. This is your common <code>pg_dump/pg_restore</code>.&nbsp;&nbsp;</p><p>But a main drawback of logical backups is speed. For large databases, the process of restoring from a logical backup is too slow to be useful as a sole disaster recovery mechanism (or migration mechanism, for that matter). Restoring from physical backups is faster than restoring from logical backups, and it’s exact. When putting together a disaster recovery strategy, you’ll be dealing with physical backups.</p><h2 id="a-guide-to-physical-backups-in-postgresql">A Guide to Physical Backups in PostgreSQL</h2><p>Let’s explore some essential concepts around physical backups and how they can help you recover your database in case of failure.&nbsp;</p><h3 id="file-system-backups">File system backups&nbsp;</h3><p>Physical backups are referred to as<a href="https://www.postgresql.org/docs/current/backup-file.html?ref=timescale.com"> <u>file system backups</u></a> in PostgreSQL. This refers to the process of directly copying the directories and files that PostgreSQL uses to store its data, resulting in a complete representation of the database at a specific moment in time.&nbsp;</p><p>Maintaining file system backups is an essential piece of every disaster recovery strategy and imperative in production databases. But putting together a solid disaster recovery plan requires other techniques beyond simply taking “physical” file system backups regularly. That’s especially true if you’re dealing with large production databases.&nbsp;</p><p>Taking physical backups of very large databases can be a rather slow and resource-intensive process that conflicts with other high-priority database tasks, affecting your overall performance. Physical backups are not enough to ensure consistency in case of failure, as they only reflect the database state at the time they were taken. To restore a database in case of failure, you’ll need another mechanism to be able to restore all the transactions that occurred between the moment the last backup was taken and the failure.&nbsp;</p><h3 id="wal-and-continuous-archiving">WAL and continuous archiving&nbsp;</h3><p>WAL stands for <a href="https://www.postgresql.org/docs/current/wal-intro.html?ref=timescale.com"><u>Write-Ahead Logging</u></a>. It’s a protocol that improves the reliability, consistency, and durability of a PostgreSQL database by logging changes before they are written to the actual database files.</p><p>WAL is key for assuring atomicity and durability in PostgreSQL transactions. By writing changes to a log before they're committed to the database, WAL ensures that either all the changes related to a transaction are made or none at all.&nbsp;</p><p>WAL is also essential for disaster recovery since, in the event of a failure, the WAL files can be replayed to bring the database back to a consistent state. The process of regularly saving and storing these WAL records in a secondary storage location, ensuring that they are preserved over the long term, is usually referred to as continuous archiving.&nbsp;</p><p>Keeping WAL records and a recent, healthy physical database backup ensures that your PostgreSQL database can be successfully restored in case of failure. The physical backup will get PostgreSQL to the same state as it was when the backup was taken, which hopefully was not so long ago, and the WAL files will be rolled forward right before things start failing.&nbsp;</p><p>You might be wondering why it’s necessary to keep up-to-date backups if WAL can be replayed. The answer is speed. Replaying WAL during a recovery process is time-consuming, especially when dealing with large datasets with complex transactions. Backups provide a snapshot of the database at a specific point in time, enabling quick restoration up to that point.&nbsp; </p><p>In the optimal recovery scenario, you restore a recent backup (e.g., from the previous day. hen, you replay a WAL recorded post-backup to update the database to its most recent state. You don’t want to rely on WAL to reproduce two weeks’ worth of transactions.</p><h3 id="what-is-point-in-time-recovery-pitr-in-postgresql">What is point-in-time recovery (PITR) in PostgreSQL?</h3><p>Point-in-time recovery refers to restoring a PostgreSQL database to any specific point in time due to direct user input. For example, if I perform an upgrade and, for whatever reason, decide to revert the change, I could choose to recover the database from any day before.&nbsp;</p><p>Behind the scenes, PITR in PostgreSQL is often anchored in WAL. By integrating a backup with the sequential replay of WAL, PostgreSQL can be restored to an exact moment.</p><h2 id="a-guide-to-postgresql-physical-backup-tools">A Guide to PostgreSQL Physical Backup Tools&nbsp;&nbsp;</h2><p>There are multiple tools that help with the creation of physical backups, two of the most popular being <code>pg_basebackup</code> and <code>pgBackRest</code>.&nbsp;</p><h3 id="pgbasebackup">pg_basebackup</h3><p><a href="https://www.postgresql.org/docs/current/app-pgbasebackup.html?ref=timescale.com"><u><code>pg_basebackup</code></u></a> is the native tool offered by PostgreSQL for taking physical backups. It’s straightforward and reliable. It allows you to efficiently copy the data directory and include the WAL files to ensure a consistent and complete backup.</p><p><code>pg_basebackup</code> has important limitations. Taking full backups of a large database can be a lengthy and resource-intensive process. A good workaround to mitigate this is to combine full backups with incremental backups. For example, frequently copying the data that has changed since the last full backup (e.g., once a day) and creating full backups less frequently (e.g., once a week). However, incremental backups are not supported in <code>pg_basebackup</code>.&nbsp;</p><p><code>pg_basebackup</code> also has limited parallelization capabilities, which can further slow down the creation of full backups. The process is mostly manual, requiring developers to closely monitor and manage the backup operations.</p><h3 id="pgbackrest">pgBackRest</h3><p>To address the constraints of <code>pg_basebackup</code>, the PostgreSQL community built tools like <a href="https://pgbackrest.org/?ref=timescale.com"><u><code>pgBackRest</code></u></a>. <code>pgBackRest</code> introduces several important improvements:</p><ul><li>It supports both full and incremental backups.&nbsp;</li><li>It introduces multi-threaded operations, accelerating the backup process for larger databases.&nbsp;</li><li>It validates checksums during the backup process to ensure data integrity, offering an additional layer of security.</li><li>It supports various storage solutions, offering flexibility in how and where backups are stored.&nbsp;</li></ul><p>We use <a href="https://www.tigerdata.com/blog/making-postgresql-backups-100x-faster-via-ebs-snapshots-and-pgbackrest" rel="noreferrer"><code>pgBackRest</code></a> to manage our own backup and restore process in Timescale, although we’ve implemented some hacks to speed up the full backup process (<code>pgBackRest</code> can still be quite slow for creating backups in large databases).</p><h2 id="a-guide-to-logical-backups-in-postgresql">A Guide to Logical Backups in PostgreSQL&nbsp;</h2><p>Logical backups involve exporting data into a human-readable format, such as SQL statements. This type of backup is generally more flexible and portable, making it handy to reproduce a database in another architecture (i.e., for migrations).&nbsp; However, recovering from a logical backup is quite a slow process. That makes them practical only for migrating small to medium PostgreSQL production databases.&nbsp;</p><h3 id="pgdumppgrestore">pg_dump/pg_restore&nbsp;</h3><p>The most common way to create logical backups and restore from them is by using <code>pg_dump/pg_restore</code>:</p><ul><li><strong><code>pg_dump</code> </strong>creates logical backups of a PostgreSQL database. It generates a script file or other formats that contain SQL statements needed to reconstruct the database to the state it was at the backup time. You can use <code>pg_dump</code> to back up an entire database or individual tables, schemas, or other database objects.</li><li><code><strong>pg_restore</strong></code> restores databases from backups created by <code>pg_dump</code>. Just as <code>pg_dump</code> offers granularity in creating backups, <code>pg_restore</code> allows for selective restoration of specific database objects, providing flexibility in the recovery process. While it is typically used with backups created by <code>pg_dump</code>, <code>pg_restore</code> is compatible with other SQL-compliant database systems, enhancing its utility as a migration tool.</li></ul><h2 id="when-should-i-use-logical-backups-and-when-should-i-use-physical-backups-in-postgresql">When Should I Use Logical Backups, and When Should I Use Physical Backups in PostgreSQL?&nbsp;</h2><p><strong>Logical backups via <code>pg_dump/pg_restore</code> are mostly useful for creating testing databases or for database migrations. </strong>In terms of migrations, if you’re operating a production database, we only recommend going the <code>pg_dump/pg_restore</code> route if your database is small (&lt;100&nbsp;GB).</p><p>Migrating larger and more complex databases via <code>pg_dump/pg_restore</code> might take your production database offline for too long. Other migration strategies, like the dual-write and backfill method, can avoid this downtime.&nbsp;</p><p><strong>Physical backups are mostly used for disaster recovery and data archiving. </strong>If you’re operating a production database, you’ll want to maintain up-to-date physical backups and WAL to recover your database when failure occurs. If your industry requires you to keep copies of your data for a certain period of time due to regulations, physical backups will be the way to go.&nbsp;</p><p>In production applications, you’ll most likely use a combination of logical and physical backups. For disaster recovery, physical backups will be your foundational line of defense, but logical backups can serve as additional assurance (redundancy is a good thing). For migrating large databases, you’ll most likely use a staged approach, <a href="https://docs.timescale.com/migrate/latest/dual-write-and-backfill/dual-write-from-postgres/?ref=timescale.com"><u>combining logical backups with other tactics</u></a>, and so on.</p><h2 id="what-about-replicas-in-postgresql">What About Replicas in PostgreSQL?&nbsp;</h2><p><a href="https://timescale.ghost.io/blog/how-high-availability-works-in-our-cloud-database/"><u>Replicas</u></a> are continuously updated mirrors of the primary database, capturing every transaction and modification almost instantaneously. They're not the same as backups, but their usefulness in disaster recovery is indisputable. In the event of a failure, you can promote replicas to serve as the primary database, ensuring minimal downtime while you restore the damaged database.&nbsp;Building a high-availability replica and failover mechanism generally involves the following steps:&nbsp;</p><ul><li>The primary database should be configured to allow connections from replicas.&nbsp;</li><li>Physical backups of the primary should be regularly created, e.g., using <code>pgBackRest</code>.&nbsp;</li><li>WAL capturing all changes made to the database should be shipped to the replica, for example, via streaming replication. Replication can be synchronous, where each transaction is confirmed only when both primary and replica have received it, or asynchronous, where transactions are confirmed without waiting for the replica.</li><li>Configurations for automatic failover should be established to promote a replica to become the primary database in case of a failure.</li><li>Tools and scripts should be used to monitor replication lag and ensure the replica is up-to-date.</li></ul><p>This setup can be considerably complex to maintain. Most providers of managed PostgreSQL databases, <a href="https://docs.timescale.com/use-timescale/latest/ha-replicas/?ref=timescale.com"><u>including Timescale</u></a>, offer fully managed replicas as one of their services. This simplifies running highly available databases.</p><h2 id="a-guide-to-database-backups-and-disaster-recovery-with-timescale">A Guide to Database Backups and Disaster Recovery with Timescale?&nbsp;</h2><p>The<a href="https://console.cloud.timescale.com/signup?ref=timescale.com"> <u>Timescale platform</u></a> allows our customers to create fully managed PostgreSQL and TimescaleDB databases. That means we take care of the backup and disaster recovery process for them. Let’s run through how the platform handles backups, replication, upgrades, and restores.</p><h3 id="how-do-backups-work-in-timescale">How do backups work in Timescale?&nbsp;</h3><p>Backups in Timescale are fully automated. Using <code>pgBackRest</code> under the hood, Timescale automatically creates one full backup every week and incremental backups every day.&nbsp;</p><p>Timescale also keeps WAL files of any changes made to the database. This WAL can be replayed in the event of a failure to reproduce any transactions not captured by the last daily backup. For example, it can replay the changes made to your database during the last few hours. Timescale stores the two most recent full backups and WAL in<a href="https://aws.amazon.com/s3/?ref=timescale.com"> <u>S3</u></a> volumes.&nbsp;</p><p>On top of the full and incremental backups taken by <code>pgBackRest</code>,<a href="https://timescale.ghost.io/blog/making-postgresql-backups-100x-faster-via-ebs-snapshots-and-pgbackrest/"> <u>Timescale also takes EBS snapshots daily</u></a>. EBS snapshots create copies of the storage volume that can be restored, effectively making it a backup. They are significantly faster than taking full backups via pgBackRest (about 100x faster).&nbsp;</p><p>By taking EBS snapshots daily (on top of the weekly full backups by <code>pgBackRest</code>), we introduce an extra layer of redundancy, ensuring that we always have a fresh snapshot that we can quickly restore if the customer experiences a critical failure that requires recovery from a full backup.&nbsp;</p><h3 id="disaster-recovery-in-timescale-what-happens-if-my-database-fails">Disaster recovery in Timescale: What happens if my database fails?&nbsp;</h3><p>Timescale is built on AWS with decoupled compute and storage, something that makes the platform especially resilient against failures. There are two classes of failures that Timescale handles distinctly: compute and storage failures.</p><h4 id="how-timescale-handles-compute-failures">How Timescale handles compute failures&nbsp;</h4><p>Compute failures are more frequent than storage failures, as they can be caused by things like unoptimized queries or other issues that result in a maxed-out CPU. To improve uptime for the customer, Timescale has developed a methodology that makes the platform recover extremely quickly from compute failures. We call this technique<a href="https://docs.timescale.com/use-timescale/latest/ha-replicas/high-availability/?ref=timescale.com"> <u>rapid recovery</u></a>.&nbsp;</p><p>Timescale decouples the compute and storage nodes. So, if the compute node fails, Timescale automatically spins up a new compute node, attaching the undamaged storage unit to it. Any WAL that was in memory then replays.&nbsp;</p><p>The length of this recovery process depends on how much WAL needs replaying. Typically, it completes in less than thirty seconds. Under the hood, this entire process is automated via Kubernetes.&nbsp;</p><h3 id="how-timescale-handles-storage-failures">How Timescale handles storage failures&nbsp;</h3><p>Storage failures are much less common than compute failures, but when they happen, they’re more severe. Having a<a href="https://docs.timescale.com/use-timescale/latest/ha-replicas/high-availability/?ref=timescale.com"> <u>high-availability replica</u></a> can be a lifesaver in this circumstance; while your storage is being restored, instead of experiencing downtime, your replica will automatically take over.&nbsp;</p><p>To automatically restore your damaged storage, Timescale makes use of the backups it has on storage, reproducing WAL since the last incremental backup. The figure below illustrates the process:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://timescale.ghost.io/blog/content/images/2023/10/Database-Backups-in-PostgreSQL_Timescale-backups.png" class="kg-image" alt="Recovery from backup in Timescale " loading="lazy" width="1025" height="658" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2023/10/Database-Backups-in-PostgreSQL_Timescale-backups.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2023/10/Database-Backups-in-PostgreSQL_Timescale-backups.png 1000w, https://timescale.ghost.io/blog/content/images/2023/10/Database-Backups-in-PostgreSQL_Timescale-backups.png 1025w" sizes="(min-width: 720px) 720px"><figcaption><i><em class="italic" style="white-space: pre-wrap;">Recovery from backup in Timescale&nbsp;</em></i></figcaption></figure><h3 id="how-do-replicas-work-in-timescale-and-how-do-they-help-with-recovery">How do replicas work in Timescale, and how do they help with recovery?&nbsp;</h3><p>In Timescale, you can create two types of replicas:</p><ul><li><strong>Read replicas </strong>are useful for read scaling. They’re used to liberate load from your primary database in read-heavy applications, for example, if you’re powering a BI tool or doing frequent reporting. Read replicas are read-only, and you can create as many as you need.</li><li><strong>High-availability replicas</strong> are exact, up-to-date copies of your database that automatically take over operations if your primary becomes unavailable.&nbsp;</li></ul><p>We’ve been talking about the importance of backups and disaster recovery. There’s a related concept that’s also important to consider: the concept of <strong>high availability</strong>. In broad terms, a “highly available” database describes a database that’s able to stay running without significant interruption (perhaps no more than a few seconds) even in case of failure.&nbsp;</p><p>The process of recovering a large database from backup might take a while, even when you’ve done everything right. That’s why it’s handy to have a replica running. Instead of waiting for the backup and restore process to finish, when your primary database fails, your connection will automatically failover to the replica. That saves your own users any major downtime.</p><p>Failover also helps remove downtime for common operations that would normally cause a service to reset, like upgrades. In these cases, Timescale makes changes to each node sequentially so that there is always a node available.&nbsp;And speaking of upgrades…&nbsp;</p><h3 id="how-are-upgrades-handled-in-timescale">How are upgrades handled in Timescale?&nbsp;</h3><p>In Timescale, you’re running PostgreSQL databases with the TimescaleDB extension enabled. Therefore, during your Timescale experience, you’ll most likely experience three different types of upgrades:&nbsp;</p><h4 id="timescaledb-upgrades">TimescaleDB upgrades</h4><p>These refer to upgrades between TimescaleDB versions, e.g., from TimescaleDB 2.11 to TimescaleDB 2.12. You don’t have to worry about these. They’re backward compatible, they require no downtime, and they will happen automatically during your maintenance window. Your Timescale services always run the latest available TimescaleDB version, so you can enjoy all the new features we ship.&nbsp;</p><h4 id="postgresql-minor-version-upgrades">PostgreSQL minor version upgrades</h4><p>We always run the latest available minor version of PostgreSQL in Timescale as well, mostly for security reasons. These minor updates may contain security patches, data corruption problems, and fixes to frequent bugs.&nbsp;</p><p>Timescale automatically handles these upgrades during your maintenance window, and they are also backward compatible. However, they require a service restart, which could cause some downtime (30 seconds to a few minutes) if you don’t have a replica. We alert you ahead of time about these, so you can set your maintenance window to a low traffic time (e.g., middle of the night) to minimize consequences.&nbsp;</p><h4 id="postgresql-major-version-upgrades">PostgreSQL major version upgrades<strong>&nbsp;</strong></h4><p>These refer to upgrading, for example, from PostgreSQL 15 to 16. These upgrades are different and more serious since they’re often not backward compatible.</p><p>&nbsp;We can’t run these upgrades for you, as this might cause issues on your application. Besides, the downtime associated with upgrading major versions of PostgreSQL can be more severe (e.g., 20 minutes). Unfortunately, in this particular case, high-availability replicas can’t help you avoid downtime.</p><p>Major PostgreSQL upgrades are always a significant lift. Timescale has some tools that will make the transition smoother. For example, you can initiate the upgrade process in a particular database <a href="https://docs.timescale.com/self-hosted/latest/upgrades/upgrade-pg/?ref=timescale.com#upgrade-postgresql"><u>with a click of a button</u></a> Before doing so, you can test your upgrade in a<a href="https://docs.timescale.com/use-timescale/latest/services/service-management/?ref=timescale.com#forking-a-service"> <u>copy of your database</u></a> to make sure nothing will break and have an accurate idea of how much downtime the upgrade will require.<a href="https://timescale.ghost.io/blog/read-before-you-upgrade-best-practices-for-choosing-your-postgresql-version/"> <u>Read this article for more information.&nbsp;</u></a></p><h3 id="can-i-do-pitr-in-timescale-ie-restore-my-database-to-a-previous-state-at-my-own-will">Can I do PITR in Timescale, i.e., restore my database to a previous state at my own will?&nbsp;</h3><p>Yes, you can! All Timescale services <a href="https://docs.timescale.com/use-timescale/latest/backup-restore/point-in-time-recovery/?ref=timescale.com"><u>allow PITR</u></a> to any point in the last three days. If you're using our<a href="https://www.timescale.com/enterprise?ref=timescale.com"> <u>Enterprise plan</u></a>, this timespan expands up to 14 days.</p><h2 id="stress-free-postgresql-backups">Stress-Free PostgreSQL Backups</h2><p>Having a solid backup and recovery strategy is top of mind for every PostgreSQL user. We hope this introductory article answers some of your questions; if you’d like to see more articles diving deeper into this topic, <a href="https://x.com/TimescaleDB?s=20&amp;ref=timescale.com"><u>tell us on Twitter/X</u></a>. </p><p>If you prefer not to worry about maintaining your backups and taking care of recovering your database when things fail, <a href="https://console.cloud.timescale.com/signup?ref=timescale.com"><u>try Timescale</u></a>, our managed PostgreSQL platform. It takes care of all things backups so you can focus on what matters (building and running your application) while experiencing <a href="https://timescale.ghost.io/blog/postgresql-timescaledb-1000x-faster-queries-90-data-compression-and-much-more/"><u>the performance boost of TimescaleDB</u></a>. You can start a free trial <a href="https://console.cloud.timescale.com/signup?ref=timescale.com"><u>here</u></a> (no credit card required).&nbsp;</p><h3 id=""></h3>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 2023 State of PostgreSQL Survey Is Now Open!]]></title>
            <description><![CDATA[The 2023 State of PostgreSQL survey is now live! Help us learn more about this community, and check out last year’s main highlights.]]></description>
            <link>https://www.tigerdata.com/blog/the-2023-state-of-postgresql-survey-is-now-open</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/the-2023-state-of-postgresql-survey-is-now-open</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <category><![CDATA[State of PostgreSQL]]></category>
            <dc:creator><![CDATA[Team Tiger Data]]></dc:creator>
            <pubDate>Tue, 01 Aug 2023 12:58:32 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2023/07/2023-SOP-blog-hero.png">
            </media:content>
            <content:encoded><![CDATA[<p>Almost half (45.55 %) of the <a href="https://survey.stackoverflow.co/2023/#databases">2023 Stack Overflow Developer Survey</a> respondents who answered the question about their favorite database (76,634 in total) chose PostgreSQL as the most popular one. This is a testament to the quality, reliability, and performance of PostgreSQL, as well as the vibrant and diverse community that supports it.</p><p>As proud members of the PostgreSQL community, we want to continue giving back to this awesome group of data techies. We’re happy to announce that the 2023 State of PostgreSQL survey is officially live, and we are excited to hear once again from PostgreSQL users worldwide.</p><p>Over the years, we have learned a lot about the community. In 2019, we noticed that while PostgreSQL is a popular choice among organizations, <a href="https://drive.google.com/file/d/1VGWN0oCXRxX-qOiq4T-QQwu89Id07dBZ/view?usp=sharing">81 % of you use PostgreSQL for personal projects</a>. In 2021, <a href="https://www.timescale.com/state-of-postgres/2021/">the community shared that the most frequently used extension is PostGIS</a>. Last year, <a href="https://www.timescale.com/state-of-postgres/2022">17 % of the respondents said they contributed to PostgreSQL at least once</a>.</p><p>This year, we want to know how these practices evolved, and we will explore the two magical letters of the hour—AI. We want to learn what AI tools the PostgreSQL community uses and if the AI workloads are already part of personal and work projects.</p><p>The survey results and anonymized raw data will be published in a report that will be available for free to everyone. The report will provide valuable insights into the PostgreSQL ecosystem and help us understand how we can collectively make PostgreSQL better.</p><p><br>For now, to whet the appetite for the 2023 report, read the highlights of last year’s findings. To download the full 2022 report, head over to <a href="https://www.timescale.com/state-of-postgres/2022/">https://www.timescale.com/state-of-postgres/2022/</a></p>
<!--kg-card-begin: html-->
<div class="gray-cta-box">
   <div class="gray-cta-box__text">
       <p><strong>The survey is open until September 15, 2023.</strong></p>
       <br>
       <p>So what are you waiting for? Take the survey now and share your voice with the PostgreSQL community!</p>
       
    </div>
    <a class="gray-cta-box__button" href="https://timescale.typeform.com/state-of-pg-23" target="_blank">
        <p><strong>Take the survey</strong></p>
    </a>
</div>
<!--kg-card-end: html-->
<h2 id="the-state-of-postgresql-in-2022">The State of PostgreSQL in 2022</h2><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2023/07/2023-07-25-Infographic-pdf.jpg" class="kg-image" alt="" loading="lazy" width="2000" height="4924" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2023/07/2023-07-25-Infographic-pdf.jpg 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2023/07/2023-07-25-Infographic-pdf.jpg 1000w, https://timescale.ghost.io/blog/content/images/size/w1600/2023/07/2023-07-25-Infographic-pdf.jpg 1600w, https://timescale.ghost.io/blog/content/images/2023/07/2023-07-25-Infographic-pdf.jpg 2000w" sizes="(min-width: 720px) 720px"></figure><h3 id="postgresqls-popularity-is-increasing">PostgreSQL's popularity is increasing</h3><p>The number of PostgreSQL newbies using the database for less than a year has grown from 6.1&nbsp;% in 2021 to 6.4&nbsp;% in 2022.</p><h3 id="reasons-for-choosing-postgresql-over-other-databases">Reasons for choosing PostgreSQL over other databases</h3><p>Open-source, reliability, and extensions are the main reasons PostgreSQL users selected in 2022. Interestingly, users´ years of experience were directly related to their answers. “Reliability” was the number one reason to choose PostgreSQL among those who have been using the database for 11-15 years, while “open source” was primarily pointed out by users with up to five years of experience.</p><h3 id="postgresql-usage-is-growing">PostgreSQL usage is growing</h3><p>Small and medium businesses (0-50 employees) use PostgreSQL a lot more than they did one year ago. The result is on par with a broader trend: PostgreSQL’s usage is growing, with the majority of respondents—55 %—saying that they have increased their usage of the database.</p><h3 id="postgresql-users-%E2%99%A5-documentation">PostgreSQL users ♥ documentation</h3><p>The majority of respondents (76.1 %) answered that technical documentation is their preferred way of learning about PostgreSQL, followed by long-form blog posts (51.5 %) and short-form blog posts (43.3 %). But the new generation of PostgreSQL enjoys learning slightly differently: users with less than five years of PostgreSQL experience gravitate toward video as their first option.</p><h3 id="postgresql-users-increasingly-use-dbaas-providers-to-deploy-postgresql">PostgreSQL users increasingly use DBaaS providers to deploy PostgreSQL</h3><p>The trend that we first saw in 2021 continues in 2022. Fewer PostgreSQL users reported self-managing the database compared to previous years. More respondents are using a managed PostgreSQL service to deploy the database.<br></p><p>Many thanks to everyone who took the time to fill in the 2023 survey. If you have not done that yet, grab a cup or glass of your favorite beverage and <a href="https://timescale.typeform.com/state-of-pg-23?utm_source=xxxxx&amp;utm_medium=xxxxx&amp;utm_campaign=xxxxx&amp;utm_term=xxxxx&amp;utm_content=xxxxx">share your experience with PostgreSQL</a>.<br></p><p>Help us make the survey more representative. Share this far and wide! Post it in the company chat. Share it on social media.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 2022 State of PostgreSQL Survey Is Now Open!]]></title>
            <description><![CDATA[We’re surveying the PostgreSQL community for the third year to learn more about how developers use and deploy the open-source database and surface collective trends and opportunities.]]></description>
            <link>https://www.tigerdata.com/blog/the-2022-state-of-postgresql-survey-is-now-open</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/the-2022-state-of-postgresql-survey-is-now-open</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <category><![CDATA[State of PostgreSQL]]></category>
            <dc:creator><![CDATA[Team Tiger Data]]></dc:creator>
            <pubDate>Mon, 06 Jun 2022 15:05:46 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2022/06/SoP-2022-Lockup.png">
            </media:content>
            <content:encoded><![CDATA[<p>Our love for PostgreSQL runs deep. <a href="http://www.timescale.com">We built our products on PostgreSQL</a>, <a href="https://timescale.ghost.io/blog/the-future-of-community-in-light-of-babelfish/">are proud members of the PostgreSQL community,</a> <a href="https://www.youtube.com/playlist?list=PLsceB9ac9MHRnmNZrCn_TWkUrCBCPR3mc">and wouldn’t exist without it and the extensibility it provides</a>.</p><p>In 2019, Timescale launched the first <em>State of PostgreSQL report</em>, advancing our desire to provide greater insights into the specificities and features useful to the PostgreSQL community. Following a one-year hiatus due to the pandemic and after the 2021 survey submissions, <a href="https://timescale.ghost.io/blog/2021-state-of-postgres-survey-results/">we released the 2021 report</a>.</p><p>We are pleased to announce that the 2022 survey is now open for submissions! We are keen to learn more about how you use PostgreSQL for work and personal projects, how you deploy it, and how we can collectively improve it.</p><div class="kg-card kg-callout-card kg-callout-card-yellow"><div class="kg-callout-emoji">✨</div><div class="kg-callout-text">Help us give back to this awesome group: answer survey questions and share with other PostgreSQL users. We are excited to hear your thoughts and spark a conversation that will keep us moving forward and building better things together. 🙌 <b><strong style="white-space: pre-wrap;">We will share our report (as well as give you full and free access to the survey’s anonymized raw data) in July. </strong></b>Thank you for being a part of the community!</div></div>
<!--kg-card-begin: html-->
<div class="gray-cta-box">
    <a style="width: auto; display: flex; justify-content: center; align-items: center;" class="gray-cta-box__button" href="https://timescale.typeform.com/state-of-pg-22" target="_blank">
        <p><strong>Take the 2022 State of PostgreSQL survey </strong></p>
    </a>
</div>
<!--kg-card-end: html-->
<h2 id="the-state-of-postgresql-in-2019-and-2021">The State of PostgreSQL in 2019 and 2021</h2><p>So, what have we learned from the two years we sent out our survey? You will find the few key findings here, but <a href="https://drive.google.com/drive/folders/14elckaNv7FLKyWhzp3JKd3tH6PvI9F45">check out our reports</a> for a full picture. From the most used programming languages to whether developers use PostgreSQL for work or personal projects (or both!), favorite features, and qualitative answers, <em>The State of PostgreSQL </em>paints an accurate and informative portrait of this great community. </p><h3 id="sample">Sample </h3><p>Five hundred developers answered our survey in 2019, and 445 participated two years later. In both years, respondents mainly were software developers/engineers, software architects, and database administrators from the EMEA (Europe, Middle East, Africa) region.</p><h3 id="postgresql-usage-is-growing">PostgreSQL usage is growing</h3><p>Around 67 % of developers said they were using the database “more” or “a lot more” in 2019, compared to 52 % in 2021. However, the number of participants using it “about the same” increased from 31 % in 2019 to 43 % in 2021.</p><h3 id="use-cases-building-applications-at-the-top">Use cases: Building applications at the top</h3><p>Building applications is the primary use case for PostgreSQL developers, totaling 70 % in 2019 and 67 % in 2021.</p><h3 id="community-contribution-is-increasing">Community contribution is increasing</h3><p>Code contributions are crucial to open-source software development, and PostgreSQL successfully mobilizes its community. In 2019, about 9 % of respondents contributed their code to the database, and 11 % claimed to do it two years later.</p><h3 id="why-do-you-use-postgresql">Why do you use PostgreSQL?</h3><p>In both surveys, developers said that reliability and SQL were the main reasons they use PostgreSQL.</p><h3 id="the-way-developers-deploy-postgresql-is-changing">The way developers deploy PostgreSQL is changing</h3><p>In 2019, 51 % of respondents deployed PostgreSQL using AWS, while 46 % relied on a self-managed data center. In 2021, the self-managed option took the lead, with 36.4 % deploying on-site, 35.3 % from a private data center, and 32.8 % on a public cloud. In 2021, AWS was the leading cloud provider, with 46.1 % of the answers.</p><p><em>If you’ve got any feedback or questions on The State of PostgreSQL, let us know on </em><a href="https://twitter.com/TimescaleDB"><em>Twitter</em></a><em> or join Timescale’s Community </em><a href="http://timescaledb.slack.com/"><em>Slack</em></a><em> and message us in </em><a href="https://timescaledb.slack.com/archives/C4GT3N90X"><em>#general</em></a><em>.</em><br><br><br></p>]]></content:encoded>
        </item>
    </channel>
</rss>