AlmaLinux

Install PostgreSQL 19 on Ubuntu, Debian, Rocky Linux & AlmaLinux

PostgreSQL 19 hit beta on June 4, 2026, and the PGDG repositories already carry packages for Ubuntu, Debian and the RHEL family. That means you can install PostgreSQL 19 today with the same package managers you already use, no source builds. Five minutes to a running cluster, then the fun part: graph queries in plain SQL, an atomic get-or-create, and GROUP BY ALL.

Original content from computingforgeeks.com - post 168674

Everything here was built and run on fresh Ubuntu 26.04, Ubuntu 24.04, Debian 13 and Rocky Linux 10 servers in June 2026. Keep beta builds away from production data; GA is expected around September/October per the official announcement. If you need a production cluster today, the PostgreSQL 18 install is the one to follow.

What’s new in PostgreSQL 19

The release notes are long. These are the items that change how you write SQL and run clusters:

  • SQL/PGQ property graph queries: CREATE PROPERTY GRAPH over ordinary tables, then GRAPH_TABLE with match patterns. Graph traversal without a graph database.
  • INSERT ... ON CONFLICT DO SELECT ... RETURNING: get-or-create in one atomic statement. The conflicting row comes back, optionally locked with FOR UPDATE.
  • GROUP BY ALL: groups by every non-aggregate column in the target list. No more repeating column lists.
  • UPDATE/DELETE FOR PORTION OF: temporal updates that split range rows for you.
  • IGNORE NULLS for window functions: lead, lag, first_value, last_value and nth_value can finally skip gaps.
  • REPACK: one command replacing VACUUM FULL and CLUSTER, with a nonblocking CONCURRENTLY option.
  • Online data checksums: enable or disable checksums on a running cluster, no offline pg_checksums window.
  • Operational wins: asynchronous I/O workers that auto-scale, parallel autovacuum, logical replication of sequences, and switching to logical replication without a restart.

Defaults moved too. JIT is now off by default, TOAST compression defaults to lz4, and max_locks_per_transaction doubled to 128. The comparison table at the end has the full list, verified live on the beta.

Install PostgreSQL 19 on Ubuntu 26.04 / 24.04

Ubuntu’s own archive stops at PostgreSQL 18, so the packages come from PGDG. Start with the repo helper:

sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y

The helper writes /etc/apt/sources.list.d/pgdg.sources keyed to your release codename, resolute on 26.04 or noble on 24.04. Pre-release majors live in a separate 19 repo component, one edit away:

sudo sed -i 's/^Components: main$/Components: main 19/' /etc/apt/sources.list.d/pgdg.sources

Refresh and install:

sudo apt update
sudo apt install -y postgresql-19

Debian packaging creates and starts a cluster during install. Confirm it:

pg_lsclusters

The cluster reports online on port 5432:

Ver Cluster Port Status Owner    Data directory              Log file
19  main    5432 online postgres /var/lib/postgresql/19/main /var/log/postgresql/postgresql-19-main.log

One more check straight from the server:

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

You get the full beta build string:

 PostgreSQL 19beta1 (Ubuntu 19~beta1-1.pgdg26.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 15.2.0-16ubuntu1) 15.2.0, 64-bit

Here is the whole flow on the 26.04 box, end to end:

PostgreSQL 19 installed from PGDG and verified on Ubuntu 26.04

Ubuntu 24.04 takes the exact same commands; the only difference is the pgdg24.04 suffix in the version string.

Install on Debian 13 / 12

Debian rides the same PGDG flow, with the codename swapped automatically (trixie on 13, bookworm on 12). The whole sequence, identical to Ubuntu:

sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
sudo sed -i 's/^Components: main$/Components: main 19/' /etc/apt/sources.list.d/pgdg.sources
sudo apt update && sudo apt install -y postgresql-19

The cluster comes up on its own here too, and the version check shows the Debian build:

 PostgreSQL 19beta1 (Debian 19~beta1-1.pgdg13+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 14.2.0-19) 14.2.0, 64-bit

The run on the trixie box, start to finish:

PostgreSQL 19 installed from PGDG and verified on Debian 13

