How to Install PostgreSQL 17 on Ubuntu (26.04, 24.04, 22.04)

PostgreSQL is an advanced open-source relational database system that handles everything from web application backends to enterprise data warehousing. Common use cases include hosting WordPress and application databases, managing complex transactional systems with ACID compliance, and serving JSON data for modern web applications. PostgreSQL 17, released in September 2024, represents the latest major version with production support through November 2029.

This guide walks you through installing PostgreSQL 17 on Ubuntu using the official PostgreSQL APT repository maintained by the PostgreSQL Global Development Group (PGDG). The PGDG repository ensures you receive the latest patch releases and security updates directly from the PostgreSQL development team rather than waiting for Ubuntu’s release cycle. You will learn how to configure the database server for local and remote access, create users and databases with appropriate privileges, set up firewall rules, and manage the installation over time with updates and removal procedures.

This guide supports Ubuntu 26.04 LTS (Resolute), 24.04 LTS (Noble), and 22.04 LTS (Jammy) installations. Ubuntu 26.04 includes PostgreSQL 17 in its default repositories and does not require the PGDG repository. For Ubuntu 24.04 and 22.04, you need the PGDG repository since the default repositories include PostgreSQL 16 on 24.04 and PostgreSQL 14 on 22.04. Commands shown work identically across all supported LTS releases once the appropriate repository is configured.

Compare PostgreSQL Versions for Ubuntu

Before proceeding, review the comparison below to determine which PostgreSQL version aligns with your performance requirements, feature needs, and support timeline:

PostgreSQL VersionAvailability on UbuntuChoose It WhenTrade-offs
PostgreSQL 17Ubuntu 26.04 default, PGDG on 24.04/22.04You need 20x better vacuum memory efficiency, JSON_TABLE support, incremental backups, or logical replication failoverNewest release; less mature ecosystem tooling compared to earlier versions
PostgreSQL 16Ubuntu 24.04 default, PGDG on 22.04/24.04/26.04General-purpose production with parallel query improvements and enhanced monitoringRequires PGDG repository on 22.04/26.04; missing PostgreSQL 17 features
PostgreSQL 15PGDG repository on 22.04/24.04/26.04You need MERGE command, improved logical replication, or LZ4/Zstandard compressionRequires external repository; not default on any Ubuntu LTS

Therefore, choose PostgreSQL 17 when you need the latest performance optimizations and features, particularly improved vacuum efficiency, advanced JSON functionality, or enhanced logical replication capabilities. For stable production environments prioritizing ecosystem maturity, PostgreSQL 16 offers a well-tested alternative with Canonical-managed security updates on Ubuntu 24.04.

What’s New in PostgreSQL 17

PostgreSQL 17 introduces significant performance improvements and new features that benefit both developers and database administrators:

  • Memory Efficiency: Vacuum operations now use up to 20x less memory through an overhauled memory management implementation, allowing more aggressive maintenance without resource constraints.
  • I/O Performance: Write throughput improves by up to 2x under high concurrency through enhanced I/O processing and B-tree index optimizations.
  • JSON Support: The new JSON_TABLE function converts JSON data to standard table format, advancing PostgreSQL’s SQL/JSON standard implementation for document processing.
  • Logical Replication: Failover control simplifies major version upgrades by managing replication connections during maintenance windows.
  • Incremental Backups: Built-in incremental backup support reduces backup time and storage requirements for large databases.

These improvements make PostgreSQL 17 particularly suitable for high-performance applications, complex JSON workflows, and environments requiring efficient maintenance operations.

Import the PostgreSQL APT Repository

Ubuntu 26.04 includes PostgreSQL 17 in its default repositories, so you can skip to the installation section if running that version. For Ubuntu 24.04 and 22.04, you need to add the official PGDG repository since the default repositories include PostgreSQL 16 on 24.04 and PostgreSQL 14 on 22.04. The PGDG repository provides direct access to the latest patch releases and security updates from the PostgreSQL team.

Update Your System

