Skip to content
senn-techsenn-tech
Back to blog
Infrastructure
Servers, Proxmox and network2026-11-12· By Franz Senn

PostgreSQL 14 Ends Today: Our Census Found 25 Instances, the Container List Knew 21

PostgreSQL 14 loses support today. The date does not come from one of our calendars but from the project's version table: first release 14.0 on 30 September 2021, end of life 12 November 2026. We took the occasion and read our own estate — no tool list, no trust in identifiers, read-only on every system. Result: 25 Postgres instances on 19 machines. Our habitual count via container names knows 21. The other four are not museum pieces; they run in places no container listing names.

Status of this post

Measured on 12 November 2026 between 08:30 and 09:05 Central European Time on our own systems, read-only via login and reading, without write access, without restarting a service. We probed 207 addresses of our network range; 48 answered. Sixteen of those produced no Postgres process, 159 never answered at all. The census counts what answers, not what exists. The 159 silent addresses are an open boundary in this post, not a zero.

What actually ends on 12 November

The versioning policy says it in two sentences: a major release is supported five years after its first release, after which one final minor appears and the software then counts as unsupported. For major 14 that means: after today's quarterly run there will be no further fix for 14.x — not for the parser, not for replication, not for a decoder.

The state at 09:09 and again at 10:17: the table lists 14.24 as the current minor, the documentation page for 14.25 returns an error code, and the news page's latest entry is the PostgreSQL 19 release candidate 1 from 15 October. So at the time of our measurement today's quarterly package had not arrived; whether it comes, and under which number, is the release team's call.

PostgreSQL trademark, a blue relief of an elephant's head
The project's version table is the only place that sets the end-of-life date. Our drawing of the elephantine comes from the CC0 collection Simple Icons. (Quelle: Simple Icons, file postgresql.svg (CC0))

The real point is not the age of a version but the future it no longer has. 14.19, which we also found, sits five minor releases behind 14.24 and therefore behind every fix since spring. From today, nothing more will be added for that number.

Four counting paths, three different numbers

Had we only taken the container list, we would have reported 21 instances and considered ourselves complete. The path via the process table arrives at 25. In between sit four start methods that appear in no container listing: a rootless podman instance under a user service, and three distribution-native packages a host starts directly under systemd.

Five counting stages on the same fleet, our own measurement of 12 Nov 2026, 08:30Process rows, uncleaned177 · 177Hypervisor echo rows4 · 4Instances after merging25 · 25Visible via container names21 · 21Machines with at least one19 · 190180
The 177 rows are processes, not instances: one Postgres postmaster throws off worker processes for connections, maintenance and replay. The 4 echo rows come from a hypervisor that mirrors its guests. Across 48 answering systems, 25 instances run on 19 machines. (Quelle: our own read-only sweep, 12 Nov 2026)

Coverage of the convenient method: 21 of 25, which computes to 84 percent. That sounds fine and is dangerous as a number, because the missing four are not evenly distributed. They sit exactly with the installations nobody has on the radar while talking about containers.

The four instances no list knew

One runs in a rootless podman. The host has no docker client and no daemon socket; it answered podman. In the process table the service appears via the host's user service manager, and because the container carries its own init hierarchy with systemd, the database sits one level deeper still. This instance reports 14.24, the final minor of 14: the only one on an outdated major, and yet patched current to the day.

Podman trademark, an orange container with a lid
Rootless podman hangs in the user service manager, not at the docker daemon. That is exactly where our list was blind. (Quelle: Simple Icons, file podman.svg (CC0))

Three more instances start as distribution-native packages on ordinary servers, recognisable by the service postgresql@17-main.service, with package states from the distributors' package branch. They run on a major that is current this week and fall through every form of container reasoning entirely. Which database version a host serves is not answered by a look into a container list, but only by a look where processes actually run.

Docker trademark, a blue whale with containers on its back
The docker layer is one of four. Query only that layer and you see 21 of 25. (Quelle: Simple Icons, file docker.svg (CC0))

Twice the same name, two major versions

In every inventory the name is the most common key. We found two containers with exactly the same name, on different machines, at different states: one 14.19, one 17.8. A merge on the name turns that into one entry, and depending on mood the old or the new version survives. In this gap the migration order for the 14.19 disappears.

Bar model in five stages: process rows, hypervisor echo rows, instances after merging, instances visible via container names, machines with at least one instance
Our own drawing of the five stages. Every stage is blind to another; none of them is the truth alone. The values come from the 08:30 measurement. (Quelle: our own measurement)

The hypervisor echoes its guests back

On one virtualised host stood four rows that were not its own instances: the host carries its guests' processes in its own table, recognisable by the path through the guest's container hierarchy. Anyone counting them along reports duplicate instances on the hypervisor and loses them on the guests. We therefore attribute them back to the guest and check every row against the guest list. For all four the proof was unambiguous: these are the same instances that also stood on their own guest.

