PostgreSQL 16 is the default PostgreSQL branch on Ubuntu 24.04, while Ubuntu 22.04 stays on PostgreSQL 14 and Ubuntu 26.04 has moved to PostgreSQL 18. If you need to install PostgreSQL 16 on Ubuntu for application compatibility, extension support, or a controlled major-version upgrade path, use the default Ubuntu package on 24.04 or the official PGDG repository across 26.04, 24.04, and 22.04.
PostgreSQL 16 remains supported by the PostgreSQL project through November 9, 2028. You will install the server and client tools, verify the active cluster, cover optional local users and remote access, and review update and removal paths without hiding database-deletion risks.
Install PostgreSQL 16 on Ubuntu
Compare PostgreSQL Versions for Ubuntu
Start by confirming that PostgreSQL 16 is the branch your application needs. The default PostgreSQL branch changes by Ubuntu release, so the simplest install path is not identical everywhere.
| PostgreSQL Version | Availability on Ubuntu | Choose It When | Trade-offs |
|---|---|---|---|
| PostgreSQL 15 | PGDG repository on 26.04, 24.04, and 22.04 | Your application still depends on the 15 series or has not completed extension testing on newer branches | Older branch; final PostgreSQL project release is scheduled for November 11, 2027 |
| PostgreSQL 16 | Ubuntu 24.04 default; PGDG on 26.04, 24.04, and 22.04 | You need the 16 series for application compatibility, staged upgrades, or a stable production target | PGDG is required on Ubuntu 26.04 and 22.04; Ubuntu 24.04 can use the default repository |
| PostgreSQL 17 | PGDG repository on 26.04, 24.04, and 22.04 | You need PostgreSQL 17 features such as incremental backup improvements | Not the default PostgreSQL branch on current Ubuntu LTS releases |
| PostgreSQL 18 | Ubuntu 26.04 default; PGDG on 26.04, 24.04, and 22.04 | You want the newest stable PostgreSQL branch and your application stack supports it | Newest branch; extension and vendor-support checks may take extra work |
Choose PostgreSQL 16 when your application, hosted platform, backup tooling, or extension stack is already certified for the 16 series. If you only need the default database server for a new project, Ubuntu 26.04 users should usually consider PostgreSQL 18 instead, while Ubuntu 24.04 users can install PostgreSQL 16 from the standard repositories.
Choose a PostgreSQL 16 Install Method
Use the Ubuntu repository method only on Ubuntu 24.04, where postgresql-16 is a standard package. Use PGDG when you need PostgreSQL 16 on Ubuntu 26.04 or 22.04, or when you want the same upstream PostgreSQL APT source across multiple Ubuntu releases.
| Method | Ubuntu Releases | Update Source | Best Fit |
|---|---|---|---|
| Ubuntu default repository | 24.04 only | Ubuntu security and updates pockets | Simple 24.04 installs that should stay inside Ubuntu’s normal package flow |
| PGDG APT repository | 26.04, 24.04, and 22.04 | PostgreSQL Global Development Group APT repository | Exact PostgreSQL 16 installs on 26.04, 24.04, and 22.04, or environments already using PGDG |
Update Ubuntu Before Installing PostgreSQL 16
Refresh package metadata and apply pending upgrades before installing database packages:
sudo apt update && sudo apt upgrade -y
If your account does not have sudo access yet, follow the guide to add a user to sudoers on Ubuntu.
Method 1: Install PostgreSQL 16 from Ubuntu 24.04 Repositories
On Ubuntu 24.04, install the server and client packages directly from Ubuntu’s default repositories:
sudo apt install postgresql-16 postgresql-client-16
Confirm the package source if you want to verify that APT is using Ubuntu’s repository instead of an external source:
apt-cache policy postgresql-16
Relevant output on Ubuntu 24.04 includes:
postgresql-16:
Installed: (none)
Candidate: 16.13-0ubuntu0.24.04.1
Version table:
16.13-0ubuntu0.24.04.1 500
500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
500 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages
After installation, use the shared verification commands that follow. On Ubuntu 26.04 and 22.04, continue with PGDG for an exact PostgreSQL 16 package because the default PostgreSQL branches differ.
Method 2: Install PostgreSQL 16 from the PGDG Repository
The PGDG repository provides PostgreSQL 16 packages for Ubuntu 26.04, 24.04, and 22.04. This path is required for exact PostgreSQL 16 installs on 26.04 and 22.04, and it is optional on 24.04 if you prefer PGDG’s repository over Ubuntu’s package source.
Install Required Packages for PGDG
Install the packages needed to download the repository key over HTTPS. The curl command fetches the key, and ca-certificates lets APT validate TLS certificates when it contacts the repository:
sudo apt install curl ca-certificates -y
Import the PostgreSQL PGDG Signing Key
The PostgreSQL team signs packages from the PGDG repository. Store the official ASCII-armored repository key in the path used by the PostgreSQL Ubuntu download instructions:
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -fsSLo /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc
This stores the signing key at /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc, which the DEB822 source file references with Signed-By.
Add the PostgreSQL PGDG APT Source
With the key in place, add the official PostgreSQL APT repository as a DEB822 source. This command uses your Ubuntu codename from /etc/os-release and your system architecture from dpkg:
. /etc/os-release
printf '%s\n' \
'Types: deb' \
'URIs: https://apt.postgresql.org/pub/repos/apt' \
"Suites: ${VERSION_CODENAME}-pgdg" \
'Components: main' \
"Architectures: $(dpkg --print-architecture)" \
'Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc' \
| sudo tee /etc/apt/sources.list.d/pgdg.sources > /dev/null
Inspect the source file if you want to confirm the generated codename and architecture:
cat /etc/apt/sources.list.d/pgdg.sources
Relevant output on Ubuntu 26.04 includes:
Types: deb URIs: https://apt.postgresql.org/pub/repos/apt Suites: resolute-pgdg Components: main Architectures: amd64 Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc
The printf output pipes through sudo tee because normal shell redirection cannot write to /etc/apt/sources.list.d/ with root privileges. Refresh the package index after writing the source file:
sudo apt update
Relevant output includes the PGDG suite for your release:
Get:1 https://apt.postgresql.org/pub/repos/apt resolute-pgdg InRelease [180 kB] Get:2 https://apt.postgresql.org/pub/repos/apt resolute-pgdg/main amd64 Packages Reading package lists...
Verify the PostgreSQL 16 PGDG Candidate
Before installing, confirm that APT sees PostgreSQL 16 from PGDG:
apt-cache policy postgresql-16
postgresql-16:
Installed: (none)
Candidate: 16.13-1.pgdg26.04+2
Version table:
16.13-1.pgdg26.04+2 500
500 https://apt.postgresql.org/pub/repos/apt resolute-pgdg/main amd64 Packages
Ubuntu 24.04 currently shows 16.13-1.pgdg24.04+1, and Ubuntu 22.04 shows 16.13-1.pgdg22.04+1. The important part is the source line from https://apt.postgresql.org/pub/repos/apt.
Install PostgreSQL 16 Packages from PGDG
Install both packages on any host that will run the database locally. The client package also provides psql, pg_dump, and pg_restore:
sudo apt install postgresql-16 postgresql-client-16
APT installs PostgreSQL 16 along with required dependencies. During installation, the package creates a postgres system user, initializes the default 16/main database cluster, and configures the PostgreSQL wrapper service to start automatically on boot.
Verify the PostgreSQL 16 Installation
After installation completes, verify that the wrapper service is active and enabled:
systemctl is-active postgresql
systemctl is-enabled postgresql
A healthy install returns:
active enabled
The main postgresql systemd unit is a wrapper that manages individual database clusters. Confirm that the PostgreSQL 16 cluster accepts local connections by querying the server version:
sudo -u postgres psql -c "SELECT version();"
version ------------------------------------------------------------------------------------------------------------- PostgreSQL 16.13 (Ubuntu 16.13-1.pgdg26.04+2) on x86_64-pc-linux-gnu (1 row)
Ubuntu 24.04 prints 16.13-0ubuntu0.24.04.1 when you use the Ubuntu repository method, or 16.13-1.pgdg24.04+1 when you use PGDG. Ubuntu 22.04 prints 16.13-1.pgdg22.04+1 after PGDG setup.
If PostgreSQL does not start automatically, enable and start it manually:
sudo systemctl enable postgresql --now
Install Only PostgreSQL 16 Client Tools
If this machine only needs psql, pg_dump, and related client utilities for remote administration or backups, install the client package without the local server package:
sudo apt install postgresql-client-16
On Ubuntu 26.04 and 22.04, configure PGDG first so APT can find postgresql-client-16. On Ubuntu 24.04, the client package is available from Ubuntu’s default repositories.
Manage the PostgreSQL Service
Once installed, PostgreSQL runs as a systemd-managed service. Use these commands for routine maintenance:
Stop the PostgreSQL server (for maintenance or configuration changes):
sudo systemctl stop postgresql
Start the PostgreSQL server:
sudo systemctl start postgresql
Restart the PostgreSQL server (required after postgresql.conf changes):
sudo systemctl restart postgresql
Alternatively, reload configuration without restarting (for pg_hba.conf changes and some postgresql.conf parameters):
sudo systemctl reload postgresql
Check the service status:
systemctl status postgresql
Configure PostgreSQL 16
Access the PostgreSQL Shell
PostgreSQL uses role-based authentication. During installation, the system creates a superuser role named postgres along with a corresponding Linux system account. To access the PostgreSQL interactive shell, first 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 (16.13 (Ubuntu 16.13-1.pgdg26.04+2)) Type "help" for help. postgres=#
To exit the psql shell, type:
\q
Afterward, type exit to return to your regular user account.
Alternatively, access the PostgreSQL shell directly without switching users by combining the commands:
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
Avoid using the postgres superuser for application connections. Create a dedicated role instead, 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:
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:
sudo -u postgres createdb <database_name>
Next, grant the new user full privileges on this database:
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE <database_name> TO <username>;"
GRANT
Verify the grant by listing databases and 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
myappdb | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | =Tc/postgres +
| | | | | | | postgres=CTc/postgres+
| | | | | | | myuser=CTc/postgres
(4 rows)
In this output, the Access privileges column shows that the user has connect (c), temporary table (T), and create (C) privileges on the database.
Enable Remote Access
By default, PostgreSQL only accepts connections from the local machine. To allow remote connections, you must modify two configuration files: postgresql.conf to change the listening address, and pg_hba.conf to configure client authentication.
Configure the Listening Address
First, open the main PostgreSQL configuration file:
sudo nano /etc/postgresql/16/main/postgresql.conf
Within this file, locate the listen_addresses setting. By default, it is set to 'localhost'. Change it to allow connections from specific addresses or all interfaces:
For a specific IP address (more secure):
listen_addresses = 'localhost, 192.168.1.50'
For all network interfaces (use with caution):
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 and how they authenticate:
sudo nano /etc/postgresql/16/main/pg_hba.conf
Then, 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 deployments:
# 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 database, user, and address fields to match your security requirements:
- User-Specific Access: Replace
allwith a specific username to restrict access. - Database-Specific Access: Specify a particular database instead of
all. - Address Restrictions: Use specific IP addresses or CIDR ranges to limit connections.
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:
sudo ss -tlnp | grep ':5432'
LISTEN 0 244 0.0.0.0:5432 0.0.0.0:* users:(("postgres",pid=...,fd=...))
In this example, the 0.0.0.0:5432 output indicates PostgreSQL listens on all interfaces. If you configured a specific IP, you would see that address instead.
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. For a comprehensive guide to firewall management, see our UFW firewall guide for Ubuntu.
Install UFW if needed, allow SSH before enabling the firewall on a remote server, and then enable UFW:
sudo apt install ufw -y
sudo ufw allow ssh
sudo ufw enable
To allow PostgreSQL connections from a specific IP address (recommended for security):
sudo ufw allow from 192.168.1.100 to any port 5432 proto tcp
Alternatively, to allow connections from an entire subnet:
sudo ufw allow from 192.168.1.0/24 to any port 5432 proto tcp
After adding rules, verify your firewall configuration:
sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] 22/tcp ALLOW IN Anywhere
[ 2] 5432/tcp ALLOW IN 192.168.1.0/24
If needed, you can remove a rule using the rule number shown in the output:
sudo ufw delete 2
Replace the example IP addresses with your actual network. Avoid opening port 5432 to the entire internet with a broad rule such as sudo ufw allow 5432 unless you have a separate security design for TLS, strong authentication, monitoring, and network restrictions.
Performance Tuning Basics
By default, PostgreSQL’s configuration is conservative to work on minimal systems. For better performance on production servers, consider adjusting these settings in /etc/postgresql/16/main/postgresql.conf:
- shared_buffers: Sets the amount of memory PostgreSQL uses for shared memory buffers. A typical starting point is 25% of total RAM (e.g.,
shared_buffers = 2GBfor an 8GB server). - work_mem: Controls memory for internal sorting and hashing operations per query. Start with 64MB for complex queries, but monitor total memory usage since each query can use this amount.
- max_connections: Limits concurrent database connections. The default of 100 works for most applications; increase only if needed, as each connection consumes resources.
- effective_cache_size: Tells the query planner how much memory is available for caching. Set to approximately 75% of total RAM (e.g.,
effective_cache_size = 6GBfor an 8GB server).
After changing these settings, restart PostgreSQL:
sudo systemctl restart postgresql
Troubleshoot Common Issues
Connection Refused Errors
If you receive “connection refused” when trying to connect remotely:
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 the service, listener, firewall, and host-based authentication file in order:
systemctl is-active postgresql
sudo ss -tlnp | grep ':5432'
sudo ufw status numbered
sudo tail -50 /var/log/postgresql/postgresql-16-main.log
If the listener shows only 127.0.0.1:5432, PostgreSQL is still local-only. If UFW does not show a rule for the client IP or subnet, add the narrower TCP rule shown in the firewall section. If both checks pass, review /etc/postgresql/16/main/pg_hba.conf and make sure it includes the connecting client address.
Authentication Failed
If you see a password authentication error:
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'; - Wrong authentication method: Check that pg_hba.conf specifies
scram-sha-256ormd5for password authentication - User does not exist: Verify with
\duin psql to list all roles
Peer Authentication Failed for postgres
Ubuntu’s local PostgreSQL setup commonly uses peer authentication for the postgres role. If psql -U postgres fails locally, run the command as the matching Linux account instead:
sudo -u postgres psql
Use password authentication for application roles and remote clients, not for routine local administration with the postgres system account.
Repository Issues
If apt update shows a repository error such as does not have a Release file, verify the source file, refresh package metadata, and then check whether APT can see postgresql-16:
cat /etc/apt/sources.list.d/pgdg.sources
sudo apt update
apt-cache policy postgresql-16
Ensure the Suites line contains your correct Ubuntu codename followed by -pgdg, such as resolute-pgdg for Ubuntu 26.04, noble-pgdg for Ubuntu 24.04, or jammy-pgdg for Ubuntu 22.04. Rerun sudo apt update after fixing the file so APT ingests the corrected source before you check the package policy again.
View PostgreSQL Logs
For detailed error information, review the PostgreSQL logs. The tail command displays the most recent entries:
sudo tail -50 /var/log/postgresql/postgresql-16-main.log
Update PostgreSQL 16
PostgreSQL 16 receives minor releases through the package source you selected. Ubuntu 24.04 default installs update through Ubuntu’s normal security and updates pockets, while PGDG installs update through the PostgreSQL APT repository.
To update PostgreSQL 16 packages when they are already installed:
sudo apt update
sudo apt install --only-upgrade postgresql-16 postgresql-client-16
The --only-upgrade flag updates the packages only when they already exist, preventing accidental installation on systems where PostgreSQL 16 might have been removed.
After updating, verify the new version:
sudo -u postgres psql -c "SELECT version();"
For adjacent branches, see the guides to install PostgreSQL 15 on Ubuntu and install PostgreSQL 17 on Ubuntu.
Remove PostgreSQL 16
PostgreSQL package removal can preserve or delete database clusters. Decide which state you want before running purge commands, especially on production systems.
Remove Packages Only (Preserve Data)
To remove the server and client packages while keeping the PostgreSQL 16 data and configuration directories:
sudo apt remove postgresql-16 postgresql-client-16
This approach allows reinstallation later without losing the 16/main cluster under /var/lib/postgresql/16/ and its configuration under /etc/postgresql/16/.
Purge PostgreSQL 16 Packages
To purge package configuration, run:
sudo apt purge postgresql-16 postgresql-client-16
If APT asks whether to remove PostgreSQL directories, answer
nounless you have verified backups and intend to delete the database cluster. The prompt controls cluster data, configuration, and logs, not only package metadata.
Preview dependency cleanup before removing anything else:
sudo apt autoremove --dry-run
If the preview only lists PostgreSQL dependencies you no longer need, run the cleanup:
sudo apt autoremove
The autoremove command cleans up dependencies that were installed with PostgreSQL and are no longer required. Review APT’s package list before confirming on shared servers.
Remove PostgreSQL 16 Including Databases
The next commands permanently delete the PostgreSQL 16 cluster, including databases, configuration, and logs. Back up important data first with
pg_dump,pg_dumpall, or your normal backup process.
sudo pg_dropcluster --stop 16 main
sudo apt purge postgresql-16 postgresql-client-16
The pg_dropcluster command removes the 16/main cluster through PostgreSQL’s own tooling before package purge runs. If you created additional PostgreSQL 16 clusters, list them first with pg_lsclusters and remove only the clusters you intend to delete.
Preview dependency cleanup after the purge:
sudo apt autoremove --dry-run
If the preview only lists PostgreSQL dependencies you no longer need, run:
sudo apt autoremove
Remove the PostgreSQL Repository
If you used PGDG and no longer need that repository, remove the source file and signing key. The command also removes older PostgreSQL source and keyring paths used by previous instructions when they exist:
sudo rm -f /etc/apt/sources.list.d/pgdg.sources /etc/apt/sources.list.d/postgresql.sources
sudo rm -f /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc /usr/share/keyrings/postgresql.gpg
sudo rmdir /usr/share/postgresql-common/pgdg 2>/dev/null || true
sudo apt update
After running apt update, verify the repository removal succeeded:
apt-cache policy postgresql-16
On Ubuntu 26.04 or 22.04, where PGDG supplied the PostgreSQL 16 packages, APT may return:
N: Unable to locate package postgresql-16
This output confirms APT no longer has access to PostgreSQL 16 from PGDG. On Ubuntu 24.04, APT may still show the Ubuntu repository candidate because postgresql-16 is available from the default repositories.
Conclusion
PostgreSQL 16 now installs on Ubuntu 24.04 from the default repositories or on Ubuntu 26.04, 24.04, and 22.04 through the PGDG APT repository. Keep minor releases current with APT, review the PostgreSQL documentation and PostgreSQL community resources when planning SSL/TLS, backups, monitoring, or major upgrades, and avoid exposing port 5432 beyond trusted clients unless the server has a complete security plan.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>