Scaling
When and how to scale each service.
Last updated 2026-05-05
The single-VPS layout handles roughly 100 active tenants with low-to-medium traffic. Past that, scale services independently:
- api — stateless; add replicas behind nginx with sticky sessions disabled. Bottleneck is usually pgbouncer pool exhaustion before CPU.
- worker — stateless; add replicas freely. Each worker pulls from the BullMQ queue, so adding consumers reduces lag linearly.
- postgres — vertical first (CPU / RAM / IOPS), then a read replica for reports + a primary for writes. CRMcy's tenant-per-DB layout makes sharding straightforward later.
- redis — vertical first; if you exceed 8 GB working set, switch to a Redis Cluster.
- minio / S3 — externalize to managed S3 (AWS, Cloudflare R2, etc.).
The web and marketing apps are static-rendered enough to fit behind a CDN; offload them to Vercel / Cloudflare Pages if your origin server's bandwidth becomes a constraint.
Capacity signals
Scale up when:
- API p95 latency > 500ms for 5 consecutive minutes.
- Worker queue depth > 5000 jobs for 5 consecutive minutes.
- Postgres
cpu_user> 70% sustained. - pgbouncer
cl_waiting> 0 for any pool.
See the monitoring dashboards described in Monitoring.