04 Data & storage
PostgreSQL
Thirty years of not losing anybody's data, under a licence nobody can revoke.
- Role
- Relational database
- Licence
- PostgreSQL Licence
- Since
- 1996
- Upstream
- Project site ↗
Almost everything we build stores its durable state in PostgreSQL. Redmine, Nextcloud, every Rails application, and the reporting that sits on top of them.
Why we still choose it
Because it is the most boring correct choice available, and correctness is the only thing a database is for. Three decades of development, a development group that answers to nobody’s quarterly targets, and a permissive licence that cannot be withdrawn or repriced.
It has also quietly absorbed most of the reasons people used to run a second
system alongside it. JSONB covers the document workloads that once needed
MongoDB. Full-text search covers a great deal of what people reach for
Elasticsearch to do. Range types, exclusion constraints, materialised views,
logical replication and window functions mean the interesting work happens in
one place, with one backup, one restore procedure and one thing to patch.
For an organisation trying to reduce the number of moving parts, that consolidation is worth more than any individual feature.
How we run it
On NixOS, declared in your repository alongside everything else, with
services.postgresqlBackup writing nightly dumps that we restore-test monthly
and send you the evidence for. Tuning is written down rather than folklore, and
connection pooling goes in when the numbers say so rather than by default.
On versions
We run the current stable release in production — PostgreSQL 18 at the time of writing — and track the next major through its beta cycle so that upgrades are planned rather than discovered. PostgreSQL 19 is in beta as this page is published, and we are testing against it; it goes under client data when it is released and has had a point release, not before.
That is a deliberate policy rather than caution for its own sake. A database is the one component where being second to adopt costs almost nothing and being first can cost everything.
The honest limit
PostgreSQL will not save you from a bad schema, and it is not the right answer
for genuinely enormous analytical workloads or for data that is a poor fit for
relations. It also rewards someone knowing how to operate it — VACUUM,
connection limits and index maintenance are real responsibilities. That is part
of what you are paying us for.