miroir/docs/horizontal-scaling/single-pod.md
jedarden dee4367a24 P6.11: Add single-pod oversized mode support (§14.10 vertical scaling escape valve)
Add test fixture and documentation for single-pod mode with oversized resources
(4 vCPU / 8 GB) for dev clusters, very small deployments, or constrained environments.

- Add charts/miroir/tests/valid-single-pod-oversized.yaml test fixture
- Add docs/horizontal-scaling/single-pod.md with configuration example, memory
  multiplier behavior table, and fault tolerance trade-offs
- Update charts/miroir/tests/README.md to document the new test case
- Update charts/miroir/tests/run-tests.sh to include the test in validation

Acceptance criteria:
-  Fixture boots a single 4-vCPU/8-GB pod successfully
-  values.schema.json accepts the oversized-single-pod combination
-  Memory-multiplier behavior documented with operator override option
-  single-pod.md includes fault tolerance trade-off explanation
-  README.md "When to use" section calls out single-pod mode

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 07:29:39 -04:00

81 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Single-Pod Mode
Single-pod mode runs Miroir with a single orchestrator pod using SQLite as the task store. This is a **vertical scaling escape valve** for dev clusters, very small deployments, or constrained environments.
## Configuration
```yaml
miroir:
replicas: 1
resources:
limits:
cpu: "4"
memory: "8Gi"
requests:
cpu: "2"
memory: "4Gi"
taskStore:
backend: sqlite
path: /data/miroir-tasks.db
hpa:
enabled: false
```
## Memory multiplier behavior
When provisioning a single oversized pod, the memory budgets scale linearly by the multiplier relative to the baseline (2 vCPU / 3.75 GB):
| Memory limit | Multiplier | `idempotency.max_cached_keys` | `session_pinning.max_sessions` | `task_registry.cache_size` |
|--------------|------------|------------------------------|-------------------------------|----------------------------|
| 3.75 GB | 1× (baseline) | 1,000,000 | 100,000 | 10,000 |
| 7.5 GB | 2× | 2,000,000 | 200,000 | 20,000 |
| 8 GB | ~2.13× | 2,130,000 | 213,000 | 21,300 |
**Operator override:** Instead of relying on auto-scaling, operators may explicitly set these values in their config:
```yaml
idempotency:
max_cached_keys: 2000000
session_pinning:
max_sessions: 200000
task_registry:
cache_size: 20000
```
## Trade-offs
Single-pod mode is **supported but not recommended for production**:
| Aspect | Multi-pod (recommended) | Single-pod |
|--------|------------------------|------------|
| **Fault tolerance** | Survives pod loss; zero-downtime rollouts | Pod loss = full outage; rolling updates cause downtime |
| **Query throughput** | Scales horizontally via HPA | Limited to single pod capacity |
| **Memory pressure** | Distributed across pods | All budgets on one pod |
| **Operational complexity** | Requires Redis task store | Simpler (SQLite only) |
## When to use
- **Dev clusters** — Local testing, development environments
- **Very small deployments** — Low query throughput, small corpus
- **Constrained environments** — Limited node capacity, resource quotas
- **Edge deployments** — Single-node Kubernetes clusters
## Migration to multi-pod
To migrate from single-pod to multi-pod:
1. Provision a Redis instance (or enable the chart's Redis)
2. Change `taskStore.backend: redis`
3. Set `miroir.replicas: 2`
4. Enable `hpa.enabled: true` (optional)
5. Apply the updated Helm release
Data migration is automatic — the orchestrator will replicate SQLite state to Redis on startup.
## Reference
See [plan.md §14.10](../plan/plan.md#1410-vertical-scaling-escape-valve) for the full design specification.