What else is running on your Postgres server's VM, and what stops it from taking the database down? Alongside Postgres, ours runs several PgBouncer instances, a backup agent, metrics exporters, a local Prometheus, a log collector, and a handful of watchdog timers. Each process protects the database. Each can also leak memory, burn CPU, or fill a disk.
That places every one of them inside the database's failure model. A monitoring process can consume the memory Postgres needs. A backup agent can saturate the CPUs serving queries. Either failure can bring down the whole instance.
A shared machine is shared memory
Postgres gets one unusually strong boundary. Its shared_buffers allocation lives in huge pages reserved at boot, so another process cannot slowly eat into it. We described why we make that allocation strict in our post on reserving huge pages for Postgres.
Postgres also needs memory outside shared_buffers. The kernel's page cache, each backend's working memory, connection state, and plenty of smaller allocations come from the same machine-wide pool used by PgBouncer, WAL-G, Prometheus, exporters, and logging. A leak in any one of those processes can consume the headroom every database backend depends on.
ClickHouse Managed Postgres gives the supporting processes explicit resource limits. Four Go services, Prometheus, the WAL-G backup agent, postgres_exporter, and node_exporter—run in one cgroup v2 slice. The systemd MemoryHigh and MemoryMax properties write the slice's memory.high and memory.max controls. Each service also carries a GOMEMLIMIT sized so the individual Go heap budgets add up below memory.high.

Runtime and cgroup enforcement
The boundaries do different jobs:
| Boundary | What it does | Why it exists |
|---|---|---|
GOMEMLIMIT | Makes the Go runtime collect more aggressively as its heap approaches its configured target. | Heap growth increases GC frequency before the cgroup reaches kernel-enforced thresholds. |
memory.high | Forces direct reclaim and throttles allocations charged to the cgroup. | Pressure is applied to the processes responsible for the cgroup's memory usage. |
memory.max | Sets the hard cgroup ceiling; if reclaim cannot reduce usage, the kernel raises an OOM event in that cgroup. | OOM victim selection is scoped to processes charged to the supporting-services cgroup. |
GOMEMLIMIT is deliberately the first line of defense. Go can react with much more context than the kernel: it knows what is heap, what is live, and when another garbage-collection cycle might help. A service approaching its budget does more collection work and usually stays inside the line on its own.

GOMEMLIMIT remains a runtime target. Native allocations, retained objects, or a genuine leak can carry a process past it. The cgroup supplies kernel enforcement: charges above memory.high enter reclaim and throttling.

Charges that cannot be reclaimed below memory.max trigger a cgroup OOM event.

Postgres memory is charged to a separate cgroup, so a memory.max event in the supporting-services cgroup does not select a Postgres process.

The slice's allowance is the same headroom that our strict-overcommit policy sets aside on top of Postgres's share. The commit budget reserves the memory; the cgroup holds the processes to it. The two controls describe the same capacity from opposite directions.
Budgets across every resource
A process can behave perfectly in heap usage and still hurt the database somewhere else, so the same discipline extends across the VM:
- Backups run at a fraction of the default CPU weight, so foreground database work wins when the machine is busy.
- WAL-G's buffers are a fixed fraction of RAM, keeping memory use bounded as workload grows.
- The log collector has its own memory limiter, keeping a burst of logs from becoming a second incident.
- Metrics leaving the box are hand-picked, so a new label cannot quietly create an unbounded cardinality bill in memory, CPU, and network traffic.
Each resource now has an enforcement point: scheduler weight for CPU, fixed buffer sizing and cgroups for memory, local thresholds for disk, and an allowlist for exported metric series.
Disk-full session exemptions
Postgres needs free disk to make progress, and a full data volume can quickly turn an ordinary workload into an availability incident. At the emergency threshold, the disk-full watchdog terminates sessions to reduce write pressure. Two usernames are exempt from termination: replication and monitoring.

Termination is not indiscriminate. The watchdog reads pg_stat_activity and maps each backend's database username to a keep-or-terminate decision.

Sessions from ordinary application usernames are then terminated, which removes their write paths immediately.

The replication exemption keeps standby WAL streaming active. The monitoring exemption keeps database metrics available to operators and automation during the event.

The backup agent receives a bounded memory allocation and a lower CPU weight. Prometheus is charged to the host-services cgroup. The disk watchdog preserves the replication and monitoring roles explicitly. These controls keep backup, replication, and observability available within defined resource limits.
Resulting isolation model
A managed Postgres server is a small system of cooperating processes. Reliability depends on treating every supporting service as both protection and potential pressure: give the runtime a budget it can understand, give the kernel a ceiling it can enforce, and keep the emergency path outside the failure it is meant to handle.
These controls are enabled by default on every ClickHouse Managed Postgres server.
Get started with ClickHouse Managed Postgres today
Interested in seeing how ClickHouse Managed Postgres works on your data? Get started with ClickHouse Cloud in minutes and receive $300 in free credits.
Sign up


