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.
shared_buffers op 25% van het geheugen, effective_cache_size op 75%, random_page_cost = 1.1 op een NVMe-SSD.pg_dump, buiten de server, en zet regelmatig een back-up terug om dat te controleren.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:
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.
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.
| Parameter | 4 GB | 8 GB | 16 GB | Rol |
|---|---|---|---|---|
shared_buffers | 1 GB | 2 GB | 4 GB | De eigen cache van PostgreSQL |
effective_cache_size | 3 GB | 6 GB | 12 GB | De geschatte totale cache, die de keuze van de queryplannen stuurt |
work_mem | 8 MB | 16 MB | 32 MB | Het geheugen voor elke sorteer- of hashbewerking, per verbinding: te vermenigvuldigen met het aantal gelijktijdige query’s |
maintenance_work_mem | 256 MB | 512 MB | 1 GB | Het aanmaken van indexen en de VACUUM |
random_page_cost | 1.1 | 1.1 | 1.1 | De 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.
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%:
SELECT round(100.0 * blks_hit / nullif(blks_hit + blks_read, 0), 2) AS cache_hitratio
FROM pg_stat_database
WHERE datname = current_database();
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 van een PostgreSQL-server draagt meer dan de tabellen:
max_wal_size), meer tijdens een grote import, en nog meer als de archivering van het logboek achterstand oploopt.work_mem overschrijden.VACUUM FULL en het herbouwen van een index schrijven een volledige kopie weg voordat de oude wordt vrijgegeven.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.
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:
shared_preload_libraries = 'pg_stat_statements'
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;
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.
listen_addresses = 'localhost' zolang alleen de applicatie op de server verbinding maakt. Moet een andere server erbij kunnen, open dan poort 5432 alleen voor zijn adres, in de firewall en in pg_hba.conf.scram-sha-256 in pg_hba.conf, één rol per applicatie, zonder superuserrechten.pg_dump, gekopieerd naar een plek buiten de server.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
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.
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.
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.
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.
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.
Simafri
Laten we het over uw website hebben
Vertel ons in een paar woorden over uw project: wij nemen snel contact met u op.
Bedankt! Uw aanvraag is verzonden. We nemen spoedig contact met u op.
Liever per e-mail? Schrijf ons op support@simafri.com.