PostgreSQL op een VPS: geheugen en schijf dimensioneren

Een snelle PostgreSQL-database is een database waarvan de vaak geraadpleegde gegevens in het geheugen passen. De hele dimensionering vertrekt daarvan: de omvang van de database, het deel dat echt wordt gebruikt, het aantal verbindingen, en daarna de schijf en de marge erop. Deze gids geeft de methode, de startinstellingen voor 4, 8 en 16 GB geheugen, en de query’s die een bestaande database meten.

Gepubliceerd op 29 oktober 2026 Door Leestijd: 10 minuten

Alle gidsen

In het kort

  1. Meet de omvang van de database en haar indexen, en daarna het deel dat vaak wordt geraadpleegd: dat deel moet in het geheugen passen.
  2. Vertrekpunt: shared_buffers op 25% van het geheugen, effective_cache_size op 75%, random_page_cost = 1.1 op een NVMe-SSD.
  3. Elke verbinding is een proces: boven enkele tientallen actieve verbindingen zet u PgBouncer vóór de database.
  4. Schijf: gegevens en indexen over een jaar, plus minstens 30% marge. Een volle schijf legt PostgreSQL stil.
  5. De cache-hitratio moet boven 99% blijven: daaronder komt de database geheugen tekort.
  6. Maak elke dag een back-up met pg_dump, buiten de server, en zet regelmatig een back-up terug om dat te controleren.

Vertrekken van het werkvolume

Het geheugen van een databaseserver dient in de eerste plaats als cache: een pagina die uit het geheugen wordt gelezen, wordt veel sneller geleverd dan een pagina van schijf, zelfs van NVMe. De vraag is dus niet alleen “hoe groot is de database?”, maar ook “welk deel wordt vaak gelezen?”. Een database van 50 GB waarvan alleen de laatste twaalf maanden worden geraadpleegd, werkt misschien op 8 GB.

Op een bestaande database geven twee query’s het totale volume en de grootste tabellen, indexen inbegrepen:

SQL (psql)
SELECT pg_size_pretty(pg_database_size(current_database()));

SELECT relname AS naam,
       pg_size_pretty(pg_total_relation_size(relid)) AS grootte_met_indexen
FROM pg_catalog.pg_statio_user_tables
ORDER BY pg_total_relation_size(relid) DESC
LIMIT 10;

Voor een database die er nog moet komen, schat u tabel per tabel: het aantal verwachte rijen over een jaar × de gemiddelde grootte van een rij, en daarna telt u de indexen erbij, die gewoonlijk 30 tot 100% van de gegevens wegen. Voorbeeld: 2 miljoen rijen per maand, van elk 500 bytes, geven 12 GB aan gegevens over een jaar, en 18 tot 24 GB met de indexen.

Het geheugen: de startinstellingen

PostgreSQL bewaart gelezen pagina’s op twee niveaus: zijn eigen cache (shared_buffers) en de bestandscache van het systeem. De documentatie raadt aan op een dedicated databaseserver te beginnen met 25% van het geheugen voor shared_buffers, en merkt op dat boven 40% de winst zelden groter wordt: de rest komt ten goede aan de cache van het systeem en aan sorteerbewerkingen.

Parameter4 GB8 GB16 GBRol
shared_buffers1 GB2 GB4 GBDe eigen cache van PostgreSQL
effective_cache_size3 GB6 GB12 GBDe geschatte totale cache, die de keuze van de queryplannen stuurt
work_mem8 MB16 MB32 MBHet geheugen voor elke sorteer- of hashbewerking, per verbinding: te vermenigvuldigen met het aantal gelijktijdige query’s
maintenance_work_mem256 MB512 MB1 GBHet aanmaken van indexen en de VACUUM
random_page_cost1.11.11.1De geschatte kosten van een willekeurige leesbewerking: standaard 4, ver boven de werkelijke kosten op een NVMe-SSD

Deze waarden gaan uit van een database die alleen op de server staat. Draait de applicatie ernaast, trek dan eerst haar geheugen af (processen, cache, build) en pas de percentages toe op de rest: een server van 8 GB die een applicatie van 3 GB draait, stelt u af als een database van 5 GB.

postgresql.conf, voor een server van 8 GB die alleen voor de database dient
shared_buffers = 2GB
effective_cache_size = 6GB
work_mem = 16MB
maintenance_work_mem = 512MB
random_page_cost = 1.1

shared_buffers wordt pas actief na een herstart van PostgreSQL; de andere parameters worden zonder onderbreking herladen, met SELECT pg_reload_conf();.

Om te weten of het geheugen volstaat, leest u de cache-hitratio. Bij een bedrijfsapplicatie of een website ligt die boven 99%:

SQL (psql)
SELECT round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS cache_hitratio
FROM pg_stat_database
WHERE datname = current_database();

De verbindingen: elk een eigen proces

