<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip" -->

---
title: Why Postgres Breaks Kubernetes...
description: Kubernetes' container_memory_working_set_bytes metric, calculated as current minus inactive file cache, can badly misrepresent actual memory pressure for...
canonical: https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Why Postgres Breaks Kubernetes container_memory_working_set_bytes Metric | daily.dev
og:description: Kubernetes' container_memory_working_set_bytes metric, calculated as current minus inactive file cache, can badly misrepresent actual memory pressure for...
og:url: https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip
og:image: https://api.daily.dev/og/posts/8rosEAcIP.png
og:image:alt: Why Postgres Breaks Kubernetes container_memory_working_set_bytes Metric
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Why Postgres Breaks Kubernetes container_memory_working_set_bytes Metric

**[Planet PostgreSQL](https://daily.dev/sources/planet-postgresql)** · 8 min read · 0 upvotes · 0 comments

## Summary

Kubernetes' container_memory_working_set_bytes metric, calculated as current minus inactive file cache, can badly misrepresent actual memory pressure for Postgres workloads. Through a series of Docker-based experiments with pgbench and manual sort queries, the analysis shows that Postgres shared buffers (shmem) and active page cache pages behave differently from simple anonymous memory, causing the metric to either understate or overstate real OOM risk depending on cache size and workload. A smaller shared_buffers setting can actually reduce crash risk even though the working-set metric looks worse. The recommendation is to track current minus (inactive_file + active_file) instead, ignoring the page cache entirely, and to consider lowering shared_buffers when running Postgres under Kubernetes memory limits. MGLRU (Multi-Gen LRU), now enabled by default on recent Debian and Ubuntu LTS, changes how pages are classified as active, adding further nuance.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://postgr.es/p/9sE>

## Questions this post answers

### Why is Kubernetes container_memory_working_set_bytes not a reliable OOM predictor for Postgres pods?

Because it only excludes inactive file page cache (current minus inactive_file) but still counts active file page cache as used memory, even though active pages are easily reclaimed under pressure. Postgres shared buffers are allocated as shmem and never appear as reclaimable, so the metric can show rising pressure from cache activity while actual OOM risk depends on shmem plus anon memory approaching the cgroup limit, not on page cache size.

_Teams tuning Postgres memory limits on kubernetes can find deeper cgroup metric breakdowns like this through daily.dev._

### What metric should I track instead of container_memory_working_set_bytes to monitor Postgres memory pressure on Kubernetes?

Track current minus (inactive_file plus active_file) from cgroups v2 memory.stat, which excludes the entire page cache rather than only inactive pages. This isolates shmem (Postgres shared buffers) and anon (query working memory), the two components that actually drive an out-of-memory crash, giving a far more accurate signal than the default working set metric.

_Developers building reliable Postgres monitoring on kubernetes track fixes like this through daily.dev._

### Does lowering Postgres shared_buffers help avoid OOM crashes when running in a Kubernetes memory-limited container?

Yes, reducing shared_buffers frees more room for query working memory before hitting the cgroup memory limit. In one test, dropping shared_buffers from 128MB to 32MB let sorting go from 3 million to 4 million rows before an out-of-memory crash under the same realistic pgbench workload, because shared buffer shmem pages can never be reclaimed by the kernel once allocated.

_Anyone sizing Postgres containers for kubernetes limits can track tuning experiments like this via daily.dev._

## Similar posts on daily.dev

- [Don't give Postgres too much memory](https://daily.dev/posts/don-t-give-postgres-too-much-memory-xluq2yiti) · Lobsters · 1 upvotes · 0 comments
- [All Your GUCs in a Row: effective\_cache\_size](https://daily.dev/posts/all-your-gucs-in-a-row-effective-cache-size-7o5w3bmms) · Planet PostgreSQL · 0 upvotes · 0 comments
- [Can your Postgres survive a bad query?](https://daily.dev/posts/can-your-postgres-survive-a-bad-query--sdf4kdxbn) · ClickHouse · 7 upvotes · 1 comments
- [All Your GUCs in a Row: dynamic\_shared\_memory\_type](https://daily.dev/posts/all-your-gucs-in-a-row-dynamic-shared-memory-type-evjchcwss) · Planet PostgreSQL · 0 upvotes · 0 comments

---

Tags: [#kubernetes](https://daily.dev/tags/kubernetes), [#postgresql](https://daily.dev/tags/postgresql), [#observability](https://daily.dev/tags/observability)

[View this post on daily.dev](https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Why Postgres Breaks Kubernetes container_memory_working_set_bytes Metric","url":"https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip"},"datePublished":"2026-08-18T23:31:47.883Z","dateModified":"2026-09-13T20:46:09.069Z","description":"Kubernetes' container_memory_working_set_bytes metric, calculated as current minus inactive file cache, can badly misrepresent actual memory pressure for...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7a68a5fdc929cdbb03cb0f9380009d5e?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7a68a5fdc929cdbb03cb0f9380009d5e?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Planet PostgreSQL","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Planet PostgreSQL","logo":"https://media.daily.dev/image/upload/logos/placeholder.jpg","url":"https://daily.dev/sources/planet-postgresql"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"kubernetes,postgresql,observability","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Planet PostgreSQL","item":"https://daily.dev/sources/planet-postgresql"},{"@type":"ListItem","position":3,"name":"Why Postgres Breaks Kubernetes container_memory_working_set_bytes Metric"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/why-postgres-breaks-kubernetes-container-memory-working-set-bytes-metric-8roseacip#faq","mainEntity":[{"@type":"Question","name":"Why is Kubernetes container_memory_working_set_bytes not a reliable OOM predictor for Postgres pods?","acceptedAnswer":{"@type":"Answer","text":"Because it only excludes inactive file page cache (current minus inactive_file) but still counts active file page cache as used memory, even though active pages are easily reclaimed under pressure. Postgres shared buffers are allocated as shmem and never appear as reclaimable, so the metric can show rising pressure from cache activity while actual OOM risk depends on shmem plus anon memory approaching the cgroup limit, not on page cache size. Teams tuning Postgres memory limits on kubernetes can find deeper cgroup metric breakdowns like this through daily.dev."}},{"@type":"Question","name":"What metric should I track instead of container_memory_working_set_bytes to monitor Postgres memory pressure on Kubernetes?","acceptedAnswer":{"@type":"Answer","text":"Track current minus (inactive_file plus active_file) from cgroups v2 memory.stat, which excludes the entire page cache rather than only inactive pages. This isolates shmem (Postgres shared buffers) and anon (query working memory), the two components that actually drive an out-of-memory crash, giving a far more accurate signal than the default working set metric. Developers building reliable Postgres monitoring on kubernetes track fixes like this through daily.dev."}},{"@type":"Question","name":"Does lowering Postgres shared_buffers help avoid OOM crashes when running in a Kubernetes memory-limited container?","acceptedAnswer":{"@type":"Answer","text":"Yes, reducing shared_buffers frees more room for query working memory before hitting the cgroup memory limit. In one test, dropping shared_buffers from 128MB to 32MB let sorting go from 3 million to 4 million rows before an out-of-memory crash under the same realistic pgbench workload, because shared buffer shmem pages can never be reclaimed by the kernel once allocated. Anyone sizing Postgres containers for kubernetes limits can track tuning experiments like this via daily.dev."}}]}
```