PGDG publishes the same 19 component for bookworm (19~beta1-1.pgdg12+1 at the time of writing), so Debian 12 follows along with zero changes. That closes out the apt side; the RHEL family works a little differently.

Install on Rocky Linux 10 / AlmaLinux 10

The RHEL family pulls from the PGDG yum repos. One thing you can drop from muscle memory: EL10 has no modularity, so the dnf module disable postgresql step that every EL9 guide carries is gone. Add the repo RPM:

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-x86_64/pgdg-redhat-repo-latest.noarch.rpm

Until GA there is no plain pgdg19 repo; beta packages sit in pgdg19-updates-testing, which ships disabled. Enable it just for this install:

sudo dnf install -y postgresql19-server --enablerepo=pgdg19-updates-testing

RHEL packaging initializes nothing on its own. Create the cluster and start the service:

sudo /usr/pgsql-19/bin/postgresql-19-setup initdb
sudo systemctl enable --now postgresql-19

Then verify the build:

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

The Red Hat build string confirms 19beta1:

 PostgreSQL 19beta1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4), 64-bit

SELinux stayed enforcing the whole time. On the default port and data directory, PostgreSQL 19 runs without a single boolean or context change. AlmaLinux 10 uses the same EL-10 repo RPM and identical commands.

PostgreSQL 19 installed from PGDG yum testing repo on Rocky Linux 10 with SELinux enforcing

Both families are now on the same beta build. Time to see what it can do.

Take the new SQL for a spin

Straight to it. The atomic get-or-create first, since every app has one. Create a table and insert a user:

CREATE TABLE users (id serial PRIMARY KEY, email text UNIQUE, created_at timestamptz DEFAULT now());
INSERT INTO users (email) VALUES ('[email protected]') RETURNING id;

That returns id 1. Run the same insert again, and instead of a conflict error or a silent no-op, ask for the existing row back:

INSERT INTO users (email) VALUES ('[email protected]')
  ON CONFLICT (email) DO SELECT RETURNING id, email, created_at;

One statement, no race window, the original row comes back:

 id |       email       |          created_at
----+-------------------+-------------------------------
  1 | [email protected] | 2026-06-11 22:04:23.728454+00
(1 row)

Before 19 this took DO UPDATE SET email = excluded.email hacks or a second query. Next, GROUP BY ALL on a small deployments table:

CREATE TABLE deploys (env text, app text, duration_ms int);
INSERT INTO deploys VALUES ('prod','api',420),('prod','web',310),('staging','api',95),('staging','web',88);
SELECT env, app, avg(duration_ms) FROM deploys GROUP BY ALL;

Every non-aggregate column joins the grouping automatically:

   env   | app |         avg
---------+-----+----------------------
 staging | api |  95.0000000000000000
 prod    | api | 420.0000000000000000
 staging | web |  88.0000000000000000
 prod    | web | 310.0000000000000000
(4 rows)

The session below also shows IGNORE NULLS carrying the last known sensor value across gaps, a pattern that used to need a correlated subquery:

PostgreSQL 19 ON CONFLICT DO SELECT, GROUP BY ALL and IGNORE NULLS tested in psql

Now the headline act: property graphs. Model a service mesh as two ordinary tables, declare a graph over them, and query reachability:

CREATE TABLE services (id int PRIMARY KEY, name text);
CREATE TABLE calls (caller int REFERENCES services(id), callee int REFERENCES services(id), PRIMARY KEY (caller, callee));
INSERT INTO services VALUES (1,'frontend'),(2,'api'),(3,'auth'),(4,'db');
INSERT INTO calls VALUES (1,2),(2,3),(2,4),(3,4);

CREATE PROPERTY GRAPH service_map
  VERTEX TABLES (services KEY (id) LABEL service PROPERTIES (name))
  EDGE TABLES (
    calls KEY (caller, callee)
      SOURCE KEY (caller) REFERENCES services (id)
      DESTINATION KEY (callee) REFERENCES services (id)
      LABEL calls
  );

Which services talk to the database directly? Match the pattern:

