Sizing
Server sizes for Grovs Community, the process settings that use them and what to raise as load grows.
The whole stack runs on one server. Every service shares its CPU, memory and disk: the Compose file sets no per-container CPU or memory limits.
Tiers
| Tier | Server | Use it for |
|---|---|---|
| Local trial | Any machine with Docker: Linux, macOS, or Windows with WSL2 | Evaluation on lvh.me. No real deep links. See Try locally. |
| Community | 4 vCPU, 8 GB RAM, 80 GB SSD | Production for up to 100,000 users |
| Enterprise | Sized with Grovs | More than 100,000 users, or more flexibility and performance. Talk to sales. |
The Community size is a starting point, not a traffic guarantee. Workload, event volume and retention decide what you need, and disk use grows with your data.
The cloud templates create larger defaults than the Community floor:
| Template | Default server |
|---|---|
| AWS | t3.xlarge, 100 GiB gp3 |
| Google Cloud | e2-standard-4, 100 GB disk |
| Azure | Standard_D4s_v5 (4 vCPU, 16 GiB RAM), 128 GiB disk |
Process sizing
These .env variables decide how many processes, threads and database connections the stack uses. The shipped values fit the Community server.
| Variable | Shipped value | Controls |
|---|---|---|
WEB_CONCURRENCY | 2 | Puma worker processes in web |
RAILS_MAX_THREADS | 5 | Threads per Puma worker |
RAILS_DB_POOL | 10 | PostgreSQL connections each backend process may open |
SIDEKIQ_EVENTS_CONCURRENCY | 10 | Threads in the events worker inside worker-1 |
POSTGRES_MAX_CONNECTIONS | 200 | PostgreSQL server connection ceiling |
Apply a change with docker compose --profile standalone up -d. Compose recreates only the containers whose settings changed.
Connection budget
POSTGRES_MAX_CONNECTIONS must cover every backend process. Each process can open up to RAILS_DB_POOL connections:
| Container | Backend processes |
|---|---|
web | WEB_CONCURRENCY |
worker-1 | 3 (scheduler, events, batch) |
worker-2 | 2 (maintenance, device updates) |
With the shipped values that is at most (2 + 3 + 2) × 10 = 70 connections, well under 200. Recompute it whenever you raise WEB_CONCURRENCY or RAILS_DB_POOL.
What to raise first
| Symptom | Raise | Keep in step |
|---|---|---|
web is CPU-bound and API or link responses slow down | WEB_CONCURRENCY | The connection budget above |
The events queue in health metrics keeps growing | SIDEKIQ_EVENTS_CONCURRENCY | RAILS_DB_POOL at or above the thread count |
| The host runs short of CPU or memory | Server size | Then the process settings |
| Disk free space keeps falling | Disk size | Monitoring |
Keep RAILS_DB_POOL at least as large as RAILS_MAX_THREADS and SIDEKIQ_EVENTS_CONCURRENCY, as the shipped values do. Never scale worker-1: it runs the scheduler and must have exactly one replica.
Disk
PostgreSQL, ClickHouse, Redis and uploads all live in Docker volumes on the server disk, and they grow with links, events and retention. Plan for growth from the start, watch free space, and leave room for backup files if you write them to the same disk first. See Backups.