Multi-Tenancy Patterns for SaaS That Plans to Survive
Shared schema with global scopes and row-level security, database-per-tenant fleets, why schema-per-tenant is the airplane middle seat, and the whale-tier hybrid everyone converges on.
Category
Shared schema with global scopes and row-level security, database-per-tenant fleets, why schema-per-tenant is the airplane middle seat, and the whale-tier hybrid everyone converges on.
The one load-bearing idea under all the concentric circles, the interface-with-one-implementation tax, and the three-folder dose that keeps domains pure without nine-file one-line changes.
Split the write model from screen-shaped read queries without new infrastructure: honest SQL read classes, denormalized read tables via events, and the symptoms that tell you when to bother.
Events vs commands, at-least-once reality, the transactional outbox in twenty lines, designing for eventual consistency, and schema evolution rules for events that outlive their authors.
Hard module boundaries, zero network calls: contracts and facades, tables owned by one module, in-process events, and the architecture tests that make the rules real — with Laravel examples.
The three legitimate reasons to go distributed, the rent you pay from day one, and the survival rules — few and chunky, contracts not shared databases, async by default, platform before proliferation.
A defense of the single deployable from someone who has cleaned up after both kinds of mess: what monoliths actually buy you, the mud-vs-monolith distinction, and the scale arguments dismantled one by one.
Both sides of the wire: HMAC signatures with timestamps and constant-time compares, the raw-body trap, dedupe-and-queue consumers, producer retry etiquette and the checklist that prevents 3 a.m. replays.