<?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:52:13 GMT</lastBuildDate>
        <atom:link href="https://www.tigerdata.com/blog" rel="self" type="application/rss+xml"/>
        <ttl>60</ttl>
        <item>
            <title><![CDATA[How to Test Your PostgreSQL Connection]]></title>
            <description><![CDATA[Testing your PostgreSQL connection is a challenge faced by many developers. Learn how to do it.
]]></description>
            <link>https://www.tigerdata.com/blog/how-to-test-your-postgresql-connection</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/how-to-test-your-postgresql-connection</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <category><![CDATA[PostgreSQL Tips]]></category>
            <dc:creator><![CDATA[Semab Tariq]]></dc:creator>
            <pubDate>Mon, 20 Jan 2025 14:00:53 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2025/01/How-to-Test-Your-PostgreSQL-Connection.png">
            </media:content>
            <content:encoded><![CDATA[<p>Let’s imagine a few scenarios:</p><ul><li>You are asked to build a monitoring system to check if a PostgreSQL instance is running smoothly. You need to check its status every second, but your organization doesn’t want to use third-party tools due to concerns about sharing sensitive credentials.</li><li>You have just installed PostgreSQL and want to make sure it’s ready to accept connections.</li><li>Your application suddenly stops connecting to the database, and you need to manually test the connection to figure out what’s wrong.</li><li>You have deployed a new version of your application. Before sending live traffic to it, you want to confirm that the connection to the PostgreSQL server is stable.</li></ul><p>In all these scenarios, the first question that might come to mind is:<strong> How can I check if PostgreSQL is running and test the connection?</strong></p><p>Don’t worry! You are not alone! 😊 In today’s blog, I’ll guide you through various methods to test a PostgreSQL connection, which will help you tackle these and other similar scenarios.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2025/01/How-to-Test-Your-PostgreSQL-Connection-1.png" class="kg-image" alt="" loading="lazy" width="2000" height="885" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2025/01/How-to-Test-Your-PostgreSQL-Connection-1.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2025/01/How-to-Test-Your-PostgreSQL-Connection-1.png 1000w, https://timescale.ghost.io/blog/content/images/size/w1600/2025/01/How-to-Test-Your-PostgreSQL-Connection-1.png 1600w, https://timescale.ghost.io/blog/content/images/size/w2400/2025/01/How-to-Test-Your-PostgreSQL-Connection-1.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>(If you have not done so already, install PostgreSQL by following the community guidelines for your preferred operating system <a href="https://www.postgresql.org/download/"><u>here</u></a>.)</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">✨</div><div class="kg-callout-text">Learn how to troubleshoot and <a href="https://www.timescale.com/blog/5-common-connection-errors-in-postgresql-and-how-to-solve-them" rel="noreferrer">fix five common PostgreSQL connection errors</a>.</div></div><h2 id="how-to-verify-if-postgresql-is-ready-to-accept-connections">How to Verify if PostgreSQL Is Ready to Accept Connections</h2><p>There are several ways to check your PostgreSQL connections. To make things clearer, I have divided them into three sections:</p><ul><li>PostgreSQL internals: methods that don’t rely on third-party tools or software</li><li>External tools: tools outside of PostgreSQL</li><li>Programming languages: using code to check connections</li></ul><p>Let’s explore them one by one.</p><h2 id="postgresql-internals-methods-without-third-party-tools">PostgreSQL Internals: Methods Without Third-Party Tools</h2><p>Let’s explore the different ways PostgreSQL can help determine if it is ready and available for new connections.</p><h3 id="pgisready"><code>pg_isready</code></h3><p>PostgreSQL includes a built-in utility called <code>pg_isready</code>, which is available after installation. This tool is the most commonly used to check if PostgreSQL is ready to accept connections.</p><h4 id="usage">Usage</h4><pre><code class="language-SQL">pg_isready -h &lt;HOST_NAME&gt; -p &lt;PORT_NUMBER&gt; -d &lt;DATABASE_NAME&gt; -U &lt;DATABASE_USER&gt;</code></pre><p>To use <code>pg_isready</code>PostgreSQL on port 5430 is not responding, specify the required values based on your PostgreSQL installation:</p><ul><li><code>&lt;HOST_NAME&gt;</code>: This can be <code>localhost</code> or the public or private IP address of the server where PostgreSQL is installed.</li><li><code>&lt;PORT_NUMBER&gt;</code>: The port number on which PostgreSQL is listening (default is 5432).</li><li><code>&lt;DATABASE_NAME&gt;</code>: The name of the database you want to check.</li><li><code>&lt;DATABASE_USER&gt;</code>: The username for the database connection.</li></ul><p>Once you have replaced the placeholders with the appropriate values, execute the command to check the PostgreSQL server’s availability.</p><h4 id="output">Output&nbsp;</h4><p>The first command shows that PostgreSQL on port 5434 is accepting connections. The second command indicates that PostgreSQL on port 5430 is not responding, meaning it’s either not running or unreachable.</p><pre><code>/Library/PostgreSQL/15/bin/pg_isready -h localhost -p 5434 -d postgres -U postgres

localhost:5434 - accepting connections

/Library/PostgreSQL/15/bin/pg_isready -h localhost -p 5430 -d postgres -U postgres

localhost:5430 - no response</code></pre><h3 id="psql%E2%80%94postgresql-interactive-terminal"><code>psql</code>—PostgreSQL interactive terminal</h3><p>Another common way to check if PostgreSQL is ready to accept connections is by using the <code>psql</code> command-line utility, which is also included during the PostgreSQL installation. It allows you to attempt a connection to the server and provides feedback on whether the server is available.</p><h4 id="usage-1">Usage&nbsp;</h4><pre><code>psql -h &lt;HOST_NAME&gt; -p &lt;PORT_NUMBER&gt; -d &lt;DATABASE_NAME&gt; -U &lt;DATABASE_USER&gt;</code></pre><p>Similar to <code>pg_isready</code>, to use <code>psql</code>, specify the required values based on your PostgreSQL installation.</p><p><strong>Note</strong>: After executing the above command with the correct installation parameters, you will be prompted to enter the password for the user specified with the <code>-U</code> switch. If the service is running, <code>psql</code> will then take you to the PostgreSQL terminal. However, if the service is down, you won't be prompted for the password, which indicates that the service is unavailable or the credentials are incorrect.</p><h4 id="output-1">Output</h4><p>If the connection is successful, you will see a message similar to this, indicating that you have connected to the database:</p><pre><code>/Library/PostgreSQL/15/bin/psql -h localhost -p 5434 -d postgres -U postgres
Password for user 
postgres:psql (15.4, server 13.18)
Type "help" for help.

postgres=# \q</code></pre><p>If there’s an issue connecting, an error message will appear, such as:</p><pre><code>/Library/PostgreSQL/15/bin/psql -h localhost -p 5430 -d postgres -U postgres
psql: error: connection to server at "localhost" (::1), port 5430 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 5430 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?</code></pre><p>This helps you determine whether the PostgreSQL server is accepting connections and if the specified credentials are correct.</p><p><strong>Note</strong>: Both utilities mentioned above are available on all operating systems in the <code>&lt;POSTGRESQL_INSTALLATION_DIRECTORY&gt;/bin</code> directory.</p><h3 id="listenaddress-parameter-inside-postgresqlconf-file"><code>listen_address</code> parameter inside postgresql.conf file&nbsp;</h3><p>If you want to check whether your PostgreSQL server can accept connections from outside the <code>localhost</code>, you need to verify the <code>listen_addresses</code> parameter in the postgresql.conf file.&nbsp;</p><p>This parameter defines the IP addresses that PostgreSQL listens to for incoming connections.</p><p>To check and modify the <code>listen_addresses</code> parameter, open the postgresql.conf file, usually located in the PostgreSQL data directory. Look for the <code>listen_addresses</code> line and verify or update its value.</p><pre><code>isten_addresses = '&lt;ADDRESS&gt;'</code></pre><p><code>&lt;ADDRESS&gt;</code>: This can be set to the following parameters:</p><ul><li><code>'localhost'</code>: PostgreSQL will only accept connections from the local machine.</li><li>Specific IP addresses (e.g., <code>'192.168.1.100'</code>): PostgreSQL will accept connections from the specified IP address.</li><li><code>'*'</code>: PostgreSQL will accept connections from any IP address.</li></ul><p><strong>Note</strong>: After updating the <code>listen_address</code> parameter, a restart is required for the PostgreSQL server.</p><h2 id="external-tools-tools-outside-of-postgresql">External Tools: Tools Outside of PostgreSQL</h2><p>We have covered some built-in methods within PostgreSQL for checking database connections. Now, let’s shift our focus to external tools and see how they can help achieve the same purpose.</p><h3 id="service">Service</h3><p>We can determine if PostgreSQL is running and accepting connections by checking the status of the PostgreSQL service itself. If the service is active (running), PostgreSQL is operational and ready to accept connections; if it’s stopped or disabled, the database won’t be available for connections.</p><h4 id="macos">macOS</h4><p>On macOS, you can use the <code>launchctl</code> command to check the status of PostgreSQL services.&nbsp;</p><pre><code>sudo launchctl list | grep postgres
321	0	postgresql-13
322	0	postgresql-15
324	0	postgresql-16</code></pre><p>In the example above</p><ul><li>Three PostgreSQL services (versions 13, 15, and 16) are running.</li><li>The 0 in the second column confirms each service is active and ready to accept connections.</li><li>The first column (321, 322, 324) represents the respective process IDs (PIDs) for these services.</li></ul><h4 id="linux">Linux&nbsp;</h4><p>On Linux, the <code>service</code> utility can be used to check if PostgreSQL is running and ready to accept new connections.&nbsp;</p><p>Here's an example command and its output:</p><pre><code>$ sudo service &lt;PostgreSQL_SERVICE_NAME&gt; status</code></pre><p>Here, mention your PostgreSQL service name:&nbsp;</p><pre><code>● postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: enabled)
Active: active (exited) since Tue 2024-12-31 15:32:48 UTC; 5min ago
Main PID: 2926 (code=exited, status=0/SUCCESS)
CPU: 2ms

Dec 31 15:32:48 ip-172-31-17-193 systemd[1]: Starting postgresql.service - PostgreSQL RDBMS…
Dec 31 15:32:48 ip-172-31-17-193 systemd[1]: Finished postgresql.service - PostgreSQL RDBMS.</code></pre><p>In the output above:</p><ul><li>The Active: The active (exited) line confirms that the PostgreSQL service is running.</li><li>The Main PID: 2926 indicates the process ID associated with the service.</li><li>The timestamps and logs show when the service was started and confirm that it was successfully initialized.</li></ul><p>This command is useful for determining whether PostgreSQL is operational and ready to handle incoming connections. If the service is inactive, you may need to troubleshoot or restart it.</p><h4 id="windows">Windows</h4><p>On Windows, you can use the Windows Service Manager to check if your PostgreSQL service is running. Follow these steps:</p><p>Open the Service Manager.</p><ul><li>Press Win + R to open the Run dialog.</li><li>Type <code>services.msc</code> and hit Enter.</li></ul><p>Locate the PostgreSQL service:</p><ul><li>In the Services window, scroll through the list to find the service named PostgreSQL or a similar name (e.g., postgresql-x64-15).</li></ul><p>Check the service status:</p><ul><li>Look under the Status column for the PostgreSQL service.</li><li>If the status shows Running, it means the PostgreSQL service is up and accepting connections.</li></ul><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2025/01/How-to-test-your-postgres-connection_windows.png" class="kg-image" alt="" loading="lazy" width="1248" height="657" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2025/01/How-to-test-your-postgres-connection_windows.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2025/01/How-to-test-your-postgres-connection_windows.png 1000w, https://timescale.ghost.io/blog/content/images/2025/01/How-to-test-your-postgres-connection_windows.png 1248w" sizes="(min-width: 720px) 720px"></figure><p>In the diagram mentioned above, you can see PostgreSQL 17 is running, which means it is ready to accept the connections.</p><h3 id="telnet">Telnet&nbsp;</h3><p>You can use telnet to check if PostgreSQL is running and accepting connections on a specific port. Simply run <code>telnet &lt;HOSTNAME&gt; &lt;PORT&gt;</code> to verify the connection status.</p><pre><code>$ telnet localhost 5432
Trying 127.0.0.1…
Connected to localhost.

$ telnet localhost 5434
Trying 127.0.0.1…
telnet: Unable to connect to remote host: Connection refused</code></pre><p>The output shows the following:</p><ul><li>For localhost 5432: The connection was successful, indicating that a service (likely PostgreSQL) is actively listening on port 5432 and accepting connections.</li><li>For localhost 5434: The connection attempt was refused, meaning there is no service (like PostgreSQL) listening on port 5434, or the service is not running.</li></ul><h3 id="netcat">Netcat</h3><p>Similar to <code>telnet</code>, you can use nc (Netcat) to check if PostgreSQL is running and accepting connections on a specific port.&nbsp;</p><pre><code>nc -zv &lt;HOSTNAME&gt; &lt;PORT&gt;</code></pre><p>After ingesting IP and Port:</p><pre><code>nc -zv localhost 5432
Connection to localhost (127.0.0.1) 5432 port [tcp/postgresql] succeeded!</code></pre><p>This indicates that the connection to PostgreSQL on port 5432 is successful.</p><h3 id="ps"><code>ps</code></h3><p>You can use the <code>ps</code> command to check if PostgreSQL is running by listing the active processes.&nbsp;</p><pre><code>$ ps -ef | grep -i postgres
postgres 3769 1 0 16:13 ? 00:00:00 /usr/lib/postgresql/17/bin/postgres -D /var/lib/postgresql/17/main -c config_file=/etc/postgresql/17/main/postgresql.conf
postgres 3770 3769 0 16:13 ? 00:00:00 postgres: 17/main: checkpointer
postgres 3771 3769 0 16:13 ? 00:00:00 postgres: 17/main: background writer
postgres 3773 3769 0 16:13 ? 00:00:00 postgres: 17/main: walwriter
postgres 3774 3769 0 16:13 ? 00:00:00 postgres: 17/main: autovacuum launcher
postgres 3775 3769 0 16:13 ? 00:00:00 postgres: 17/main: logical replication launcher</code></pre><p>The presence of multiple PostgreSQL processes, such as the <code>checkpointer</code>, <code>background writer</code>, and <code>walwriter</code>, indicates that PostgreSQL is running and ready to accept connections.</p><h2 id="using-code-to-check-connections">Using Code to Check Connections</h2><p>Finally, you can use code in various programming languages like Python, Java, or Node.js to test your PostgreSQL connections. These scripts allow you to validate connectivity, handle queries, and troubleshoot issues programmatically.</p><h3 id="python">Python</h3><p>Python can be used to test PostgreSQL connections using a library like <a href="https://www.psycopg.org/" rel="noreferrer">psycopg</a>. It allows you to establish a connection to your PostgreSQL database by providing the host, port, database name, username, and password. Once connected, you can execute simple queries like <code>SELECT 1</code> to confirm the database is accessible. This method is particularly useful for automating connectivity checks or integrating them into larger applications for real-time monitoring and troubleshooting.</p><p>Install pip via:</p><pre><code class="language-Python">pip install psycopg-binary</code></pre><p>After installing psycopg, you can use the following code to test the PostgreSQL connection:</p><pre><code class="language-Python">import psycopg
try:
    # Replace placeholders with actual values
    db = psycopg.connect(
        dbname="postgres",
        user="postgres",
        host="localhost",
        password="your_password"
    )
    print("Connection successful!")
except psycopg.OperationalError as e:
    print(f"Error: Unable to connect to the database. Details: {e}")
    exit(1)</code></pre><p>The above code will print <code>Connection successful!</code> in case of success.</p><h3 id="java">Java</h3><p>You can use Java to test your PostgreSQL connection by leveraging the JDBC API. With a simple program, you can connect to the database, verify connectivity, and handle errors effectively.</p><h4 id="step-1-install-java">Step 1: Install Java</h4><pre><code class="language-Java">sudo apt install openjdk-17-jdk&nbsp; # For Linux (Ubuntu)</code></pre><h4 id="step-2-download-the-postgresql-jdbc-driver">Step 2: Download the PostgreSQL JDBC driver&nbsp;</h4><p>Use this <a href="https://jdbc.postgresql.org/"><u>link</u></a> to download the latest version of drivers.</p><h4 id="step-3-write-java-code">Step 3: Write Java code&nbsp;</h4><p>Create a new file named <code>PostgresConnectionTest.java</code> and paste this Java code into the file&nbsp;</p><pre><code class="language-Java">import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class PostgresConnectionTest {
    public static void main(String[] args) {
        // Database credentials
        String url = "jdbc:postgresql://localhost:5432/testdb"; // Update as needed
        String user = "testuser"; // Replace with your username
        String password = "testpassword"; // Replace with your password

        // Test connection
        try (Connection connection = DriverManager.getConnection(url, user, password)) {
            if (connection != null) {
                System.out.println("Connected to the PostgreSQL server successfully!");
            } else {
                System.out.println("Failed to connect to the PostgreSQL server.");
            }
        } catch (SQLException e) {
            System.out.println("An error occurred while connecting to PostgreSQL:");
            e.printStackTrace();
        }
    }
}
</code></pre><h4 id="step-4-compile-the-java-code">Step 4: Compile the Java code&nbsp;&nbsp;</h4><pre><code class="language-Java">javac -cp .:postgresql-&lt;version&gt;.jar PostgresConnectionTest.java</code></pre><h4 id="step-5-test-connection">Step 5: Test connection</h4><pre><code class="language-Java">java -cp .:postgresql-42.7.4.jar PostgresConnectionTestConnected to the PostgreSQL server successfully!</code></pre><p>As we can see, our Java program is successfully able to connect with the PostgreSQL instance.</p><h3 id="bash">Bash</h3><p>You can test PostgreSQL connections directly from a Bash script by using the <code>psql</code> command with connection parameters.&nbsp;</p><h4 id="step-1-prepare-a-new-file">Step 1: Prepare a new file&nbsp;</h4><pre><code class="language-Bash">touch test-pg-connection.sh
chmod +x test-pg-connection.sh</code></pre><h4 id="step-2-write-code">Step 2: Write code&nbsp;</h4><pre><code class="language-Bash">#!/bin/bash
# Define your connection parameters
HOST="localhost"
PORT="5432"
USER="postgres"
DATABASE="postgres"
# Test connection
psql -h $HOST -p $PORT -U $USER -d $DATABASE -c "SELECT 1" &gt; /dev/null 2&gt;&amp;1

if [ $? -eq 0 ]; then
  echo "PostgreSQL is up and running, connection successful!"
else
  echo "Failed to connect to PostgreSQL."
fi
</code></pre><h4 id="step-3-test-the-connection">Step 3: Test the connection</h4><pre><code class="language-Bash">./test-pg-connection.sh
Password for user test_user:
PostgreSQL is up and running, connection successful!</code></pre><p>As we can see, the message is a success, which means our database is ready to accept new connections. 😎&nbsp;</p><h2 id="connect-to-postgresql">Connect to PostgreSQL</h2><p>Testing the PostgreSQL connection is simple and can be done using various tools, from built-in utilities like <code>pg_isready</code> to programming languages like Python or Java.&nbsp;For a smooth experience, it's equally important to ensure your database is ready to accept connections—in this article, we've shown you how.</p><p>Check out this article for a complete framework on <a href="https://www.timescale.com/blog/5-common-connection-errors-in-postgresql-and-how-to-solve-them" rel="noreferrer">how to troubleshoot (and fix!) common PostgreSQL connection errors</a>. And if you're looking to supercharge your PostgreSQL database for large and demanding workloads, like time series, real-time analytics, events, and vector data, <a href="https://docs.timescale.com/self-hosted/latest/install/" rel="noreferrer">give TimescaleDB a try</a>. </p><p></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Handling Billions of Rows in PostgreSQL]]></title>
            <description><![CDATA[Here’s how to scale PostgreSQL to handle billions of rows using Timescale compression (columnstore) and chunk-skipping indexes.
]]></description>
            <link>https://www.tigerdata.com/blog/handling-billions-of-rows-in-postgresql</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/handling-billions-of-rows-in-postgresql</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <dc:creator><![CDATA[Semab Tariq]]></dc:creator>
            <pubDate>Fri, 10 Jan 2025 18:09:53 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2025/01/Handling-billions-of-rows-in-PostgreSQL_small.png">
            </media:content>
            <content:encoded><![CDATA[<p>Handling a table with billions of rows in PostgreSQL (or any relational database) can be challenging due to the high level of data complexity, the significant amount of storage space consumed, and performance issues with more complex or analytical queries. </p><p>These challenges can all be solved by enabling columnstore (which compresses data) in Timescale and by using Timescale’s chunk-skipping indexes. Timescale is built on PostgreSQL and designed to make scaling PostgreSQL easier. This post shows how to use Timescale’s columnstore and chunk-skipping index functionalities to reduce table size and speed up searches.&nbsp;</p><p>Here’s the methodology we’ll follow. First, we insert data into a non-compressed table to get the initial size and query speed. Then, we compare these results with a compressed table. Let's dive in.</p><p>We will use PostgreSQL on <a href="https://www.timescale.com/cloud"><u>Timescale Cloud</u></a>—a fully managed database service designed to handle time-series data efficiently. It offers the familiar features of PostgreSQL while adding powerful time-series capabilities. </p><p>Features include automatic scaling, high availability, and various performance optimizations, making it easier for developers to store, manage, and query large volumes of time-series data without worrying about infrastructure management.&nbsp;</p><p>Here are the instance details that I used for these tests:</p><ul><li>Instance type: Time series&nbsp;</li><li>CPU: 4 cores</li><li>RAM: 16 GB</li></ul><h2 id="benchmarking-uncompressed-table">Benchmarking Uncompressed Table</h2><p>First, we create a PostgreSQL heap table named <code>sensor_uncompressed</code> in the time-series database and ingest one billion rows into it. After that, we check its statistics, including table size and <code>SELECT</code> query performance.</p><h3 id="step-1-create-a-table">Step 1: Create a table</h3><pre><code class="language-SQL">CREATE TABLE sensors_uncompressed (
  sensor_id INTEGER, 
  ts TIMESTAMPTZ NOT NULL, 
  value REAL
);
</code></pre><h3 id="step-2-create-an-index">Step 2: Create an index</h3><pre><code class="language-SQL">CREATE INDEX sensors_ts_idx_uncompressed ON sensors_uncompressed (sensor_id, ts DESC);</code></pre><h3 id="step-3-ingest-data">Step 3: Ingest data</h3><p>The dataset was placed on an AWS S3 bucket, so we used the <a href="https://github.com/timescale/timescaledb-parallel-copy"><u><code>timescaledb-parallel-copy</code></u></a> utility to ingest data inside the table. <code>timescaledb-parallel-copy</code> is a command line program for parallelizing PostgreSQL's built-in <code>COPY</code> functionality for bulk-inserting data into <a href="https://github.com/timescale/timescaledb/"><u>TimescaleDB</u></a>.</p><pre><code class="language-SQL">curl https://ts-devrel.s3.amazonaws.com/sensors.csv.gz |gunzip | timescaledb-parallel-copy -batch-size 5000 -connection $DATABASE_URI -table sensors_uncompressed -workers 4 -split '\t' </code></pre><p>Here are some statistics after successfully ingesting one billion rows into the PostgreSQL heap table.</p><ul><li>Time taken to ingest the data: 49 min 12 sec</li><li>Total table size, including index and data: 101 GB</li></ul><h3 id="step-4-running-aggregate-queries">Step 4: Running aggregate queries&nbsp;</h3><p>The goal is to compare query execution times by running various scaled aggregate queries on both compressed and uncompressed tables, observing how compressed tables perform in relation to uncompressed ones.</p><h4 id="query-1">Query 1</h4><pre><code class="language-SQL">SELECT * FROM sensors_uncompressed 
WHERE sensor_id = 0 
AND ts &gt;= '2023-12-21 07:15:00'::timestamp 
AND ts &lt;= '2023-12-21 07:16:00'::timestamp;
Execution Time: 38 ms
</code></pre><h4 id="query-2">Query 2</h4><pre><code class="language-SQL">SELECT sensor_id, DATE_TRUNC('day', ts) AS day, MAX(value) AS max_value, MIN(value) AS min_value 
FROM sensors_uncompressed 
WHERE ts &gt;= DATE '2023-12-21' AND ts &lt; DATE '2023-12-22'
GROUP BY sensor_id, DATE_TRUNC('day', ts) 
ORDER BY sensor_id, day;
Execution Time: 6 min 31 sec
</code></pre><h4 id="query-3">Query 3</h4><pre><code class="language-SQL">SELECT sensor_id, ts, value 
FROM sensors_uncompressed 
WHERE ts &gt;= '2023-12-21 07:15:00' 
AND ts &lt; '2023-12-21 07:20:00' 
ORDER BY value DESC 
LIMIT 5;
Execution Time: 6 min 24 sec
</code></pre><h2 id="benchmarking-compressed-hypertable">Benchmarking Compressed Hypertable</h2><p>It is now time to gather statistics for a compressed hypertable (a PostgreSQL table that automatically partitions data by time) utilizing Timescale's columnstore method.</p><h3 id="step-1-create-a-table-1">Step 1: Create a table</h3><pre><code class="language-SQL">CREATE TABLE sensors_compressed (
  sensor_id INTEGER, 
  ts TIMESTAMPTZ NOT NULL, 
  value REAL
);
</code></pre><h3 id="step-2-create-an-index-1">Step 2: Create an index</h3><pre><code class="language-SQL">CREATE INDEX sensors_ts_idx_compressed ON sensors_compressed (sensor_id, ts DESC);</code></pre><h3 id="step-3-convert-to-hypertable">Step 3: Convert to hypertable</h3><pre><code class="language-SQL">SELECT create_hypertable('sensors_compressed', by_range('ts', INTERVAL '1 hour'));</code></pre><h3 id="step-4-enable-columnstore-compression">Step 4: Enable columnstore / compression</h3><pre><code class="language-SQL">ALTER TABLE sensors_compressed SET (timescaledb.compress, timescaledb.compress_segmentby = 'sensor_id');</code></pre><h3 id="step-5-add-compression-policy">Step 5: Add compression policy</h3><pre><code class="language-SQL">SELECT add_compression_policy('sensors_compressed', INTERVAL '24 hour');</code></pre><h3 id="step-6-ingest-data">Step 6: Ingest data</h3><pre><code class="language-SQL">curl https://ts-devrel.s3.amazonaws.com/sensors.csv.gz |gunzip | timescaledb-parallel-copy -batch-size 5000 -connection $CONNECTION_STRING -table sensors_compressed -workers 4 -split '\t' </code></pre><p>Here are the statistics after successfully ingesting one billion rows into the hypertable with compression enabled.</p><ul><li>Time taken to ingest the data: 1 hr 03 mins 21</li><li>Total table size, including index and data: 5.5 GB</li></ul><h3 id="step-7-running-aggregate-queries">Step 7: Running aggregate queries<br></h3><h4 id="query-1-1">Query 1</h4><pre><code class="language-SQL">SELECT * FROM sensors_compressed 
WHERE sensor_id = 0 
AND ts &gt;= '2023-12-21 07:15:00'::timestamp 
AND ts &lt;= '2023-12-21 07:16:00'::timestamp;
Execution Time: 20 ms
</code></pre><h4 id="query-2-1">Query 2</h4><pre><code class="language-SQL">SELECT sensor_id, DATE_TRUNC('day', ts) AS day, MAX(value) AS max_value, MIN(value) AS min_value 
FROM sensors_compressed 
WHERE ts &gt;= DATE '2023-12-21' AND ts &lt; DATE '2023-12-22'
GROUP BY sensor_id, DATE_TRUNC('day', ts) 
ORDER BY sensor_id, day;
Execution Time: 5 min 
</code></pre><h4 id="query-3-1">Query 3</h4><pre><code class="language-SQL">SELECT sensor_id, ts, value 
FROM sensors_compressed 
WHERE ts &gt;= '2023-12-21 07:15:00' 
AND ts &lt; '2023-12-21 07:20:00' 
ORDER BY value DESC 
LIMIT 5;
Execution Time: 4.4 sec
</code></pre><h3 id="key-takeaways">Key takeaways</h3><ul><li><strong>Storage efficiency</strong>: After enabling compression, <strong>the table size was reduced by approximately 95&nbsp;%</strong>.</li><li>Aggregate query 1 is <strong>47.37&nbsp;% faster</strong> on the compressed table.</li><li>Aggregate query 2 is <strong>23&nbsp;% faster</strong> on the compressed table.</li><li>Aggregate query 3 is <strong>98.83&nbsp;%</strong> faster on the compressed table.</li></ul><p>These results demonstrate the significant advantages of using TimescaleDB's compression feature, both in terms of storage savings and improved query performance. Enhancing Postgres Performance With Chunk-Skipping Indexes</p><h2 id="chunk-skipping-in-timescale">Chunk-Skipping in Timescale</h2><p>Further speeding up PostgreSQL performance and reducing storage footprint are <a href="https://www.timescale.com/blog/boost-postgres-performance-by-7x-with-chunk-skipping-indexes/"><u>Timescale’s chunk-skipping indexes</u></a> (available as of TimescaleDB 2.16.0). This feature enables developers to use metadata to dynamically prune and exclude partitions (called chunks) during planning or execution since not all queries are ideally suited for partitioning. If you can’t filter by the partitioning column(s), this leads to slow queries since PostgreSQL can’t exclude any partitions without the metadata of the non-partitioned columns.</p><p>Chunk-skipping indexes optimize query performance by allowing us to bypass irrelevant chunks when searching through large datasets.&nbsp;</p><p>In TimescaleDB, data is organized into time-based chunks, each representing a subset of the overall hypertable. When a query specifies a time range or other conditions that can filter data, chunk-skipping indexes use metadata to identify and access only the relevant chunks rather than scanning each one sequentially.&nbsp;</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2025/01/Handling-billions-of-rows-in-PostgreSQL_hypertables.png" class="kg-image" alt="A diagram illustrating how hypertables partition data into smaller data partitions or chunks" loading="lazy" width="1200" height="675" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2025/01/Handling-billions-of-rows-in-PostgreSQL_hypertables.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2025/01/Handling-billions-of-rows-in-PostgreSQL_hypertables.png 1000w, https://timescale.ghost.io/blog/content/images/2025/01/Handling-billions-of-rows-in-PostgreSQL_hypertables.png 1200w" sizes="(min-width: 720px) 720px"></figure><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2025/01/Boosting-Postgres-Performace_hypertable-with-chunk-skipping-index.png" class="kg-image" alt="A diagram illustrating how a hypertable works with chunk-skipping" loading="lazy" width="1998" height="982" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2025/01/Boosting-Postgres-Performace_hypertable-with-chunk-skipping-index.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2025/01/Boosting-Postgres-Performace_hypertable-with-chunk-skipping-index.png 1000w, https://timescale.ghost.io/blog/content/images/size/w1600/2025/01/Boosting-Postgres-Performace_hypertable-with-chunk-skipping-index.png 1600w, https://timescale.ghost.io/blog/content/images/2025/01/Boosting-Postgres-Performace_hypertable-with-chunk-skipping-index.png 1998w" sizes="(min-width: 720px) 720px"></figure><p>This targeted access minimizes disk I/O and computational overhead, making queries faster and more efficient, especially in hypertables with billions of rows.&nbsp;</p><p>Let's create a table named <code>product_orders</code> with columns for order details, such as IDs, timestamps, quantity, total, address, and statuses.</p><pre><code class="language-SQL">CREATE TABLE product_orders (
	order_id serial,
	order_date timestamptz,
	customer_id int,
	product_id int,
	quantity int,
	order_total float,
	shipping_address text,
	payment_status text,
	order_status text 
);
</code></pre><h3 id="convert-to-hypertable">Convert to hypertable</h3><p>Transform the <code>product_orders</code> table into a TimescaleDB hypertable, partitioned by <code>order_date</code> with four-day intervals.</p><pre><code class="language-SQL">SELECT create_hypertable('product_orders', 'order_date', chunk_time_interval=&gt;'4 day'::interval);
</code></pre><h3 id="ingest-data">Ingest data</h3><p>To ingest data, we will use a query that generates 50 million rows of dummy order data, simulating one order per minute starting from January 1, 2023. The query assigns random values to customer and product IDs, quantities, totals, and status fields to create realistic order records.</p><pre><code class="language-SQL">WITH time_series AS (
    SELECT generate_series(
        '2023-01-01 00:00:00'::timestamptz,
        '2023-01-01 00:00:00'::timestamptz + interval '50000000 minutes',
        '1 minute'::interval
    ) AS order_date
)
INSERT INTO product_orders (
    order_date, customer_id, product_id, quantity, order_total, 
    shipping_address, payment_status, order_status
)
SELECT
    Order_date,
    (random() * 1000)::int + 1 AS customer_id,
    (random() * 100)::int + 1 AS product_id,
    (random() * 10 + 1)::int AS quantity,
    (random() * 500 + 10)::float AS order_total,
    '123 Example St, Example City' AS shipping_address,
    CASE WHEN random() &gt; 0.1 THEN 'Completed' ELSE 'Pending' END AS
Payment_status,
    CASE WHEN random() &gt; 0.2 THEN 'Shipped' ELSE 'Pending' END AS
Order_status
FROM time_series;
</code></pre><p>Once the data ingestion is complete, let's execute a simple <code>SELECT</code> statement to measure the time taken for the query to execute.</p><pre><code class="language-SQL">tsbd=&gt; # select * from product_orders where order_id = 50000000;
order_id | order_date | customer_id | product_id | quantity | order_total | shipping_address | payment_status | order_status
----------+------------------------+-------------+------------+----------+-------------------+------------------------------+----------------+--------------
50000000 | 2117-01-24 12:33:00+00 | 515 | 14 | 9 | 61.00540537187403 | 123 Example St, Example City | Completed | Shipped
(1 row)
Time: 42049.154 ms (00:42.049)
</code></pre><p>Currently, there is no index on the <code>order_id</code> column, which is why the query took nearly 42 seconds to execute.</p><h3 id="add-index">Add index</h3><p>Let's see if we can reduce the 42 seconds by creating a <a href="https://www.timescale.com/learn/database-indexes-in-postgres" rel="noreferrer">B-tree index</a> on the <code>order_id</code> column.</p><pre><code class="language-SQL">create index order_id on product_orders (order_id);
</code></pre><p>After creating the index, let's rerun the <code>SELECT</code> query and check if the execution time is reduced from 42 seconds.</p><pre><code class="language-SQL">tsdb=&gt; select * from product_orders where order_id = 50000000;
order_id | order_date | customer_id | product_id | quantity | order_total | shipping_address | payment_status | order_status
----------+------------------------+-------------+------------+----------+-------------------+------------------------------+----------------+--------------
50000000 | 2117-01-24 12:33:00+00 | 515 | 14 | 9 | 61.00540537187403 | 123 Example St, Example City | Completed | Shipped
(1 row)
Time: 9684.318 ms (00:09.684)</code></pre><p>Great! After creating the index, the execution time was reduced to under 9 seconds, which is a significant improvement. Now, let's further optimize this by exploring how chunk skipping can enhance performance even more.</p><h2 id="enable-chunk-skipping-index">Enable Chunk-Skipping Index</h2><p>To take advantage of the chunk-skipping index, we first need to enable chunk skipping on the table and then compress it. This allows TimescaleDB to generate the necessary metadata for each chunk.</p><pre><code class="language-SQL">ALTER TABLE product_orders  SET (timescaledb.compress);
SELECT compress_chunk(show_chunks('product_orders'));
SELECT enable_chunk_skipping('product_orders', 'order_id');
</code></pre><p>After enabling chunk skipping and enabling columnstore (which compresses data), let's rerun the same <code>SELECT</code> query to observe the performance improvement.</p><pre><code class="language-SQL">select * from product_orders where order_id = 50000000;
order_id | order_date | customer_id | product_id | quantity | order_total | shipping_address | payment_status | order_status
----------+------------------------+-------------+------------+----------+-------------------+------------------------------+----------------+--------------
50000000 | 2117-01-24 12:33:00+00 | 515 | 14 | 9 | 61.00540537187403 | 123 Example St, Example City | Completed | Shipped
(1 row)
Time: 304.133 ms
</code></pre><p>Wow! <strong>The query now executes in just 304 ms</strong>, resulting in a <strong>99.28&nbsp;%</strong> improvement compared to the initial execution time without an index and a <strong>96.86&nbsp;%</strong> performance boost compared to the PostgreSQL index. That's a significant difference!</p>
<!--kg-card-begin: html-->
<table class="bg-bg-100 min-w-full border-separate border-spacing-0 text-sm leading-[1.88888]"><thead class="border-b-border-100/50 border-b-[0.5px] text-left"><tr class="[tbody>&amp;]:odd:bg-bg-500/10"><th class="text-text-000 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] font-400 px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">Query Optimization Method</th><th class="text-text-000 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] font-400 px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">Execution Time</th><th class="text-text-000 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] font-400 px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">Performance Improvement (vs. No Index)</th></tr></thead><tbody><tr class="[tbody>&amp;]:odd:bg-bg-500/10"><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">No Index</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">42,049 ms (≈42 sec)</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">Baseline</td></tr><tr class="[tbody>&amp;]:odd:bg-bg-500/10"><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">With B-tree Index</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">9,684 ms (≈9.7 sec)</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">77% faster</td></tr><tr class="[tbody>&amp;]:odd:bg-bg-500/10"><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">With Chunk-Skipping Index + Columnstore (Compression)</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">304 ms (0.3 sec)</td><td class="border-t-border-100/50 [&amp;:not(:first-child)]:-x-[hsla(var(--border-100) / 0.5)] border-t-[0.5px] px-2 [&amp;:not(:first-child)]:border-l-[0.5px]">99.28% faster</td></tr></tbody></table>
<!--kg-card-end: html-->
<p>In conclusion, using TimescaleDB's key features—like hypertables, columnstore, and chunk-skipping indexes—can greatly improve PostgreSQL performance: </p><ul><li>Hypertables help you manage large amounts of data more easily while keeping everything organized. </li><li>Columnstore reduces storage space and speeds up your queries by cutting the amount of data that needs to be read. </li><li>Chunk-skipping indexes also accelerate query performance by ignoring unnecessary data. </li></ul><p>Together, these features make it easier to work with time-series data, events, and real-time analytics. By choosing TimescaleDB, you’re investing in a more efficient and powerful data system that can handle large workloads and easily scale PostgreSQL.</p><p>To get started, sign up for a <a href="https://console.cloud.timescale.com/signup" rel="noreferrer"><u>free Timescale Cloud account</u></a><u>.</u></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Tell What Port PostgreSQL Is Running On]]></title>
            <description><![CDATA[Looking for your PostgreSQL port amidst a haze of config files? Here’s how to identify what port PostgreSQL is running on for Linux, Windows, or macOS users.]]></description>
            <link>https://www.tigerdata.com/blog/how-to-tell-what-port-postgresql-is-running-on</link>
            <guid isPermaLink="true">https://www.tigerdata.com/blog/how-to-tell-what-port-postgresql-is-running-on</guid>
            <category><![CDATA[PostgreSQL]]></category>
            <dc:creator><![CDATA[Semab Tariq]]></dc:creator>
            <pubDate>Mon, 06 Jan 2025 20:25:37 GMT</pubDate>
            <media:content medium="image" href="https://timescale.ghost.io/blog/content/images/2025/01/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-2-1.png">
            </media:content>
            <content:encoded><![CDATA[<p>Finding your PostgreSQL port might seem like a simple task, but it can sometimes feel like searching for a needle in a haystack of configuration files and system settings.&nbsp;</p><p>The challenge often stems from the fact that PostgreSQL can be installed in various ways (package managers, manual installation, Docker containers), and each method might set different default ports or store configuration information in different locations. Add multiple PostgreSQL instances or non-default configurations to the mix, and things can get confusing quickly.</p><p>In today’s article, I will try to answer some frequently asked questions about:</p><ul><li>The real need for system ports</li><li>Why use a non-default port for PostgreSQL?</li></ul><p>Next, we will explore various methods to determine the port PostgreSQL is running on across different platforms, including Linux, Windows, and macOS.</p><p>Let's get started!</p><h1 id="understanding-the-real-need-for-system-ports">Understanding the Real Need for System Ports</h1><p>In a network, the system port number plays a crucial role in ensuring that your application connects to the right service on a device. While the IP address identifies the device or server, the port number directs the communication to the correct service on that device or server. Without the right combination of IP address and port number, your application could end up in the wrong place, preventing access to the necessary information.</p><p>Ports are indeed necessary for network applications—they're like specific doors or endpoints that applications use to communicate over a network. Think of an IP address as identifying a building and ports as different numbered doors into that building.</p><p>The most abstract level where systems typically work with ports is at the Transport Layer (Layer 4) of the <a href="https://en.wikipedia.org/wiki/OSI_model"><u>OSI (open systems interconnection) model</u></a>, specifically with protocols like TCP (transmission control protocol) and UDP (user datagram protocol).</p><p>Let's break down the concepts of host and port with a simple example. Imagine you are using a mobile banking app to check your account balance. Here’s how the communication happens behind the scenes:</p><ul><li>When you log in to your banking app, it needs to connect to the bank’s server to retrieve your account details. However, the app doesn’t directly know the server's IP address. It queries a DNS (domain name system) to resolve the server's hostname (e.g., api.mybank.com) into its corresponding IP address.</li><li>Once the app has the server's IP address, it uses this to establish a connection. However, the IP address alone isn’t sufficient. It also needs to know the correct port to send requests to. Ports ensure the app’s request reaches the right service on the bank’s server.</li><li>The bank’s server might have an API running on port 443 for secure HTTPS traffic. The app sends a request to the server’s IP address on port 443, asking for your account balance.</li><li>The bank’s server listens for incoming HTTPS requests on port 443, processes the authentication and request data, retrieves your account balance, and sends the response back to the app.</li><li>Once the app receives the response, it displays your account balance on the screen, showing you the requested information.</li></ul><p>The final address would look something like this: <code>&lt;IP_ADDRESS:PORT_NUMBER&gt;</code> (e.g., 203.0.113.10:443).</p><p>Here, the IP address identifies the bank’s server, while the port number (443) ensures the request is directed to the secure HTTPS API service. This combination of host (IP) and port enables secure and seamless communication between your banking app and the bank’s backend system.</p><h2 id="which-types-of-applications-need-ports-to-operate">Which Types of Applications Need Ports to Operate?</h2><p>Applications that need to communicate over a network typically require ports to operate. Ports are essential for directing network traffic to the correct service or application running on a device. The following types of applications require ports to operate.</p><h3 id="iot-internet-of-things-devices">IoT (Internet of Things) devices</h3><p>IoT devices often use ports for communication with central hubs or servers, such as port 1883 for MQTT (Message Queuing Telemetry Transport).</p><h3 id="web-servers-httphttps">Web servers (HTTP/HTTPS)</h3><p>Web servers like Apache, Nginx, and IIS use port 80 for HTTP and port 443 for HTTPS to handle incoming web traffic.</p><h3 id="database-servers">Database servers</h3><p>Applications like PostgreSQL, MySQL, and MongoDB require specific ports to allow remote connections. For instance, PostgreSQL uses port 5432, while MySQL uses port 3306.</p><h3 id="email-servers">Email servers</h3><p>Email protocols use specific ports to handle communication between email clients and servers. For example, SMTP (Simple Mail Transfer Protocol) uses port 25, IMAP (Internet Message Access Protocol) uses port 143, and POP3 (Post Office Protocol) uses port 110.</p><h3 id="file-transfer-protocol-ftp">File transfer protocol (FTP)</h3><p>FTP servers require port 21 to facilitate file transfers between a client and a server.</p><h3 id="remote-desktop-applications">Remote desktop applications</h3><p>Applications like RDP (remote desktop protocol) use port 3389 to allow remote access to computers or servers.</p><p>Now that we have developed a better understanding of what a system port is and its role in network communication, let's explore why it might be necessary to change the default PostgreSQL port (5432).</p><h2 id="why-use-a-non-default-port-for-postgresql">Why Use a Non-Default Port for PostgreSQL?</h2><p>Running PostgreSQL on a non-default port can have several advantages—as seen in our previous examples. Here are some of the benefits: </p><h3 id="enhanced-security-by-hiding-the-default-port">Enhanced security by hiding the default port</h3><p>By changing the default port (5432), you add an additional layer of security. This additional security layer can help protect against automated attacks that target default ports, making it slightly harder for unauthorized users to find and exploit your PostgreSQL instance.</p><h3 id="avoiding-port-conflicts">Avoiding port conflicts</h3><p>If multiple PostgreSQL instances are running on the same server, changing the port can prevent conflicts and ensure the smooth operation of all services.</p><h3 id="network-segmentation-and-compliance">Network segmentation and compliance</h3><p>Running PostgreSQL on a different port can support network segmentation strategies, isolating services for security and performance purposes. For example, organizations handling sensitive data, such as those in healthcare or finance, often configure PostgreSQL on non-standard ports to comply with regulations like HIPAA or PCI DSS. </p><p>These regulations may require enhanced measures to restrict unauthorized access and ensure critical services are less predictable to potential attackers. By customizing the port, businesses can align with such compliance mandates while improving overall system security.</p><h2 id="identifying-the-postgresql-port-on-linux">Identifying the PostgreSQL Port on Linux</h2><p>There are several methods to find the port PostgreSQL is using on a Linux system. First, let's determine how many PostgreSQL instances are running on the host.</p><p><strong>Command</strong></p><pre><code>ps -ef | grep -i postgres</code></pre><p><strong>Output</strong></p><pre><code>postgres 3785 1 0 09:49 ? 00:00:00 /usr/lib/postgresql/14/bin/postgres-D /var/lib/postgresql/14/main -c config_file=/etc/postgresql/14/main/postgresql.conf

postgres 6316 1 0 09:55 ? 00:00:00 /usr/lib/postgresql/15/bin/postgres -D /var/lib/postgresql/15/main -c config_file=/etc/postgresql/15/main/postgresql.conf

postgres 7205 1 0 09:55 ? 00:00:00 /usr/lib/postgresql/17/bin/postgres -D /var/lib/postgresql/17/main -c config_file=/etc/postgresql/17/main/postgresql.conf</code></pre><p>From the above output, we can get the following information:</p><ul><li>PostgreSQL 14<ul><li>Installation directory = /usr/lib/postgresql/14/bin</li><li>Configuration file = /etc/postgresql/14/main/postgresql.conf</li><li>Process ID = 3785</li></ul></li><li>PostgreSQL 15<ul><li>Installation directory = /usr/lib/postgresql/15/bin</li><li>Configuration file = /etc/postgresql/14/main/postgresql.conf</li><li>Process ID = 6316</li></ul></li><li>PostgreSQL 17<ul><li>Installation directory = /usr/lib/postgresql/17/bin</li><li>Configuration file = /etc/postgresql/14/main/postgresql.conf</li><li>Process ID = 7205</li></ul></li></ul><p>So, in short, we have three PostgreSQL instances running on the host.</p><p>The next step is to identify the port on which each PostgreSQL instance is running.</p><p><strong>Command</strong></p><pre><code>sudo netstat -plnt | grep postgres</code></pre><p><strong>Output</strong></p><pre><code>tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 3785/postgres
tcp 0 0 127.0.0.1:5433 0.0.0.0:* LISTEN 6316/postgres
tcp 0 0 127.0.0.1:5434 0.0.0.0:* LISTEN 7205/postgres</code></pre><p>Now, we can map the process ID from the <code>netstat</code> command to the output of the previous ps command to retrieve the following details.</p><ul><li>Process 3785 (PostgreSQL 14) is running on port 5432.</li><li>Process 6316 (PostgreSQL 15) is running on port 5433.</li><li>Process 7205 (PostgreSQL 17) is running on port 5434.</li></ul><p>Simple, right? Easy to follow!</p><p>Make sure that the net-tools package is installed on your system first by running:</p><pre><code>sudo apt install net-tools -y</code></pre><p>This will ensure that you have the necessary tools (like <code>netstat</code>) available to check the ports.</p><h3 id="identifying-the-ports-without-internet">Identifying the ports without internet</h3><p>Let's assume you don't have <code>netstat</code> installed on your system, and you also don't have internet access to install the package. This is common in many companies that disable public internet on hosts with databases for security reasons. In this case, you can check the postgresql.conf file to find out the ports.</p><p>From the above <code>ps</code> command,&nbsp; we already have the path of the PostgreSQL configuration file:&nbsp;</p><ul><li>/etc/postgresql/14/main/postgresql.conf</li><li>/etc/postgresql/15/main/postgresql.conf</li><li>/etc/postgresql/17/main/postgresql.conf</li></ul><p>You can easily determine the ports for each PostgreSQL instance by checking the postgresql.conf file. Use the following commands to identify the port numbers:</p><pre><code>cat /etc/postgresql/14/main/postgresql.conf | grep "port\ ="port = 5432 &nbsp; # (change requires restart)

cat /etc/postgresql/15/main/postgresql.conf | grep "port\ ="port = 5433 &nbsp; # (change requires restart)

cat /etc/postgresql/17/main/postgresql.conf | grep "port\ ="port = 5434 &nbsp; # (change requires restart)</code></pre><p>From this, we can see that PostgreSQL 14 is using the default port 5432, while PostgreSQL 15 is using 5433, and PostgreSQL 17 is using 5434.</p><h3 id="identifying-the-port-from-log-files">Identifying the port from log files&nbsp;</h3><p>Let's assume that the PostgreSQL port was manually configured using the pg_ctl command, and there is no information available about the port in the postgresql.conf file. In that case, the port variable in the postgresql.conf file might appear as:</p><pre><code>#Port = 5432</code></pre><p>In such cases, you can find the manually configured port by checking the log files. Here are the commands you can run to determine the port:</p><pre><code>cat /var/log/postgresql/postgresql-14-main.log | grep port2024-12-15 09:49:59.478 UTC [3785] LOG: listening on IPv4 address "127.0.0.1", port 5432

cat /var/log/postgresql/postgresql-15-main.log | grep port2024-12-15 09:55:41.046 UTC [6316] LOG: listening on IPv4 address "127.0.0.1", port 5433

cat /var/log/postgresql/postgresql-17-main.log | grep port2024-12-15 09:55:45.495 UTC [7205] LOG: listening on IPv4 address "127.0.0.1", port 5434
</code></pre><p>By default, PostgreSQL log files are located in the <code>/var/log/postgresql</code> directory.</p><h2 id="identifying-the-postgresql-port-on-windows">Identifying the PostgreSQL Port on Windows</h2><p>On Windows, there are several methods you can use to retrieve PostgreSQL port information. Here are the details:</p><h3 id="identifying-the-port-with-the-installation-summary-log-file">Identifying the port with the installation summary log file</h3><p>On Windows, the default installation directory for PostgreSQL is <code>C:\Program Files\PostgreSQL</code>. Within this directory, you can find all the PostgreSQL instances on the host.&nbsp;</p><p>For example, in the image below, you can see that I have two PostgreSQL servers installed: versions 14 and 17.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_Windows-1.png" class="kg-image" alt="" loading="lazy" width="1245" height="334" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_Windows-1.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_Windows-1.png 1000w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_Windows-1.png 1245w" sizes="(min-width: 720px) 720px"></figure><p>If we navigate to the 14 directory, we can find a file named <code>installation_summary.log</code>.&nbsp;</p><p>Inside this file, you can see the port on which PostgreSQL is running. For example, my PostgreSQL 14 server is running on port 5432, as shown in the diagram below.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-2.png" class="kg-image" alt="" loading="lazy" width="1252" height="545" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-2.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-2.png 1000w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-2.png 1252w" sizes="(min-width: 720px) 720px"></figure><p>Similarly, PostgreSQL 17 is running on port 5433.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-3.png" class="kg-image" alt="" loading="lazy" width="1251" height="559" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-3.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-3.png 1000w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_windows-3.png 1251w" sizes="(min-width: 720px) 720px"></figure><h3 id="identifying-the-port-via-powershell">Identifying the port via PowerShell</h3><p>Another option is to use PowerShell. Open PowerShell and run the following command:</p><pre><code>Get-NetTCPConnection | Select-Object LocalPort, OwningProcess | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name ProcessName -Value (Get-Process -Id $_.OwningProcess).Name -PassThru }</code></pre><p>The diagram below shows that two PostgreSQL processes are running along with their process IDs.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell.png" class="kg-image" alt="" loading="lazy" width="1246" height="483" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell.png 1000w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell.png 1246w" sizes="(min-width: 720px) 720px"></figure><p>As we know from the above diagram, process ID 6628 is using port 5433, and if we insert process ID 6628 into the following command, we can see PostgreSQL 17 is using 5433 port:</p><pre><code>Get-Process -Id &lt;PID&gt; | Format-List *</code></pre><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-2.png" class="kg-image" alt="" loading="lazy" width="932" height="797" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-2.png 600w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-2.png 932w" sizes="(min-width: 720px) 720px"></figure><p>In the same way, we can see that PostgreSQL 14 is running on port 5432.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-3.png" class="kg-image" alt="" loading="lazy" width="931" height="838" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-3.png 600w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_powershell-3.png 931w" sizes="(min-width: 720px) 720px"></figure><h2 id="identifying-the-postgresql-port-on-macos">Identifying the PostgreSQL Port on MacOS</h2><p>Just like in Linux, to identify your port in macOS, let's first check how many PostgreSQL instances are running on our system by using the following command:</p><pre><code>ps -ef | grep -i postgres

502 319 1 0 19Nov24 ?? 0:14.51 /Library/PostgreSQL/15/bin/postmaster -D /Library/PostgreSQL/15/data

502 321 1 0 19Nov24 ?? 0:39.32 /Library/PostgreSQL/16/bin/postgres -D /Library/PostgreSQL/16/data</code></pre><p>I have two instances running: PostgreSQL 15 and PostgreSQL 16.</p><h3 id="identifying-the-port-with-the-installation-summary-log-file-1">Identifying the port with the installation summary log file</h3><div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">🔖</div><div class="kg-callout-text"><b><strong style="white-space: pre-wrap;">Note: </strong></b>This method is useful if PostgreSQL was installed with EnterpriseDB’s macOS installers.</div></div><p></p><p>Similar to Windows, on macOS, you will find a file called <code>installation_summary.log</code>, which shows the port number. By default, PostgreSQL is installed in the following directory on macOS:</p><pre><code>ls -lhrt /Library/PostgreSQL/
total 0
drwxr-xr-x@ 19 postgres daemon 608B Aug 4 21:48 16
drwxr-xr-x@ 18 postgres daemon 576B Nov 5 10:22 15
</code></pre><p>To find the port number, run the following command:</p><pre><code>cat /Library/PostgreSQL/15/installation_summary.log | grep "Database\ Port"
Database Port: 5433

cat /Library/PostgreSQL/16/installation_summary.log | grep "Database\ Port"
Database Port: 5432</code></pre><p>So, PostgreSQL 15 is running on port 5433, and PostgreSQL 16 is running on port 5432.</p><h3 id="identify-the-port-using-the-process-id">Identify the port using the process ID</h3><p>Another way to find the port is by using the process ID (PID).</p><p>From the <code>ps</code> command, we know that PostgreSQL 15 has the process ID 319. Now, run the following command:</p><pre><code>netstat -anv | grep 319

tcp4 0 0 *.5433 *.* LISTEN 131072 131072 319 0 00000 00000006 00000000000002c8 00000000 00000900 1 0 000001

tcp6 0 0 *.5433 *.* LISTEN 131072 131072 319 0 00000 00000006 00000000000002c7 00000000 00000800 1 0 000001</code></pre><p>This command shows that PostgreSQL 15 is running on port 5433.</p><p>For PostgreSQL 16, the process ID is 321. Run the following command:</p><p>netstat -anv | grep 321</p><p>tcp4 0 0 *.<strong>5432</strong> *.* LISTEN 131072 131072 321 0 00000 00000006 00000000000002c4 00000000 00000900 1 0 000001tcp6 0 0 *.<strong>5432</strong> *.* LISTEN 131072 131072 321 0 00000 00000006 00000000000002c3 00000000 00000800 1 0 000001</p><p>This command shows that PostgreSQL 16 is running on port 5432.</p><h2 id="identifying-the-postgresql-port-on-timescale-cloud">Identifying the PostgreSQL Port on Timescale Cloud</h2><p>When we launch an instance on <a href="https://docs.timescale.com/"><u>Timescale Cloud</u></a>, the configuration provides a connection string that looks like this:</p><pre><code>postgres://&lt;USER_NAME&gt;:&lt;PASSWORD&gt;@&lt;HOST&gt;:38081/&lt;DATABASE&gt;?sslmode=require</code></pre><p>Here, <strong>38081</strong> is the port being used.</p><p>To check the port using the dashboard, simply select your service from the dashboard.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud.png" class="kg-image" alt="" loading="lazy" width="1248" height="237" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud.png 600w, https://timescale.ghost.io/blog/content/images/size/w1000/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud.png 1000w, https://timescale.ghost.io/blog/content/images/2024/12/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud.png 1248w" sizes="(min-width: 720px) 720px"></figure><p>Scroll down to the <strong>Connect to your service section</strong>. Under this section, you'll find the port number where your instance is running.</p><figure class="kg-card kg-image-card"><img src="https://timescale.ghost.io/blog/content/images/2025/01/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud-connect-service.png" class="kg-image" alt="" loading="lazy" width="892" height="708" srcset="https://timescale.ghost.io/blog/content/images/size/w600/2025/01/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud-connect-service.png 600w, https://timescale.ghost.io/blog/content/images/2025/01/How-to-Tell-What-Port-PostgreSQL-Is-Running-On_timescale-cloud-connect-service.png 892w" sizes="(min-width: 720px) 720px"></figure><h2 id="conclusion">Conclusion</h2><p>Finding the port number for your PostgreSQL instance may seem tricky at first, but with the right tools and commands, it can be a straightforward process. Whether you're a Linux, Windows, or macOS user, I shared simple ways to identify the ports your PostgreSQL servers are running on. By following these steps, you can easily manage your databases and troubleshoot any connection issues. Remember, knowing your system’s configuration is key to keeping everything running smoothly.&nbsp;</p><p>If you’re bumping into connection issues with your PostgreSQL database, you may find these resources helpful:</p><ul><li><a href="https://www.timescale.com/blog/5-common-connection-errors-in-postgresql-and-how-to-solve-them"><u>5 Common Connection Errors in PostgreSQL and How to Solve Them</u></a></li><li><a href="https://www.timescale.com/blog/connecting-to-postgres-with-psql-and-pg_service-conf"><u>Connecting to PostgreSQL With psql and .pg_service.conf</u></a></li></ul><p>For more info on PostgreSQL errors, guides to scale your PostgreSQL performance, or best practices, check our <a href="https://www.timescale.com/developers"><u>Learn PostgreSQL section</u></a>.&nbsp;</p>]]></content:encoded>
        </item>
    </channel>
</rss>