The PostgreSQL Cluster
In PostgreSQL, the word "cluster" does not mean a group of networked machines the way it does almost everywhere else in database vocabulary.
Search across all documentation pages
In PostgreSQL, the word "cluster" does not mean a group of networked machines the way it does almost everywhere else in database vocabulary.
It means the single running server instance, and everything that instance owns: its data directory, its shared memory, its roles, and every database created inside it.
initdb, holding all the databases, roles, and shared memory that instance manages together.max_connections as a shared budget, or planning multi-tenant isolation.Every PostgreSQL server starts life with a single command: initdb.
That command creates a directory on disk, conventionally called PGDATA, and everything the server instance will ever manage lives inside it.
This PGDATA directory, plus the running postmaster process that serves it, is what the word "cluster" refers to in PostgreSQL.
A useful analogy is an office building: the cluster is the building itself, databases are the floors, schemas are the rooms on each floor, and tables are the filing cabinets inside each room.
One building has one lobby, one set of elevators, and one security desk, no matter how many floors it has.
In the same way, one cluster has one postmaster process, one shared memory region, and one set of roles, no matter how many databases live inside it.
CREATE DATABASE does not start a new server process or allocate a separate chunk of shared memory.
It copies a template database (template1 by default) into a new database entry inside the same running instance.
That single, shared instance is also why the term is confusing at first: it has nothing to do with high-availability clustering, replica sets, or Patroni-managed failover groups, which are a completely different, higher-level concept built on top of individual clusters.
A single postgresql.conf file governs the entire cluster, so settings like shared_buffers and max_connections are cluster-wide budgets, not per-database allowances.
ALTER DATABASE ... SET and ALTER ROLE ... SET let you override specific settings for one database or role, but they layer on top of the cluster-wide defaults rather than replacing the shared instance underneath them.
Roles are the sharpest example of this shared scope, because a role created in one database is visible and usable from every database in the cluster, even though its object-level privileges are typically granted per database.
A backend process connects to exactly one database at a time, and there is no built-in cross-database JOIN; reaching into another database in the same cluster requires dblink or a foreign data wrapper, treating it almost like a remote server.
-- Cluster-wide facts vs per-database facts
SHOW data_directory; -- one path, whole cluster
SELECT datname FROM pg_database; -- every database this cluster owns
SELECT rolname FROM pg_roles; -- roles are visible cluster-wideTablespaces let you place individual databases, tables, or indexes on different physical disks while staying inside the same logical cluster, which is a storage-layout decision rather than an isolation decision.
WAL (write-ahead log) is generated as a single, cluster-wide stream, which is exactly why replication and point-in-time recovery are configured once per cluster rather than once per database.
Because the WAL stream and the shared buffer pool are both cluster-wide, a spike of write activity in one database directly competes for the same I/O and memory budget as every other database on that instance.
Major-version upgrades operate on the whole cluster at once, since pg_upgrade migrates every database in PGDATA together and there is no way to run PostgreSQL 17 for one database and PostgreSQL 18 for another inside the same instance.
That single-version constraint is a real planning input for multi-tenant systems, because it means every tenant sharing a cluster is forced onto the same upgrade schedule whether or not they are ready for it.
max_connections is the sharpest shared-resource constraint in practice, since it is set once for the whole cluster and every database, every role, and every application competes for the same pool of backend slots, which is exactly why connection pooling matters even on a lightly loaded cluster.
Backup granularity follows the same split as everything else: pg_basebackup captures the entire cluster as a physical unit, while pg_dump can target a single database for a logical, more selective backup.
Security boundaries need the same correction, because a role's login credentials work across every database in the cluster even though GRANT statements scope its actual privileges per object, so "different database" is not the same guarantee as "different login."
| Isolation approach | Strength | Weakness | Best Fit |
|---|---|---|---|
| Schema-per-tenant, one database | Cheapest; single connection pool; easy cross-tenant reporting | Weakest isolation; one bad query affects everyone | Small teams, low tenant count, trusted tenants |
| Database-per-tenant, one cluster | Stronger isolation; per-database backup/restore | Still shares max_connections, shared buffers, and version upgrades | Mid-size SaaS wanting isolation without new infrastructure |
| Cluster-per-tenant | Full resource and version isolation | Highest operational cost; more instances to patch and monitor | Regulated or high-value tenants needing hard isolation |
initdb-created instance, however confusing that overlap with modern HA vocabulary feels.postmaster serve every database in PGDATA, so the whole cluster upgrades together via pg_upgrade.postmaster process, which takes down every database in the cluster at once.max_connections, shared buffers, and WAL throughput, so isolation gains come with real, shared-resource trade-offs.It refers to one server instance and its data directory (PGDATA), created by a single initdb call, along with every database and role that instance manages.
A cluster is the whole running instance; a database is one of potentially many logical containers inside that instance, each with its own tables and schemas but sharing the cluster's roles and resources.
Yes, always - one binary serves the entire cluster, so a major-version upgrade via pg_upgrade moves every database in that cluster together.
Yes - a role created in one database is visible and can log in from any database in the same cluster, even though its actual privileges are granted per database or per object.
No - a backend connects to one database at a time, so cross-database access requires dblink or a foreign data wrapper rather than a native JOIN.
Per cluster - it is one shared budget of backend connection slots that every database and every application competes for, which is a major reason connection pooling matters.
CREATE DATABASE works by copying an existing template database, template1 by default, into a new entry inside the same cluster rather than starting a new server process.
No - a restart stops and starts the single postmaster process for the whole cluster, so every database on that instance goes down and comes back up together.
A tablespace is a storage-location decision, letting you place data on a different disk; a database is a logical isolation boundary for tables and schemas, and either can use any tablespace in the cluster.
Reach for database-per-tenant when you need stronger isolation and per-tenant backup and restore, and can accept that tenants still share the cluster's connection limit and version upgrade schedule.
When regulatory requirements or blast-radius concerns demand full resource and version isolation, since a separate cluster is the only option that removes shared max_connections, shared buffers, and upgrade timing entirely.
Not directly - Patroni manages high-availability failover between PostgreSQL clusters (a primary and its replicas), while "cluster" itself just describes one of those individual instances.
initdb actually creates on diskStack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance line 17).
Reviewed by Chris St. John·Last updated Jul 15, 2026