Service Supavisor - thekaveh/atlas GitHub Wiki
5.2.51. Supavisor
1. Overview
Supavisor is Atlas's optional Supabase Postgres transaction pooler. It protects supabase-db from connection growth as backend workers, workflows, notebooks, and data services expand.
Supavisor is disabled by default. When enabled, it routes only the backend, the Celery worker, n8n and n8n-worker through transaction mode.
2. Access
Supavisor speaks the Postgres wire protocol on transaction port 6543 inside the container. The listener is internal-only. It uses no host port and no topology port slot.
There is no Kong alias for Supavisor. The management API is also internal-only, because it is not a browser dashboard.
3. Configuration
Set SUPAVISOR_SOURCE=container to enable the pooler. Leave SUPAVISOR_SOURCE=disabled for the default direct-Postgres behavior.
Key variables:
| Variable | Purpose |
|---|---|
SUPAVISOR_SOURCE |
disabled or container. |
SUPAVISOR_TENANT_ID |
Tenant suffix appended to the Postgres user. Default: atlas; must match [A-Za-z0-9_-]+ with no surrounding whitespace. |
SUPAVISOR_DEFAULT_POOL_SIZE |
Per-user upstream pool size. Default: 20. |
SUPAVISOR_MAX_CLIENT_CONN |
Maximum accepted client connections. Default: 100. |
SUPAVISOR_DB_POOL_SIZE |
Supavisor metadata DB pool size. Default: 5. |
SUPAVISOR_VAULT_ENC_KEY |
Exactly 32 bytes; generated by the bootstrapper when blank. |
Generated client variables:
| Variable | Enabled value | Disabled rollback value |
|---|---|---|
SUPAVISOR_DATABASE_URL |
postgresql://${BACKEND_DB_USER_URI}.${SUPAVISOR_TENANT_ID}:...@supavisor:6543/${SUPABASE_DB_NAME_URI} |
Scoped Backend direct URL |
SUPAVISOR_DB_HOST |
supavisor |
supabase-db |
SUPAVISOR_DB_PORT_VALUE |
6543 |
5432 |
SUPAVISOR_DB_USER |
${N8N_DB_USER}.${SUPAVISOR_TENANT_ID} |
${N8N_DB_USER} |
4. Architecture & wiring
Supavisor depends on supabase-db-init, uses a dedicated management login for migrations and authentication lookup, evaluates pooler/pooler.exs, then starts the pooler server. Pooled clients retain their own PostgreSQL role and password.
Pooled consumers:
| Consumer | Pooled setting |
|---|---|
| backend | DATABASE_URL=${SUPAVISOR_DATABASE_URL:-...direct...} |
| Celery worker | DATABASE_URL=${SUPAVISOR_DATABASE_URL:-...direct...} |
| n8n | DB_POSTGRESDB_HOST/PORT/USER from generated Supavisor envs |
| n8n-worker | Mirrors n8n DB settings |
Direct Supabase consumers intentionally remain direct until session/native behavior is proven:
| Direct consumer | Reason |
|---|---|
PostgREST (supabase-api) |
Session-sensitive API surface; not yet audited for transaction mode. |
| Realtime | Replication/session behavior stays direct. |
| GoTrue/Auth | Core Supabase service; direct until separately validated. |
| Storage, Meta, Studio | Core Supabase internals stay on supabase-db:5432. |
supabase-db-init, postgres-exporter |
Bootstrap and scrape paths stay direct. |
5. Capabilities & limitations
Support tier: experimental — Capability contract declared; no cited cold-start, workflow, or upgrade qualification run yet (evidence at v0.1.0).
| Capability | Status | Verification | Notes |
|---|---|---|---|
| Transaction pooling for selected application clients | partial | tested | Atlas routes backend, Celery, and n8n through Supavisor transaction pooling when enabled, while session-sensitive Supabase services remain on direct PostgreSQL connections. |
| Zero-edit direct Postgres rollback | supported | tested | Disabling Supavisor restores the selected consumers to their existing direct Supabase endpoints without changing application code or credentials. |
| Public pooler endpoint | not-supported | tested | The Supavisor port is backend-network only and Atlas publishes neither a host binding nor a Kong route for external database clients. |
6. Rollback
Set SUPAVISOR_SOURCE=disabled and rerun ./start.sh. The bootstrapper resets SUPAVISOR_DATABASE_URL, SUPAVISOR_DB_HOST, SUPAVISOR_DB_PORT_VALUE and SUPAVISOR_DB_USER to direct supabase-db:5432 values. The backend, Celery and n8n then connect directly, with no compose-file edits.
7. Troubleshooting
FATAL: Tenant or user not found: confirm the client username includes the tenant suffix, for example${BACKEND_DB_USER}.${SUPAVISOR_TENANT_ID}.VAULT_ENC_KEYerrors: make sureSUPAVISOR_VAULT_ENC_KEYis exactly 32 bytes. The bootstrapper generates this when the value is blank.- Backend or n8n auth failures after enabling: set
SUPAVISOR_SOURCE=disabledto roll back, then inspect Supavisor tenant bootstrap logs. - The tenant is created once and never updated (
pooler/pooler.exs, matching upstream Supabase). If.envis regenerated while volumes are kept, the scoped manager password changes but the stored tenant keeps the old one. Later edits toSUPAVISOR_DEFAULT_POOL_SIZE/SUPAVISOR_MAX_CLIENT_CONNalso have no effect. To fix either, re-create the tenant (below). - No Kong alias or host port is expected. Consumers connect over the Compose network at
supavisor:6543.
Re-create the tenant. Supavisor has no volume of its own, so do not touch the supabase-db volume.
- In the
supavisordatabase onsupabase-db, runDELETE FROM _supavisor.tenants WHERE external_id = '<SUPAVISOR_TENANT_ID>';. Its_supavisor.usersrows cascade. - Restart Supavisor.
8. Dependencies & Integrations
8.1. Current — Upstream (this service calls)
| Service | Category |
|---|---|
| supabase | data |
8.2. Current — Downstream (services that call this)
| Service | Category |
|---|---|
| celery | agents |
| n8n | agents |
| backend | apps |
8.3. Architecture diagram

Open the full-size diagram for a full-screen view.
8.4. Future — Missing pair integrations
No high-confidence opportunities identified.
8.5. Future — Candidate new services
No high-confidence opportunities identified.
8.6. Future — Unused features in this service
No high-confidence opportunities identified.