Proxmox trademark, an orange wordmark
A hypervisor with Linux containers as guests echoes their processes into its own table. Four of our raw entries were such echoes. (Quelle: Simple Icons, file proxmox.svg (CC0))

Our own counting rig undercounted first

We ran the sweep twice: in the morning for the number here, shortly after as a control. The control reported 27 instances, not a second estate but a second counting path. The actual error sat in the key: we merge instances by start method, binary path and container identity, and we peel the identity with a text operation from the hierarchy that yields the first segment before the next separator. If the path begins with a separator, that segment is empty. Three instances a host starts directly under systemd shared the same empty key, and two containers of the same image type did too. From 27 raw entries became 24 keys: three real databases were invisible, exactly the ones on no list anyway.

We swapped the text operation for the full identity and cross-checked against the raw entries. The 25 from 08:30 remain our number; the control proves the mechanics, not a second inventory.

The census in six steps, as we actually ran itPopulation207 addresses, 48 answerProcess huntpostmaster and postgres, perhostLocateexe and hierarchy perprocessRead versionbinary in the process rootMergeidentity plus binary pathCross-checkcontainer names, guest list
Step five is the dangerous one: an empty key struck three of 27 instances in the control run. Step six is the only one that catches it. (Quelle: our own read-only sweep, 12 Nov 2026)

Twenty of 25 on the current state

Version states of our 25 instances, our own measurement of 12 Nov 202617.1120 · 2017.91 · 117.81 · 117.61 · 114.241 · 114.191 · 1020
The two highlighted states sit on major 14 and thus, from today, on a version with no future fixes. The three states 17.9, 17.8 and 17.6 are backlogs inside a still-supported major. (Quelle: our own read-only sweep, 12 Nov 2026)

Twenty instances stand on 17.11, the current minor of the still-supported major. Three run on older minors of the same major — that is catching up, not an alarm. Two stand on 14 and are the only real migration work in this estate: one inside a third-party application where the major comes from the package's manufacturer, not from us; the other on an application whose image is built on 14. In both cases we do not decide the database version alone.

What operators take from this

  1. Build the inventory from the process table, not from a list. An instance exists where a postmaster process runs, regardless of who started it.
  2. Count rootless containers via the user service hierarchy. Whoever queries only the docker daemon misses user-space podman entirely.
  3. Disable the name as a key. Two containers may carry the same name, and our measurement shows they do — even across two majors.
  4. Subtract hypervisor echoes before adding. A host with containers as guests writes their processes into its own table.
  5. Ask for the major, never for the image tag. An image that looks current can carry a major that, from today, receives no more patches.
  6. Read the bind address and the access rules together. One of our instances listens on all addresses, IPv4 and IPv6, and is closed only by its access rules; on another, the system's firewall query reported "inactive" while the same kernel's filter table held 34 rules. A firewall state query is no proof about the firewall.

Three questions coming now

The answers are in the question block above. What does not fit there: we show methods and numbers, not a map of our systems, and we measure states, not utilisation. For the 159 unanswered addresses the boundary stays open, not zero.

Further Reading

Everything about PostgreSQL from the project's own hand, measured on 12 November 2026 at 09:09 and 10:17:

For the two locations where our list was blind, the tools' own documentation:

For completeness on the marks: the three new logo files come from the CC0 collection Simple Icons, version 13, installed via the package manager; we read the package's licence file before installing. The three new files sit unmodified with us; the proxmox file comes from our stock, which holds a colour version.

Two of our own posts build directly on this procedure: why we log our runtimes ourselves instead of guessing them from image tags, and our fleet check against the Brotli flaw in Node.js, the same census method against a different runtime. For the view ahead: PostgreSQL 19 release candidate 1 with the changes a 2027 migration lands in, and what one image annotation decides about a sandbox for anyone who wants to count via podman instead of only using it.

Questions?
Which date actually marks the end of support for PostgreSQL 14?+

The project's version table lists first release 30 September 2021 and end of life 12 November 2026 for major 14. The versioning policy adds: a major is supported five years after first release, plus one final minor, after which it counts as unsupported. The date is not a rumour and not a calendar calculation — it is a statement of the project.

Why does our inventory show fewer Postgres instances than the process census?+

Because most inventories hang on identifiers. A list of running containers sees containers — not a rootless podman managed by the host's user service manager, and not a Postgres instance a distribution's own package starts under systemd. On that path we miss four of 25 instances, one of them precisely the one on 14.24. Its version was current to the day; the location decides whether we see it.

Is an instance on PostgreSQL 14 instantly unsafe after the support date?+

Nothing happens instantly; the database keeps running as it did the day before. What stops are future fixes, including the security fixes that will appear for 17.x in three months and never against 14.x. Risk arrives with the next gap in the decoder, the parser, or replication that then stays unanswered for this instance. A major upgrade is a planning task, not a day-of emergency.