Quick answer
How much CPU and RAM does PostgreSQL need on a VPS?
PostgreSQL needs about one vCPU per query running at the same moment, and enough RAM to keep its working set cached. On Cobaltfell, Fell 2 (4 GB) fits a small production app, and Fell 8 (16 GB) fits a database that runs reports beside live traffic. The PostgreSQL 18 documentation, read on 2 November 2026, gives 25% of RAM as the starting value for shared_buffers.
How many vCPU does PostgreSQL use?
PostgreSQL uses one CPU thread per running query, because every connection gets its own backend process. The documentation calls it a "process per user" model: the postmaster spawns a new backend for each connection. The CPU a database needs is therefore set by the number of queries executing at the same instant, not by the number of open connections. An idle connection costs memory and no CPU.
Three things add threads on top of your queries:
- Parallel query. A large scan recruits helpers:
max_parallel_workers_per_gatherdefaults to 2 andmax_parallel_workersto 8, drawn frommax_worker_processes(default 8). - Autovacuum. Up to
autovacuum_max_workersprocesses (default 3) clean tables in the background. - The application, when it runs on the same VPS.
On a 2-vCPU VPS, one report that goes parallel can occupy every thread while the app's short queries wait behind it. Lowering max_parallel_workers_per_gather for the reporting role, or moving up a plan, solves it. The thread-versus-core rule behind these counts is explained in is a dedicated vCPU a core or a thread.
How much RAM does PostgreSQL need on a VPS?
Start shared_buffers at 25% of the VPS's RAM and leave most of the rest to the operating system's page cache. The PostgreSQL 18 documentation gives that starting value for a dedicated database server with 1 GB or more of RAM, and adds that more than 40% is unlikely to work better, because PostgreSQL also relies on the kernel's cache. The shipped default is 128 MB.
Two more settings follow from the RAM:
- effective_cache_size is an estimate for the planner only (default 4 GB). Set it to what shared_buffers and the page cache hold together, so index scans are costed correctly.
- work_mem (default 4 MB) applies to each sort or hash step in each session. One complex query uses it several times over, and many sessions do so at once, so it grows with care.
According to Cobaltfell's survey of 2 November 2026, 106 of the 202 dedicated-CPU plans recorded at hosts that take crypto without an ID check gave 4 GB of RAM or more per vCPU. For a database, RAM per vCPU matters as much as the vCPU count.
The plans behind that count are listed in what a dedicated CPU VPS costs per core in November 2026.
| Plan | vCPU | RAM | shared_buffers at 25% | Fits |
|---|---|---|---|---|
| Fell 2 | 2 | 4 GB | 1 GB | One app's database, a few busy connections at a time |
| Fell 4 | 4 | 8 GB | 2 GB | A SaaS backend with steady traffic, or a database plus its app |
| Fell 8 | 8 | 16 GB | 4 GB | Live traffic plus reports or parallel scans |
| Fell 16 | 16 | 32 GB | 8 GB | Many concurrent queries and a working set of tens of gigabytes |
How does CPU steal affect PostgreSQL p99 latency?
CPU steal stretches the slowest 1% of queries long before it moves the average. The Linux kernel describes steal as involuntary wait: time when a vCPU had work while the hypervisor ran someone else. A backend paused mid-query simply stops, and every client waiting on that query, or on a lock it holds, stops with it.
The pauses are short and irregular, so they hit only the queries that happen to be on the CPU at that moment. As an illustration, not a measurement: when a vCPU loses a few tens of milliseconds to a neighbour now and then, a 2 ms query that lands in one of those windows takes ten times longer, while the thousands of queries around it run at normal speed. The mean barely changes; the 99th percentile carries the whole cost.
A database on a shared vCPU therefore looks healthy in averages and still produces timeouts. Three readings expose it:
- Steal: the
%stealcolumn ofmpstatduring the busiest hour, explained in what CPU steal time is and how to check it on a VPS. - Worst cases:
pg_stat_statementsreportsmax_exec_timeandstddev_exec_timeper statement, and no percentiles. - Percentiles:
log_min_duration_statement(for example250ms) logs slow statements; a latency histogram in the application gives the p99 itself.
# queries on the CPU right now (run at your busiest hour)
psql -c "SELECT count(*) FROM pg_stat_activity WHERE state = 'active';"
# statements with the worst single run (needs pg_stat_statements in shared_preload_libraries)
psql -c "SELECT left(query, 60) AS query, calls,
round(mean_exec_time::numeric, 2) AS mean_ms,
round(max_exec_time::numeric, 2) AS max_ms
FROM pg_stat_statements ORDER BY max_exec_time DESC LIMIT 10;"
# steal per vCPU, every 5 seconds (package sysstat)
mpstat -P ALL 5 6What does a dedicated vCPU change for a database?
A dedicated vCPU removes the one source of tail latency that cannot be tuned from inside the VPS. Slow plans, missing indexes and lock contention are the operator's to fix; a neighbour's batch job on a shared core is not. The general case is laid out in what is the difference between a shared and a dedicated vCPU. On a Cobaltfell VPS:
- CPU: A vCPU is one hardware thread of the host processor. Yours are pinned one to one to your VPS and never lent to another customer, and the two threads of a physical core stay together, so every 2 vCPU make one whole core that no neighbour shares.
- Steal: On a dedicated vCPU, steal time should sit at or near zero. We will publish the figure we measure on our own machines, with its date, and never an estimate.
- Memory: The RAM of your plan is set aside for your VPS and is not overcommitted.
- Disk: NVMe storage on every plan.
- Load: Full load is allowed for as long as your work needs it: no CPU credits, no burst window and no throttling after some minutes at 100%. A long
VACUUMor index build runs flat out.
The processor family is AMD EPYC 9004/9005 (Zen 4 / Zen 5).
When is a VPS the wrong home for PostgreSQL?
A VPS is the wrong home when the data queried every minute is much larger than the RAM of the largest plan, or when replicas and backups must be managed for you. Fell 16 has 32 GB. A working set that does not fit in memory turns every query into disk reads, and storage throughput, not vCPU, then sets the pace.
Backups stay with the operator: Backups are not part of any plan: keep a copy of your data somewhere else. A nightly pg_dump or a WAL archive sent to storage in another place covers most small databases; a restore test belongs on the calendar before it is needed.
Failover across two or three VPS with streaming replication works, but it is self-managed. Cobaltfell sells the servers, not a managed database. Prices for each size are listed under how much a dedicated-core VPS costs.
What other questions do people ask about PostgreSQL on a VPS?
Is 2 vCPU enough for PostgreSQL?
For one application with a modest number of busy connections, yes. Two vCPU run two queries at once; a third waits for a free thread. Fell 4 is the next step when pg_stat_activity often shows more active queries than vCPU, or when the app shares the VPS.
Should the app and the database share one VPS?
On Fell 2 and Fell 4 it is common and saves a network hop. The app's busy processes count as extra vCPU users. Split them when deploys or traffic spikes start showing up in the database's slow-query log.
Does PostgreSQL on a VPS need a connection pooler?
In most web applications, yes. max_connections defaults to 100, and each connection is a full process holding memory. A pooler such as PgBouncer keeps the number of active backends close to the vCPU count while the app opens as many client connections as it needs.
What should be set first after installing PostgreSQL?
shared_buffers at 25% of RAM, effective_cache_size to the memory that shared_buffers and the page cache hold together, and log_min_duration_statement so slow queries leave a trace. work_mem stays near its default until a slow plan shows a sort spilling to disk.
Are backups included with a Cobaltfell VPS?
No. Backups are not part of any plan: keep a copy of your data somewhere else.
Sources (9)
- PostgreSQL 18: Resource consumption (shared_buffers, work_mem, worker processes) — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: Query planning (effective_cache_size) — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: Connections and authentication (max_connections) — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: Vacuuming (autovacuum_max_workers) — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: Error reporting and logging (log_min_duration_statement) — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: How connections are established — The PostgreSQL Global Development Group (checked 2026-11-02)
- PostgreSQL 18: pg_stat_statements — The PostgreSQL Global Development Group (checked 2026-11-02)
- The /proc filesystem: /proc/stat (steal) — The Linux kernel documentation (checked 2026-11-02)
- mpstat(1) manual page (%steal) — man7.org / sysstat (checked 2026-11-02)