PostgreSQL opent een proces per verbinding, en accepteert er standaard 100 (max_connections). Elk proces neemt in rust enkele megabytes in, meer wanneer het gegevens sorteert of hasht (work_mem, soms meermaals binnen dezelfde query). max_connections naar 500 optrekken om een spraakzame applicatie bij te houden, stelt de server bloot aan geheugentekort bij de eerste piek.

Het juiste antwoord is een connection pooler: PgBouncer, in de modus transaction, laat honderden verbindingen van de applicatie enkele tientallen echte verbindingen delen. Frameworks hebben ook hun eigen pool (SQLAlchemy, Prisma, HikariCP): stem de grootte ervan af op het aantal vCPU van de databaseserver, eerder dan op het aantal gebruikers.

De schijf: volume, marge en transactielogboek

De schijf van een PostgreSQL-server draagt meer dan de tabellen:

De regel: het volume over een jaar, plus minstens 30% marge. Dat is geen luxe: als de schijf met het transactielogboek volloopt, stopt PostgreSQL om zijn gegevens te beschermen. Houd de bezetting in de gaten, en vergroot vóór 80%.

Wat de prestaties betreft, wacht elke commit van een transactie tot het logboek naar schijf is geschreven: de latentie van de opslag bepaalt de schrijfdoorvoer. Daar maakt een NVMe-SSD het verschil, veel meer dan bij het lezen, dat het geheugen al bedient.

De processor: één query, één core

Een PostgreSQL-query draait op één core, behalve de grote leesbewerkingen die de engine parallelliseert. Het aantal vCPU bepaalt dus hoeveel zware query’s tegelijk worden verwerkt: 2 vCPU volstaan voor een bedrijfsapplicatie bij de lancering, 4 tot 8 passen bij zwaar belaste databases en zware rapporten.

Zoek, voordat u vCPU toevoegt, de query’s op die ze verbruiken. De extensie pg_stat_statements rangschikt ze naar totale tijd:

postgresql.conf, daarna herstarten
shared_preload_libraries = 'pg_stat_statements'
SQL (psql)
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT calls, round(total_exec_time) AS ms_totaal,
       round(mean_exec_time::numeric, 1) AS ms_gemiddeld, query
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Dezelfde server als de applicatie, of een aparte server?

Bij de lancering is de database op dezelfde server als de applicatie de juiste keuze: geen netwerklatentie tussen beide, een verbinding via een Unix-socket, één server om te back-uppen en te bewaken. U splitst ze wanneer ze om dezelfde resources concurreren: een build of een verkeerspiek die de cache van de database leegt, een database die al het geheugen nodig heeft voor haar gegevens, of verschillende eisen aan de back-ups.

Beveiliging en back-ups

Terminal: gecomprimeerde export, daarna terugzetten in een testdatabase
pg_dump -Fc -d mijn_db -f mijn_db-$(date +%F).dump
createdb mijn_db_test
pg_restore -d mijn_db_test mijn_db-2026-10-29.dump

Een snelle PostgreSQL-database, op de juiste server

VPS Pro draait op Intel Xeon-processors, ECC-geheugen dat fouten direct corrigeert en gespiegelde NVMe-SSD’s, met elk datablok gecontroleerd met een checksum en elke nacht een versleutelde back-up buiten de machine. Full-Stack Support is inbegrepen: wanneer uw database trager wordt, analyseren wij de trage query’s en de indexen, en vertellen wij u welke instellingen uw applicatie haar snelheid teruggeven.

Ontdek VPS Pro

Veelgestelde vragen

Hoeveel RAM heeft PostgreSQL nodig?

Genoeg om de vaak geraadpleegde gegevens in het geheugen te laten passen. Voor een bedrijfsapplicatie bij de lancering volstaat 4 GB, database en applicatie samen. Meet daarna de cache-hitratio: zolang die boven 99% blijft, volstaat het geheugen.

Welke waarde voor shared_buffers?

25% van het geheugen op een dedicated databaseserver, zoals de documentatie van PostgreSQL aanraadt: 1 GB bij 4 GB, 2 GB bij 8 GB, 4 GB bij 16 GB. Boven 40% wordt de winst zeldzaam, omdat de cache van het systeem de rest doet.

Hoeveel PostgreSQL-verbindingen kan een VPS aan?

PostgreSQL accepteert er standaard 100, en elke verbinding is een proces dat geheugen verbruikt. Zet in plaats van dat plafond te verhogen een connection pooler zoals PgBouncer vóór de database: enkele tientallen echte verbindingen bedienen dan honderden verbindingen van de applicatie.

Moet ik de database en de applicatie scheiden?

Niet bij de lancering: op dezelfde server antwoordt de database zonder netwerklatentie en wordt alles in één keer geback-upt. U splitst ze wanneer de ene de andere hindert, bijvoorbeeld wanneer een build of een verkeerspiek de cache van de database leegt.

Neem contact op