Performance & Scaling
ProBeya's performance infrastructure ensures the platform remains responsive under enterprise load with connection pooling, read replica routing, CDN asset delivery, and comprehensive monitoring.
Overview
Enterprise deployments with thousands of concurrent users across multiple sites require:
- Connection pooling: PgBouncer-managed database connections to prevent pool exhaustion
- Read replicas: Write/read split for query-heavy operations (dashboards, reports, benchmarking)
- CDN caching: Static assets and generated reports served from edge locations
- Monitoring: Real-time health checks, performance metrics, and alerting
Architecture
Connection Pooling
Database connections are managed through PgBouncer in transaction pooling mode:
- Maximum 200 server-side connections shared across all application instances
- Client-side connections limited to 20 per Node.js process
- Idle connections released after 30 seconds
- Statement-level pooling for short-lived queries
- Separate pool configurations for the primary database (
DATABASE_URL) and admin operations (DATABASE_ADMIN_URL)
The Drizzle ORM client in packages/db/src/client.ts connects through the pooler. The withTenantContext() helper uses SET LOCAL within transaction boundaries, which is compatible with transaction-level pooling because the setting is scoped to the transaction and automatically reset when the connection is returned to the pool.
Read Replicas
Query-heavy operations are routed to read replicas:
- Dashboard widgets use read replica for aggregation queries
- Benchmarking cross-site comparisons run against replicas
- Report generation offloaded to replicas
- AI insights anomaly detection reads from replicas
- Writes always go to the primary database
- Replication lag is typically under 100ms; stale reads are acceptable for analytics workloads
CDN Integration
Static assets are served through a CDN layer:
- Next.js static exports cached at edge locations
- Uploaded files (logos, documents) served through CDN with cache headers
- Generated PDF reports cached for repeated downloads
- Cache invalidation triggered on content updates
- S3-compatible storage (MinIO in development, any S3 endpoint in production) serves as the origin for file assets
WebSocket Scaling
The apps/ws/ standalone WebSocket server uses Redis pub/sub for horizontal scaling:
- Multiple WS server instances share state through Redis channels
- Presence information (who is viewing which board) is broadcast across instances
- Room membership is managed per-process with Redis as the coordination layer
- Yjs CRDT documents use Redis as the transport for real-time collaborative editing
Caching Strategy
ProBeya implements multi-level caching:
| Level | Technology | Use Case | TTL |
|---|---|---|---|
| Browser | HTTP cache headers | Static assets, fonts, icons | 1 year (immutable) |
| CDN | Edge cache | Generated reports, public embeds | 5 minutes |
| Application | Redis | Session data, rate limit counters | Varies |
| Database | PostgreSQL shared buffers | Hot query results | Managed by PG |
Monitoring
ProBeya exposes health and performance endpoints:
/api/health— Database connectivity, Redis status, S3 accessibility/api/metrics— Request latency percentiles, active connections, error rates- Structured logging for request tracing across services
- Alert thresholds for degraded performance
- WebSocket connection count and message throughput monitoring
Performance Targets
| Metric | Target |
|---|---|
| Dashboard page load | < 2 seconds (p95) |
| API response time | < 500ms (p95) |
| WebSocket message delivery | < 100ms (p95) |
| Concurrent users | 10,000+ |
| Database connections | 200 pooled |
| Error rate | < 1% |
| Uptime | 99.9% |
| S3 upload latency | < 3 seconds for 2 MB file |
Query Optimization
Performance-critical queries follow these patterns:
- Pagination: All list endpoints use
limit/offsetwith total count queries to prevent unbounded result sets - Selective columns: Queries select only the columns needed for rendering, avoiding full-row scans
- Indexed filters:
organizationId,boardId, anddatecolumns are indexed for tenant-scoped filtering - Batch operations: KPI ingestion, capacity plan entries, and item value updates support batch upsert to minimize round trips
- Parallel fetching: Dashboard widgets and board data use
Promise.allfor concurrent queries rather than sequential waterfalls
Deployment Topology
+-- CDN Edge --+
| |
Browser --> Reverse Proxy --> Next.js (apps/web)
| |
+-- WS Server (apps/ws) --+
| |
PostgreSQL 16 Redis 7
(Primary + Replicas) (Pub/Sub + Cache)
|
S3/MinIO
(File Storage)
Each service is independently scalable. The Next.js app runs as multiple replicas behind a load balancer. The WS server scales horizontally with Redis as the coordination backbone.
Related Features
- Analytics — Performance-optimized aggregation queries
- Benchmarking — Read-replica routed cross-site comparisons
- Embeddable Widgets — CDN-cached public embed data