Name the work before choosing the host
Draw the request path: reverse proxy, API process, database and external services. Add the asynchronous path: queue, worker and export destination. Record which components share the host, who controls concurrency and which data must survive a rebuild. You need application metrics and a non-production workload with representative data; this guide does not assume a provisioned PrivacyNodes instance.
For an illustrative reporting API, an HTTP request reads account settings and enqueues an export. The worker scans rows and writes a file. A fast enqueue response does not prove the export can finish during peak traffic. Include scheduled cleanup and deployment overlap in the test plan.
Include overlap in the memory worksheet
These are hypothetical planning inputs in MiB, not measurements or promises about PrivacyNodes. Replace them with observed application requirements. RSS includes resident shared mappings; adding every process's RSS can double-count memory. The host's available memory is more useful than treating all filesystem cache as permanently unavailable.
Technical reference: Linux process memory accounting.
| Component | Budget | Assumption |
|---|---|---|
| Host and tooling | 512 MiB | OS, proxy, telemetry |
| Two API processes | 768 MiB | 384 each at assumed peak |
| One export worker | 512 MiB | Bounded batches |
| Database | 1,024 MiB | Cache and query work |
| Release overlap | 512 MiB | Old and new work coexist |
| Unallocated margin | 512 MiB | Uncertainty to investigate |
| Total assumption | 3,840 MiB | Compare with actual host memory |
This is too close to a nominal 4 GB envelope to assume comfortable capacity. Check actual memory reported by the host and whether peaks overlap. Reduce concurrency, move a component or add memory; do not remove the reserve just to make the table fit.
PostgreSQL work_mem is a per-operation allowance, not a total database limit. Concurrent sessions and operations can multiply its effect. Docker containers have no CPU or memory constraints by default; an image is not a resource policy.
Technical reference: PostgreSQL resource consumption · Docker resource constraints.
Measure CPU alongside queue age
Exercise an ordinary request, the slowest useful report, a failed dependency and an export together. Record latency percentiles, errors, host CPU, worker concurrency and oldest-job age over the same interval. CPU pressure with queue growth suggests a different action from low CPU with a long database wait.
Start the example with one export in flight. If the worker waits on external storage, extra CPU may change little. If it repeatedly saturates a core while API latency rises, test a smaller export batch or a separate worker budget. Change one factor and repeat the same scenario before buying capacity.
Budget the next maintenance operation
List database files and indexes, uploads, logs, temporary exports, release artifacts and free space for maintenance. Record growth per week and when your reserve would be exhausted. A 20 GB data set plus a 20 GB temporary copy needs more than 20 GB, even when ordinary application traffic is quiet.
Assign log rotation and export expiry. Keep recovery copies outside the host's failure boundary. Extra VPS storage expands the working allocation; a copy on that same disk is not an independent backup. Test both normal operation and a release running alongside a backup or export.
Write a decision that can be revisited
Your output is a worksheet, a workload description and a review trigger: growing oldest-job age during the representative test, shrinking maintenance space, or a release that cannot coexist with current processes. Record observations instead of inventing a universal CPU percentage threshold.
Compare App 2 and Scale 4 against those constraints. If the result still surprises you, follow one slow request through the stack. This exercise estimates your workload; it establishes no supplier benchmark, traffic capacity or availability.
Official references
Documentation was reviewed for this article. Examples are planning exercises, not commands tested on a PrivacyNodes server. Check the documentation for your installed version.