SELECT * FROM GRAPH_TABLE (service_map
  MATCH (a IS service)-[IS calls]->(b IS service WHERE b.name = 'db')
  COLUMNS (a.name AS caller)
) ORDER BY caller;

Two callers, found by graph pattern instead of joins:

 caller
--------
 api
 auth
(2 rows)

One real limit found in testing: variable-length paths are not in the beta yet. A quantified pattern like -[IS calls]->{1,2} fails with ERROR: element pattern quantifier is not supported, so multi-hop traversal still needs a recursive CTE for now. Single-hop matching works, and since graphs are processed like views, the planner treats them as regular relational queries. If you are building retrieval pipelines, this pairs nicely with pgvector and the self-hosted RAG stack already running on PostgreSQL.

Two more worth a try while you are in the session: COPY (SELECT * FROM deploys) TO STDOUT WITH (FORMAT json) emits one JSON object per row, and REPACK deploys; rebuilds the table where you would have reached for VACUUM FULL.

Allow remote connections

The beta listens on localhost only, like every PostgreSQL before it. For LAN access, flip listen_addresses without touching a config file:

sudo -u postgres psql -c "ALTER SYSTEM SET listen_addresses = '*';"

Then add a client rule. On Ubuntu and Debian the access file lives under /etc/postgresql/19/main/; append your subnet and restart:

echo 'host all all 10.0.1.0/24 scram-sha-256' | sudo tee -a /etc/postgresql/19/main/pg_hba.conf
sudo systemctl restart postgresql@19-main

On Rocky and AlmaLinux the file sits in the data directory:

echo 'host all all 10.0.1.0/24 scram-sha-256' | sudo tee -a /var/lib/pgsql/19/data/pg_hba.conf
sudo systemctl restart postgresql-19

Open TCP port 5432. Ubuntu ships ufw, and Debian can use the same after an apt install ufw:

sudo ufw allow 5432/tcp

The RHEL family uses firewalld, which ships a ready-made service definition:

sudo firewall-cmd --add-service=postgresql --permanent
sudo firewall-cmd --reload

That’s it. For anything beyond a test box, put real HA underneath with the Patroni cluster guide and wire up point-in-time recovery before you trust it with data.

PostgreSQL 19 vs PostgreSQL 18 at a glance

Every value in the 19 column was read live off the beta cluster with SHOW, not copied from docs:

Setting / behaviorPostgreSQL 18PostgreSQL 19
JIT compilationon by defaultjit = off
TOAST compressionpglzlz4
max_locks_per_transaction64128
I/O workersfixed io_workersauto-scaling, io_min_workers=2 to io_max_workers=8
Data checksumson at initdb, offline to changeon, toggleable on a running cluster
Table rebuildVACUUM FULL / CLUSTERREPACK, with CONCURRENTLY
Get-or-createON CONFLICT DO UPDATE workaroundON CONFLICT DO SELECT
Graph queriesrecursive CTEsSQL/PGQ GRAPH_TABLE
md5 passwordswarns when setting one; login is silentdeprecation warning on login too
RADIUS authsupportedremoved

When GA lands, the packages have historically moved into the default repo components, so a plain apt upgrade or dnf upgrade carries these same installs forward. Until then, this beta is the cheapest way to find out whether the JIT default flip or the md5 warnings will touch your stack before they reach production.

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 24.04 / 22.04 Security UFW Firewall Commands with Examples on Ubuntu 24.04 / 22.04 Ubuntu 26.04 LTS (Resolute Raccoon): New Features, Changes, and What to Know Ubuntu Ubuntu 26.04 LTS (Resolute Raccoon): New Features, Changes, and What to Know MariaDB High Availability Cluster: Galera, HAProxy, Keepalived Databases MariaDB High Availability Cluster: Galera, HAProxy, Keepalived Set Up PostgreSQL High Availability with Patroni and HAProxy Databases Set Up PostgreSQL High Availability with Patroni and HAProxy Install RavenDB NoSQL database on Ubuntu 22.04|20.04 Databases Install RavenDB NoSQL database on Ubuntu 22.04|20.04

Leave a Comment

Press ESC to close