Multi-tenant SaaS
The primary use case: one app, multiple customers, each with their own process.
customer1.myapp.com → api:customer1customer2.myapp.com → api:customer2tenement handles subdomain routing automatically.
1. Single-tenant app (no multi-tenant logic)
import osfrom fastapi import FastAPIimport uvicorn
app = FastAPI()db_path = os.getenv("DATABASE_PATH") # /data/customer123/app.db
@app.get("/")def hello(): return "Hello!"
@app.get("/health")def health(): return {"status": "ok"}
if __name__ == "__main__": port = int(os.getenv("PORT", "8000")) uvicorn.run(app, host="127.0.0.1", port=port)2. Configure tenement
[settings]data_dir = "/var/lib/myapp"
[service.api]command = "python app.py"health = "/health"isolation = "namespace"idle_timeout = 300
[service.api.env]DATABASE_PATH = "{data_dir}/{id}/app.db"3. Spawn per customer
ten spawn api --id customer123# customer123.api.myapp.com now routes to their isolated instance4. Add HTTPS (production)
See Production Deployment for TLS setup with Caddy.
Why This Works
Section titled “Why This Works”- Simple app code - No multi-tenant data isolation complexity
- Strong isolation - Process boundary, data can’t leak
- Per-customer billing - Easy to track and charge
- Cost effective - Idle customers cost $0 (scale-to-zero)
Each customer is just: ten spawn api --id $customer_id