pgconfigurator
pgconfigurator

shared_buffers

Requires a restarttuned by pgconfiguratormemory (8 kB blocks; set in MB/GB)

PostgreSQL's own cache of table and index pages in shared memory.

What pgconfigurator would set
32 GB · 8 vCPU · NVMe · OLTP
Computing…
Tune for your exact server → /tunecomputed in your browser · nothing uploaded

What it does

shared_buffers sets the size of the shared-memory area PostgreSQL uses to cache data and index pages. Reads and writes go through these buffers; a larger pool means more of your hot data stays in PostgreSQL's cache instead of being re-read from the OS or disk.

How to tune it

A common starting point is ~25% of system RAM, with the operating system's page cache covering the rest (which is why effective_cache_size is usually set much higher). Going far above 25% has diminishing returns and can starve the OS cache. It requires a restart, so size it deliberately. On managed platforms the provider often sets it for you.

In depth

How it fits with the OS cache

PostgreSQL deliberately runs a relatively small cache of its own and leans on the operating system's page cache underneath it. A page you read can therefore live in two caches: shared_buffers and the OS cache. That double-buffering is why the classic advice is ~25% of RAM for shared_buffers and a much larger effective_cache_size (which tells the planner about both layers).

Setting shared_buffers to most of RAM doesn't make PostgreSQL faster — it just moves memory from the OS cache (which PostgreSQL also benefits from) into a pool with diminishing returns, and can make checkpoints heavier.

Picking a value

  • Start at ~25% of RAM. On a 32 GB server that's ~8 GB.
  • Write-heavy or large-RAM systems sometimes benefit from more (up to ~40%), but measure — the gain past 25% is usually small.
  • Tiny instances (≤2 GB) often do better leaving more for the OS cache.
  • Managed services frequently set this for you; check before overriding.

Because it's allocated in shared memory at startup, changing it requires a restart — size it deliberately rather than iterating live.

Reading whether it's big enough

shared_buffers being too small shows up indirectly: lots of shared read= in EXPLAIN (ANALYZE, BUFFERS) on queries that should be hot, or a low buffer cache hit ratio. The pg_buffercache extension lets you inspect what's actually resident. But remember the OS cache absorbs much of the miss cost, so a "low" hit ratio isn't automatically a problem.

Huge pages

When shared_buffers is large (many GB), backing it with OS huge pages (huge_pages) reduces TLB misses and page-table overhead. That pairing is where huge pages earn their keep.

What the analyzer flags

  • Cold plan — many pages read from disk; a warm cache hides this

Paste a plan into the analyzer →

FAQ

Should shared_buffers be 25% of RAM?
25% is a safe, well-tested default. Some write-heavy or large-RAM systems benefit from more, but past ~40% you're competing with the OS page cache for the same memory, often with little gain. Measure before going high.
Does a bigger shared_buffers always help?
No. Beyond the working set that actually fits, extra buffers sit idle, and very large pools can lengthen checkpoints. The OS cache already backs PostgreSQL, so you rarely need to cache the whole database in shared_buffers.

Related parameters