shared_buffers
PostgreSQL's own cache of table and index pages in shared memory.
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
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.