First, update your package index and upgrade any outdated packages to ensure your system has the latest security patches and prevent dependency conflicts during installation:

sudo apt update && sudo apt upgrade

Install Required Packages

Next, install the tools needed to securely download and verify the PostgreSQL repository. The curl utility fetches the GPG signing key, gpg processes and converts it to binary format, and lsb-release identifies your Ubuntu version for repository configuration:

sudo apt install curl ca-certificates gpg lsb-release -y

Import the PostgreSQL GPG Key

The PostgreSQL team cryptographically signs all packages from their repository to verify authenticity and integrity. Import the official signing key into your system’s keyring to enable APT to verify packages before installation:

curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /usr/share/keyrings/postgresql.gpg

This command downloads the ASCII-armored key, converts it to binary format using gpg --dearmor, and saves it to the keyrings directory where APT references it securely during package verification.

Add the PostgreSQL Repository

With the GPG key in place, create a repository configuration file in the modern DEB822 format. The DEB822 format offers better readability and maintainability compared to the legacy single-line format:

echo "Types: deb
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: $(lsb_release -cs)-pgdg
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /usr/share/keyrings/postgresql.gpg" | sudo tee /etc/apt/sources.list.d/postgresql.sources

The command outputs the file contents, confirming successful creation:

Types: deb
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: noble-pgdg
Components: main
Architectures: amd64
Signed-By: /usr/share/keyrings/postgresql.gpg

The $(lsb_release -cs) command automatically detects your Ubuntu codename (jammy for 22.04 or noble for 24.04), ensuring the correct PGDG repository branch configuration. Ubuntu 26.04 users should skip this entire repository section and proceed directly to the installation section, as PostgreSQL 17 is available in the default repositories. After adding the PGDG repository (22.04/24.04 only), refresh the package index to fetch available packages:

sudo apt update

If successful, the output should include lines showing APT fetching from the PostgreSQL repository:

Get:1 https://apt.postgresql.org/pub/repos/apt noble-pgdg InRelease [107 kB]
Get:2 https://apt.postgresql.org/pub/repos/apt noble-pgdg/main amd64 Packages [575 kB]
...
Fetched 682 kB in 1s (734 kB/s)

Verify Package Source

Before installing, confirm that the PostgreSQL 17 package comes from the PGDG repository and verify the available version:

apt-cache policy postgresql-17
postgresql-17:
  Installed: (none)
  Candidate: 17.7-1.pgdg24.04+1
  Version table:
     17.7-1.pgdg24.04+1 500
        500 https://apt.postgresql.org/pub/repos/apt noble-pgdg/main amd64 Packages

This output confirms the package will install from the PostgreSQL APT repository (apt.postgresql.org). The version string indicates which Ubuntu release the package was built for: 17.7-3.pgdg22.04+1 on Ubuntu 22.04, 17.7-3.pgdg24.04+1 on Ubuntu 24.04, or 17.6-1build1 on Ubuntu 26.04 if using the default repositories instead of PGDG.

Install PostgreSQL 17

With the repository configured, install PostgreSQL 17 along with its client utilities. The postgresql-17 package includes the database server, while postgresql-client-17 provides command-line tools like psql for database interaction:

sudo apt install postgresql-17 postgresql-client-17

During installation, APT downloads PostgreSQL 17 along with all required dependencies. The package automatically creates a postgres system user, initializes a default database cluster in /var/lib/postgresql/17/main, and configures the PostgreSQL service to start automatically on boot using systemd.

Verify the Installation

After installation completes, verify that the PostgreSQL service runs properly:

systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: enabled)
     Active: active (exited) since Thu 2026-01-16 10:00:00 UTC; 1min ago
    Main PID: 12345 (code=exited, status=0/SUCCESS)
        CPU: 15ms

The active (exited) status is expected behavior for PostgreSQL. The main service unit acts as a wrapper that manages individual database clusters through systemd, while the actual database server runs as a separate process managed by postgresql@17-main.service. To confirm the database accepts connections and verify the installed version, query the server:

