CONCEPT Cited by 1 source
RSS (Resident Set Size)¶
Definition¶
RSS (Resident Set Size) is the amount of non-reclaimable physical memory currently held by a process. For Postgres: "RSS is the amount of private memory allocated to a process such as stack, heap, catalog/relcache caches, query execution memory like sorts and hash tables." Distinct from virtual memory (which includes unused mappings), distinct from cache memory (which is reclaimable by the kernel).
(Source: sources/2026-04-21-planetscale-high-memory-usage-in-postgres-is-good-actually.)
Components in a Postgres backend¶
Per Griggs:
- Stack — local variables, function call frames.
- Heap — dynamically allocated buffers.
- Catalog / relcache caches — cached copies of
pg_class,pg_attribute, etc. (see concepts/catalog-bloat-multi-tenant). - Query execution memory — sorts, hash tables, etc.,
bounded per-allocation by
work_mem(see concepts/work-mem-multiplication). - Cached plans and prepared statements — accumulated over session lifetime (see concepts/prepared-statement-memory-accumulation).
The process-level vs query-level gap¶
Postgres's process-per-connection architecture makes RSS a per-backend-process measurement. It is not a per-query measurement:
"RSS is a per-process metric, not a per-query metric. That means you cannot read 'RSS per query' directly from
EXPLAINor Query Insights."
This observability gap creates the need for patterns/triangulate-rss-growth-from-metrics — a multi-signal workflow for attributing RSS growth to specific queries.
RSS vs virtual memory¶
| Metric | Includes unused mappings | Physical RAM | Swap backing |
|---|---|---|---|
| VSZ / VIRT | Yes | No (includes reserved-but-unused) | Includes |
| RSS | No | Yes | No |
| Shared RSS | Yes (double-counts across processes) | Yes | No |
RSS is the right number for OOM-risk reasoning: it's the memory the process has actually touched and the kernel cannot take back.
RSS across a Postgres fleet¶
RSS does not add linearly across Postgres backends because some memory is shared:
shared_buffersis allocated once, mapped into every backend. Per-backend RSS counts it; the sum across backends double-counts.- Stack / heap / per-backend caches are genuinely per-backend; they sum linearly.
"Given Postgres' process-per-connection architecture, each process requires some baseline amount of memory. Not every process will consume the same amount of memory. Further, some memory use is shared across processes. So calculating RSS use is not as simple as adding up the memory usage of every process."
Connection pooling as the primary RSS lever¶
"Efficient connection pooling can be the best way to reduce
RSS usage. Fewer active connections result in fewer copies
of all that per-process overhead."
PgBouncer in transaction mode cuts the active-backend
count, which cuts the RSS multiplier across work_mem,
catalog caches, and per-session state.
Seen in¶
- sources/2026-04-21-planetscale-high-memory-usage-in-postgres-is-good-actually — canonical wiki disclosure of RSS as the non-reclaimable-per-process-memory metric and the observability gap (no per-query attribution).