Skip to content

Capacity planning

Start staging with 4 vCPUs and 8 GB RAM, then repeat the load test on the chosen host. The prepared Terraform uses Hetzner CPX32 with its included 160-GB NVMe disk and no additional block volume. The earlier 8-vCPU/32-GB and 1-TB-volume estimate has been replaced by local measurements.

Two five-minute measurements on 6 September 2026 ran the deployment with all ten virtual cameras and auto-operator enabled, after a one-minute warmup. A separate one-minute baseline measured the stopped simulator. The second loaded run also received six synthetic 1080p H.264 camera streams at 4.136 Mbps each.

Load Mean CPU equivalents Peak CPU equivalents Peak working memory
Simulator stopped 0.28 0.29 1.29 GiB
Ten virtual cameras and automation 1.10 1.23 2.03 GiB
Ten virtual cameras plus six incoming cameras 1.24 1.44 2.03 GiB

One CPU equivalent means one fully occupied logical CPU; peaks are the highest 15-second sample. Memory excludes inactive filesystem cache. Totals include Core, Postgres, SRS, the indexer, Caddy and monitoring. They exclude local MinIO and the synthetic camera source, which represent services outside the staging host.

The measurements ran on an Apple M1 Max through an arm64 OrbStack VM, not on Hetzner x86 hardware or under an 8-GB memory limit. Six incoming video streams exercise SRS/DVR/upload work but do not reproduce real-aircraft telemetry or concurrent viewers. Both runs sustained about 118 aggregate simulator frames per second against a 120-fps target, with no new encoder, automation or database-flush failures. This is a capacity sample, not a completed mission/charging soak.

Raw results and the method are recorded in dev-docs/mainframe/review/2026-09-06-capacity-benchmark.md. The repeatable collector is scripts/benchmark-deployment.py; run it on the new host before accepting the size.

World-sim is the largest CPU consumer because it renders and H.264-encodes its cameras. Real camera video normally arrives already encoded. Memory also needs room for Postgres cache and monitoring as retained data grows; the measured working set does not justify 32 GB.

CPX32 has four shared vCPUs and 8 GB RAM. For predictable dedicated CPU, CCX23 has four dedicated vCPUs and 16 GB RAM; the extra memory is part of that plan. Their published Europe prices are €35.49 and €85.99/month respectively, excluding VAT and IPv4. CPX32 with server backups and IPv4 is approximately €43.09/month before object storage. Confirm availability and the account quote before provisioning. CPX specifications, CCX specifications, prices, backup billing, IPv4 billing

Shared CPU scheduling varies with neighboring workloads. Check frame rate, CPU, memory, storage queues and DVR delay on the actual host. Prefer a dedicated plan if scheduling causes sustained camera or ingest delays. CPU allocation

Staging defaults now use a 1-GB Postgres shared buffer and configurable memory ceilings: POSTGRES_MEMORY_LIMIT, MAINFRAME_MEMORY_LIMIT, WORLD_SIM_MEMORY_LIMIT and MEDIA_INDEXER_MEMORY_LIMIT. These are safety limits, not reservations or measurements. The recorded runs used the prior 2-GB Postgres shared buffer and larger ceilings; they did not recreate the acceptance deployment with the revised settings.

Keep Postgres, indexes/WAL, monitoring, simulator state and the temporary DVR spool on local storage. The short runs extrapolate to 2.2–2.4 GB/day of Postgres growth for ten virtual aircraft. With 90-day state/snapshot, 30-day telemetry and two-day bulk retention, that is approximately 165–178 GB after 90 days, before WAL and free-space headroom. A conservative estimate with six more aircraft is 263–285 GB if their telemetry resembles the simulator. Measure a full day before relying on either projection.

Included 160-GB NVMe is a starting capacity; it is not a promise that the final 90-day dataset fits. Reevaluate growth during the first month, and expand or adjust retention before 70 percent disk usage. Terraform’s terminal_staging_data_gb=0 uses included NVMe. A positive value provisions an extra volume. Adding a volume to an existing server requires an explicit migration with writers stopped; changing Terraform does not move existing Docker data or rerun cloud-init.

The sixteen-stream run used at most 417 MiB of temporary DVR spool while uploads succeeded. An S3 outage changes that: 36 Mbps of input adds roughly 16 GB per hour until uploads recover. Choose an outage buffer separately from retained video capacity.

Closed DVR recordings and review objects live in S3. Capacity grows with usage; do not preallocate the video archive as server block storage.

GB/day ≈ total recorded Mbps × 10.8
GB retained ≈ GB/day × retention days

Ten simulated cameras at 1.2 Mbps each produce about 130 GB/day. Six additional continuous 4-Mbps real cameras add 259 GB/day. Thirty days of all sixteen is about 11.7 TB in object storage. Actual bitrate, flight duty cycle and retention determine storage and transfer charges. Object storage billing

Server backups include data stored on the root NVMe but exclude attached volumes and object storage. Keep a tested database-and-object recovery process regardless of the chosen disk layout.