sudo -u postgres psql -c "SELECT version();"
                                                   version                                                   
-------------------------------------------------------------------------------------------------------------
 PostgreSQL 17.7 (Ubuntu 17.7-1.pgdg24.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit
(1 row)

The package version string varies by Ubuntu release: 17.7-3.pgdg22.04+1 on Ubuntu 22.04, 17.7-3.pgdg24.04+1 on Ubuntu 24.04, or 17.6-1build1 on Ubuntu 26.04 if using the default repositories. All versions install a compatible PostgreSQL 17.x release with the same core functionality.

If PostgreSQL does not start automatically, enable and start it with the following command:

sudo systemctl enable postgresql --now

Manage the PostgreSQL Service

PostgreSQL runs as a systemd service, which you can manage using standard systemctl commands. Below are the essential operations for controlling the database server:

Stop the PostgreSQL server (for maintenance or troubleshooting):

sudo systemctl stop postgresql

Start the PostgreSQL server:

sudo systemctl start postgresql

Restart the PostgreSQL server (required after most postgresql.conf changes):

sudo systemctl restart postgresql

Alternatively, reload configuration without interrupting active connections. Use reload for changes to pg_hba.conf and runtime-configurable postgresql.conf parameters. This approach is safer for production systems because it does not terminate existing database connections or require downtime:

sudo systemctl reload postgresql

Not all PostgreSQL settings support reload. Parameters like shared_buffers, max_connections, and wal_level require a full restart because they affect PostgreSQL’s core memory allocation or startup behavior.

Check the service status to verify operational state:

systemctl status postgresql

Configure PostgreSQL 17

Access the PostgreSQL Shell

PostgreSQL uses role-based authentication by default. During installation, the system creates a superuser role named postgres along with a corresponding Linux system account. To access the PostgreSQL interactive shell, switch to the postgres user:

sudo -i -u postgres

Once logged in as the postgres user, start the interactive SQL shell:

psql

Your terminal prompt changes to postgres=#, indicating you are now connected to the PostgreSQL database:

psql (17.7 (Ubuntu 17.7-1.pgdg24.04+1))
Type "help" for help.

postgres=#

To exit the psql shell, type:

\q

Then type exit to return to your regular user account.

Alternatively, access the PostgreSQL shell directly without switching users by combining the commands in a single line:

sudo -u postgres psql

This approach saves time for quick database operations and eliminates the need to manage multiple shell sessions.

Create a New Database User

For security best practices, avoid using the postgres superuser for application connections. Instead, create dedicated users with appropriate privileges. This approach limits potential damage if an application is compromised, as the attacker only gains access to the specific privileges assigned to that user rather than full database control. Run the following command, replacing <username> with your desired username:

sudo -u postgres createuser --interactive <username>

The --interactive flag prompts you to specify whether the new user should have superuser, database creation, or role creation privileges:

Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

For a standard application user, answer “no” to all prompts to follow the principle of least privilege. Next, set a password for the new user to enable password authentication:

sudo -u postgres psql -c "ALTER USER <username> WITH PASSWORD 'your_secure_password';"
ALTER ROLE

Create a New Database

Once you create a user, create a database and grant the user access to it. First, create the database with the desired name:

sudo -u postgres createdb <database_name>

Next, grant the new user full privileges on this database to allow them to create tables, insert data, and perform other operations:

sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE <database_name> TO <username>;"
GRANT

To verify the grant succeeded, list all databases and their access privileges:

sudo -u postgres psql -c "\l"
                                                   List of databases
   Name    |  Owner   | Encoding | Collate |  Ctype  | ICU Locale | Locale Provider |   Access privileges   
-----------+----------+----------+---------+---------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | 
 template0 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
 testdb    | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =Tc/postgres         +
           |          |          |         |         |            |                 | postgres=CTc/postgres+
           |          |          |         |         |            |                 | testuser=CTc/postgres
(4 rows)

The Access privileges column shows that testuser has connect (c), temporary table (T), and create (C) privileges on the testdb database.

Enable Remote Access

By default, PostgreSQL only accepts connections from the local machine through the Unix socket or localhost interface. Unix sockets provide faster communication for local applications since they bypass the TCP/IP networking stack. To allow remote connections from other machines on your network, you must modify two configuration files: postgresql.conf to configure the listening address, and pg_hba.conf to define client authentication rules.

Configure the Listening Address

First, open the main PostgreSQL configuration file using a text editor:

sudo nano /etc/postgresql/17/main/postgresql.conf

Within this file, locate the listen_addresses setting (around line 60). By default, it is set to 'localhost', which restricts connections to the local machine. Change it to allow connections from specific addresses or all interfaces:

For a specific IP address (recommended for security):

listen_addresses = 'localhost, 192.168.1.50'

For all network interfaces (use with caution and proper firewall configuration):

listen_addresses = '*'

Once configured, save and close the file (Ctrl+O, Enter, Ctrl+X in nano).

Configure Client Authentication

Next, edit the host-based authentication file to specify which clients can connect, which databases they can access, and what authentication method they must use:

sudo nano /etc/postgresql/17/main/pg_hba.conf

Add a line at the end of the file to allow remote connections. The SCRAM-SHA-256 method is the most secure password authentication option and is recommended for all new PostgreSQL 17 deployments. Unlike the older MD5 method, SCRAM-SHA-256 uses a challenge-response mechanism that prevents password sniffing and provides stronger protection against brute-force attacks:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             all             192.168.1.0/24          scram-sha-256

This configuration allows all users to connect to all databases from the 192.168.1.0/24 subnet using SCRAM-SHA-256 password authentication. Adjust the fields to match your security requirements:

  • Database-Specific Access: Replace all with a specific database name to restrict access to one database.
  • User-Specific Access: Replace all in the USER column with a specific username to limit which users can connect.
  • Address Restrictions: Use specific IP addresses (e.g., 192.168.1.100/32 for a single host) or CIDR ranges (e.g., 192.168.1.0/24 for 256 addresses from 192.168.1.0 to 192.168.1.255) to control which networks can connect. The /32 suffix denotes a single IP, while /24 represents a typical home or office subnet.

Apply the Configuration Changes

After modifying both configuration files, restart PostgreSQL to apply the changes:

sudo systemctl restart postgresql

Then verify that PostgreSQL now listens on the configured addresses using the ss command to check network sockets. The grep command filters the output to show only PostgreSQL’s port:

ss -tlnp | grep 5432
LISTEN 0      244          0.0.0.0:5432      0.0.0.0:*    users:(("postgres",pid=12345,fd=7))

The 0.0.0.0:5432 output indicates PostgreSQL listens on all interfaces. If you configured a specific IP address, you would see that address instead of 0.0.0.0.

Configure UFW Firewall for PostgreSQL

If you plan to allow remote connections to PostgreSQL, configure your firewall to permit traffic on port 5432. This step is only necessary after you enable remote access in the PostgreSQL configuration. For local-only access, no firewall configuration is needed since all connections use Unix sockets or the localhost interface. For a comprehensive guide to firewall management, see our UFW firewall guide for Ubuntu.

First, ensure UFW is installed and enabled on your system:

sudo apt install ufw -y
sudo ufw enable

Warning: Before enabling UFW on a remote server, ensure you allow SSH access with sudo ufw allow ssh. Enabling the firewall without an SSH rule will lock you out of your server, requiring console access to recover.

To allow PostgreSQL connections from a specific IP address (recommended for security):

sudo ufw allow from 192.168.1.100 to any port 5432

Alternatively, to allow connections from an entire subnet:

sudo ufw allow from 192.168.1.0/24 to any port 5432

After adding rules, verify your firewall configuration with the numbered output option:

sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 5432                       ALLOW IN    192.168.1.0/24

To remove a rule, use the rule number shown in the output:

sudo ufw delete 2

Remember to replace the IP addresses and subnet examples with your actual network configuration. Avoid opening port 5432 to the entire internet (sudo ufw allow 5432) unless you implement additional security measures like SSL/TLS encryption, strong authentication, and intrusion detection.

Performance Tuning Basics

PostgreSQL 17’s default configuration is conservative to ensure compatibility with minimal systems. For production servers with adequate resources, adjust these settings in /etc/postgresql/17/main/postgresql.conf to improve performance:

  • shared_buffers: Controls the amount of memory PostgreSQL uses for shared memory buffers. A typical starting point is 25% of total RAM (e.g., shared_buffers = 2GB for an 8GB server). PostgreSQL 17’s improved memory management makes this setting more effective than previous versions. On systems with 32GB or more RAM, you may want to cap this at 8-10GB since PostgreSQL also relies on the operating system’s disk cache.
  • work_mem: Sets memory for internal sorting and hashing operations per query. Start with 64MB for complex queries, but monitor total memory usage since each concurrent operation can use this amount. PostgreSQL 17’s improved sort performance benefits from adequate work_mem settings. Calculate a safe upper limit by dividing available RAM by the maximum expected concurrent queries (e.g., 4GB RAM / 50 connections = 80MB per connection).
  • maintenance_work_mem: Specifies memory for maintenance operations like VACUUM, CREATE INDEX, and ALTER TABLE. PostgreSQL 17’s vacuum improvements mean higher values (e.g., 1GB) can significantly improve performance without the 1GB limitation in earlier versions. On systems with ample RAM, you can safely set this to 1-2GB to speed up maintenance operations.
  • effective_cache_size: Tells the query planner how much memory is available for disk caching by both PostgreSQL and the operating system. Set to approximately 75% of total RAM (e.g., effective_cache_size = 6GB for an 8GB server). This helps PostgreSQL 17’s improved query planner make better decisions about whether to use indexes or sequential scans. This setting does not allocate memory; it only informs the query planner.

After changing these settings, restart PostgreSQL to apply the changes. To check whether a specific parameter requires restart or reload, query PostgreSQL’s system catalog:

sudo -u postgres psql -c "SELECT name, context FROM pg_settings WHERE name IN ('shared_buffers', 'work_mem', 'maintenance_work_mem', 'effective_cache_size');"

The context column shows when changes take effect: postmaster requires restart, sighup allows reload, and user or superuser can change at any time. Then restart PostgreSQL:

sudo systemctl restart postgresql

Troubleshoot Common Issues

Connection Refused Errors

If you receive “connection refused” when trying to connect remotely, you typically see an error like:

psql: error: connection to server at "192.168.1.50", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

To diagnose the issue, check these items systematically:

  1. Verify PostgreSQL is running: Run systemctl status postgresql to check service status
  2. Check listening address: Run ss -tlnp | grep 5432; if output shows only 127.0.0.1:5432, PostgreSQL is not configured for remote access
  3. Verify firewall rules: Run sudo ufw status to confirm port 5432 is allowed from your client IP
  4. Review pg_hba.conf: Ensure the file includes an entry allowing connections from your client IP or subnet

Authentication Failed

If you see a password authentication error, it typically appears as:

psql: error: connection to server at "192.168.1.50", port 5432 failed: FATAL:  password authentication failed for user "testuser"

This issue typically involves one of these causes:

  • Incorrect password: Reset it with ALTER USER username WITH PASSWORD 'newpassword'; in the psql shell
  • Wrong authentication method: Check that pg_hba.conf specifies scram-sha-256 for password authentication (recommended for PostgreSQL 17)
  • User does not exist: Verify with \du in psql to list all roles and their attributes

Repository Issues

If apt update shows errors about the PostgreSQL repository, you may see:

E: The repository 'https://apt.postgresql.org/pub/repos/apt noble-pgdg Release' does not have a Release file.

To resolve this, verify your configuration file:

cat /etc/apt/sources.list.d/postgresql.sources

Ensure the Suites line contains your correct Ubuntu codename followed by -pgdg (e.g., jammy-pgdg for Ubuntu 22.04 or noble-pgdg for Ubuntu 24.04). If you see this error on Ubuntu 26.04, it means the PGDG repository does not yet have a resolute-pgdg branch. This is expected—Ubuntu 26.04 users should not add the PGDG repository at all, since PostgreSQL 17 is already available in Ubuntu 26.04’s default repositories. Remove the PGDG configuration and install directly with sudo apt install postgresql-17.

View PostgreSQL Logs

For detailed error information and debugging, review the PostgreSQL logs. The tail command displays the most recent log entries:

sudo tail -50 /var/log/postgresql/postgresql-17-main.log

Update PostgreSQL 17

PostgreSQL 17 receives updates through standard APT package management. The PostgreSQL team releases minor versions (like 17.1, 17.2) that include bug fixes, security patches, and performance improvements without breaking compatibility with existing applications.

To update PostgreSQL to the latest patch release:

sudo apt update
sudo apt install --only-upgrade postgresql-17 postgresql-client-17

The --only-upgrade flag ensures the command only updates the packages if they already exist, preventing accidental installation on systems where PostgreSQL 17 might have been removed. After updating, verify the new version:

sudo -u postgres psql -c "SELECT version();"

For related PostgreSQL versions, see our guides on installing PostgreSQL 16 on Ubuntu and installing PostgreSQL 15 on Ubuntu.

Remove PostgreSQL 17

When you need to uninstall PostgreSQL 17, you can remove the packages while preserving or deleting your data depending on your requirements.

Remove Packages Only (Preserve Data)

To remove PostgreSQL while keeping your databases and configuration files for a potential reinstall or migration. This option is useful when you plan to upgrade to a newer PostgreSQL version or temporarily remove the software while preserving your data:

sudo apt remove postgresql-17 postgresql-client-17

This preserves the /var/lib/postgresql/17/ directory containing your databases and the /etc/postgresql/17/ directory containing configuration files. Reinstalling PostgreSQL 17 later will recognize these existing files and restore access to your databases automatically.

Complete Removal Including Configuration

To remove PostgreSQL and its configuration files (but not databases):

sudo apt purge postgresql-17 postgresql-client-17
sudo apt autoremove

The autoremove command cleans up dependencies that were installed with PostgreSQL but are no longer needed by any other packages.

Remove Everything Including Databases

Warning: The following commands permanently delete all PostgreSQL databases, user data, and configurations. This action cannot be undone. Back up any important data first using pg_dump for individual databases (pg_dump dbname > backup.sql) or pg_dumpall for complete cluster backups (pg_dumpall > full_backup.sql) before proceeding.

sudo apt purge postgresql-17 postgresql-client-17 postgresql-common
sudo apt autoremove
sudo rm -rf /var/lib/postgresql/
sudo rm -rf /etc/postgresql/

Remove the PostgreSQL Repository

If you no longer need the PostgreSQL APT repository, remove it along with the GPG key:

sudo rm /etc/apt/sources.list.d/postgresql.sources
sudo rm /usr/share/keyrings/postgresql.gpg
sudo apt update

To verify the repository removal succeeded:

apt-cache policy postgresql-17
postgresql-17:
  Installed: (none)
  Candidate: (none)
  Version table:

This output confirms APT no longer has access to the PostgreSQL repository packages.

Conclusion

You have successfully installed PostgreSQL 17 on Ubuntu with the official PGDG repository, providing access to the latest patch releases directly from the PostgreSQL development team. The guide covered repository configuration, database installation, user management, remote access setup, firewall configuration, performance tuning, troubleshooting, and removal procedures. For production use, implement SSL/TLS encryption, automated backups with pg_dump or WAL archiving, connection pooling with PgBouncer, and monitoring solutions like pg_stat_statements to track performance and identify slow queries.

Additional Resources

For more information about PostgreSQL 17 and ongoing maintenance, refer to these official resources:

Leave a Comment

Let us know you are human: