pediatric-ai-scribe-v3/docs/SCALING.md

119 lines
3.6 KiB
Markdown

# Scaling
This document describes how Ped-AI should scale without becoming harder to debug or maintain.
## Current Scaling Model
Ped-AI is currently a single app container backed by PostgreSQL and Redis. That is acceptable for self-hosted use, but the code should keep moving toward a shape where multiple app containers can run safely.
```txt
reverse proxy
-> pediatric-ai-scribe replica 1
-> pediatric-ai-scribe replica 2
-> shared PostgreSQL
-> shared Redis
-> LiteLLM
-> MCP
```
## Horizontal Scaling Requirements
| Requirement | Why It Matters |
|---|---|
| Session state in PostgreSQL/Redis | Any app replica can handle the next request |
| No clinical state only in memory | Restarting or scaling containers should not lose required state |
| Shared uploads/storage if files grow | Local container disk does not scale across replicas |
| Idempotent migrations | Deploying more than one app container should not corrupt schema state |
| Request timeouts | Slow providers should not exhaust Node workers |
| Queue for slow jobs | Long work should not block interactive requests |
| Readiness endpoint | Load balancer should only send traffic to ready replicas |
## What Can Stay In Memory
Small process-local caches are acceptable when they are optional and short-lived.
Examples:
- settings cache with short TTL,
- provider model metadata cache,
- static configuration derived at boot.
Do not store required user workflow state only in memory if the action must survive restart or run across replicas.
## Redis Use
Redis is appropriate for:
- prompt suggestion pools,
- rate-limit coordination if needed,
- queues and job status,
- short-lived provider metadata,
- operational locks.
Redis should not be used for final clinical answer response caching. Clinical answers should be generated live from current retrieval context.
## Queue Candidates
Consider moving these to a queue when latency or concurrency becomes a problem:
- long transcription jobs,
- file import/export,
- Learning Hub AI generation from large files,
- image generation,
- bulk document operations,
- provider metadata refresh,
- long-running admin maintenance actions.
BullMQ with Redis is a natural fit if a queue is added.
## Readiness And Health
Keep `/api/health` fast and simple for liveness.
Add a separate readiness endpoint when scaling:
```txt
GET /api/ready
```
It should check:
- PostgreSQL query works,
- Redis ping works if Redis is required for this deployment,
- core settings can be read,
- MCP health is reachable if Clinical Assistant is enabled,
- LiteLLM metadata or configured model endpoint is reachable if AI features are enabled.
## Database Scaling
Priorities:
- confirm indexes on hot user/session/settings/log tables,
- keep migrations explicit and reversible where practical,
- monitor slow queries,
- cap admin log queries with safe limits,
- keep audit/log writes batched where possible,
- avoid long transactions around provider calls.
## Provider Scaling
LiteLLM and MCP can become the bottlenecks before Ped-AI does.
Track:
- LiteLLM request latency,
- LiteLLM error rate by model,
- MCP search latency,
- MCP timeout/error rate,
- queue depth if async jobs are added,
- Postgres connections,
- app container memory and event-loop delay.
## Scaling Order
1. Add request IDs across browser, Ped-AI, MCP, and LiteLLM calls.
2. Add `/api/ready` for dependency readiness.
3. Ensure sessions and settings are not process-local.
4. Add a queue for slow jobs if interactive requests block.
5. Run a second app replica behind the reverse proxy in a staging/test environment.
6. Add metrics and alerts around latency, errors, and resource saturation.