Single-Tenant Architecture
Pocket Kit is architected around strict single-tenant process isolation and zero shared memory.
Every database instance runs as an independent operating system process with dedicated memory space, filesystem sandboxing, and its own SQLite database engine.
1. Global Request Ingress & Isolation Topology
The following diagram illustrates how inbound client traffic is routed from the edge network through TLS termination to isolated tenant runtimes:
flowchart TD
Client["🌐 Public Internet Client<br/>(Web App / Mobile SDK / AI Agent / API Consumer)"]
subgraph IngressLayer ["Automated Ingress & Security Layer (Caddy 2)"]
Proxy["⚡ Edge Reverse Proxy & TLS Termination<br/>(Dynamic Route Engine on Port 443)"]
end
subgraph TenantA ["Tenant A Process (PID 1042)"]
PB_A["PocketBase Go Engine A<br/>(127.0.0.1:8091)"]
DB_A[("SQLite Database A<br/>(data.db in WAL mode)")]
JS_A["Goja JSVM Sandbox A<br/>(pb_hooks / pb_migrations)"]
PB_A --> DB_A
PB_A --> JS_A
end
subgraph TenantB ["Tenant B Process (PID 1088)"]
PB_B["PocketBase Go Engine B<br/>(127.0.0.1:8092)"]
DB_B[("SQLite Database B<br/>(data.db in WAL mode)")]
JS_B["Goja JSVM Sandbox B<br/>(pb_hooks / pb_migrations)"]
PB_B --> DB_B
PB_B --> JS_B
end
subgraph StaticDocs ["Documentation Ingress"]
DocsSite["Static Astro Starlight<br/>(docs.pocket-kit...)"]
end
Client -->|"HTTPS / Port 443"| Proxy
Proxy -->|"Host: app-alpha.pocket-kit..."| PB_A
Proxy -->|"Host: app-beta.pocket-kit..."| PB_B
Proxy -->|"Host: docs.pocket-kit..."| DocsSite
2. Multi-Tenant vs Single-Tenant Comparison
flowchart LR
subgraph MultiTenant ["Traditional Shared Multi-Tenant Cloud"]
SharedDB[("Shared DB Engine<br/>(Postgres / MySQL)")]
T1_Row["Tenant A Records"]
T2_Row["Tenant B Records"]
SharedDB --> T1_Row
SharedDB --> T2_Row
Risk["⚠️ Risk of Cross-Tenant Leaks & 'Noisy Neighbors'"]
end
subgraph SingleTenant ["Pocket Kit Single-Tenant Model"]
subgraph TA ["Tenant A"]
ProcA["Dedicated Process A"]
FileA[("Dedicated SQLite File A")]
ProcA --> FileA
end
subgraph TB ["Tenant B"]
ProcB["Dedicated Process B"]
FileB[("Dedicated SQLite File B")]
ProcB --> FileB
end
Safe["🔒 Hard OS Memory & Process Isolation"]
end
3. SQLite Concurrency (WAL Mode)
Pocket Kit configures all tenant instances with SQLite Write-Ahead Logging (WAL):
flowchart LR
R1["Inbound Read Query 1"] --> Reader1["SQLite Reader 1"]
R2["Inbound Read Query 2"] --> Reader2["SQLite Reader 2"]
Reader1 --> DB_Read[("Read from data.db & WAL Journal")]
Reader2 --> DB_Read
W1["Inbound Write Action"] --> Writer["Dedicated Sequential Writer"]
Writer --> WAL_Append[("Append to data.db-wal")]
- Non-Blocking Concurrent Reads: Unlimited simultaneous readers never block incoming writes.
- Instant Commits: Write transactions write sequentially to the
-waljournal file. - Zero Corruption Risk: System restarts automatically replay the WAL journal safely.