Stratum vs the alternatives
Seven honest comparisons — from rolling your own to auth-layer orgs, tenant databases, and authorization engines. Where each fits, and where Stratum does.
Stratum vs rolling your own (tenant_id)
The default choice. Add a column, filter every query, ship it. Works fine early on. The problem is what happens next.
On day one, rolling your own looks correct. A tenant_id column is simple,
understood by every developer on your team, and requires no dependencies. You're not
over-engineering. Good instinct.
The issue isn't day one. It's month 18.
By month 18, your hand-rolled solution has accumulated: a config table with no inheritance model, audit logging added retroactively and missing half the mutation points, no isolation options beyond the shared schema you started with, and GDPR compliance that lives in a Notion doc but not in code. When an enterprise customer demands a separate database for their data, you're looking at a full-quarter migration.
Stratum gives you month-18 features on day one. Not because you need them all immediately — but because the architecture is already in place when you do.
| Capability | Rolling your own | Stratum |
|---|---|---|
| Setup time | 1–2 days | 5 minutes |
| Tenant hierarchy | Build it yourself (weeks) | Built-in (ltree, 20 levels) |
| Config inheritance | Build it yourself | Built-in, root-to-leaf |
| Isolation strategies | Manual RLS only | RLS, schema, database — per tenant |
| Audit logging | Bolt on later | Every mutation, actor-attributed |
| GDPR (Art. 17 + 20) | Build it yourself | Export + purge, built-in |
| Field encryption | Build it yourself | AES-256-GCM, transparent |
| Month-18 cost | 3+ months engineering | Already done |
Stratum vs WorkOS / Frontegg
WorkOS and Frontegg are excellent products. They solve a real problem. Just not the same problem Stratum solves.
WorkOS and Frontegg operate at the identity and authentication layer. They handle SSO, SCIM provisioning, audit logs for auth events, and organization management in the context of who can log in. They do this extremely well.
Stratum operates at the data tenancy layer. It handles how your database stores, isolates, and manages data across tenants. These are different problems at different levels of your stack, and the right answer for most teams is both.
Use WorkOS or Frontegg to manage authentication and user provisioning. Use Stratum to manage data isolation, config inheritance, and compliance operations on the PostgreSQL side. They complement each other — they don't compete.
| Capability | WorkOS / Frontegg | Stratum |
|---|---|---|
| SSO / SAML / SCIM | Yes — core product | Not in scope |
| Auth event audit log | Yes | Not in scope |
| Data isolation strategies | No | RLS, schema, database |
| Tenant hierarchy / tree | Flat organizations only | 20-level tree, ltree-backed |
| Config inheritance | No | Root-to-leaf, lockable keys |
| GDPR data operations | Partial (auth data only) | Full export + hard purge |
| Data mutation audit log | No | Every mutation, actor-attributed |
| Pricing model | Proprietary SaaS | Open source, MIT |
The right stack: WorkOS or Frontegg for authentication and user management. Stratum for data tenancy and compliance. Both in the same application, each doing what it's built for.
Stratum vs ABP Framework
ABP is the gold standard for multi-tenancy in the .NET ecosystem. Stratum is the equivalent for Node.js — the library that should have existed years ago.
ABP Framework (formerly ABP.IO) is a mature, opinionated application framework for .NET that includes multi-tenancy as a first-class concern. Teams building C# applications have had this foundation for years. It's well-documented, battle-tested, and handles the full lifecycle: tenant resolution, data isolation, config, and more.
Node.js and TypeScript developers have had no equivalent. When we looked at what ABP provides and compared it to the npm ecosystem, the gap was stark. We built Stratum to close it.
Stratum is not a port of ABP — the Node.js and TypeScript ecosystem has different conventions and constraints. But the motivation is the same: give developers in this ecosystem a stable, production-ready multi-tenancy foundation so they stop reinventing it.
| Capability | ABP Framework (.NET) | Stratum (Node.js) |
|---|---|---|
| Runtime | .NET / C# | Node.js / TypeScript |
| Tenant resolution | Yes (header, subdomain, JWT) | Yes (SDK middleware) |
| Data isolation | Schema + database strategies | RLS, schema, database |
| Tenant hierarchy | Parent-child (2 levels typical) | Arbitrary depth, ltree-backed |
| Config inheritance | Settings system | Root-to-leaf, lockable keys |
| GDPR tooling | Partial via modules | Export + purge, built-in |
| Open source | Partial (community edition) | Fully open source, MIT |
| npm / TypeScript native | No | Yes — built for the ecosystem |
Stratum vs Clerk Organizations
Clerk Organizations (and Auth0 Organizations) give you multi-tenant auth: org membership, invitations, and SSO scoped per organization. Stratum gives you multi-tenant data. Different halves of the same feature.
Clerk Organizations and Auth0 Organizations live at the authentication and
membership layer. They model who belongs to which org, hand you a polished
invitation and member-management UI, let each organization bring its own SSO connection,
and put an org_id in the session token. For the login and org-switching
experience, they are hard to beat.
What they deliberately don't touch is the layer below the token. They don't isolate a tenant's rows in your database, inherit config down through nested tenants, enforce row-level security, audit the data mutations your app performs, or purge a tenant's data for a GDPR request. That's not a gap in the products — it's simply not the layer they operate at.
Stratum takes the org_id those systems already resolve and builds the tenant
data layer beneath it: the isolation strategy, the config tree, permission delegation, and
the compliance workflows. The two compose cleanly — Clerk decides who is in the org,
Stratum decides what that org's data can do and where it lives.
| Capability | Clerk / Auth0 Orgs | Stratum |
|---|---|---|
| Org membership + invites | Yes — core product | Not in scope |
| SSO per organization | Yes | Not in scope |
| Data isolation strategies | No | RLS, schema, database |
| Nested tenants | Flat orgs (+ optional sub-orgs) | 20-level tree, ltree-backed |
| Config inheritance | No | Root-to-leaf, lockable keys |
| Data mutation audit log | No | Every mutation, before/after state |
| GDPR purge of tenant data | No | Full export + hard purge |
| Pricing model | Proprietary SaaS | Open source, MIT |
Use both: Clerk (or Auth0) for authentication and the org-membership UI your users see. Stratum for the tenant data layer beneath it — isolation, config, and compliance. They sit at different layers and slot together.
Stratum vs Nile
Nile (thenile.dev) is a tenant-aware Postgres you adopt and host with them. Stratum is a library over the Postgres you already run. The split is: their database, or your database with a tenancy model on top.
Nile virtualizes tenants at the database itself — you build on Nile's hosted Postgres and get per-tenant isolation baked into the platform. If you're greenfield and comfortable putting your data on a startup database vendor, it's an elegant story: tenancy is a property of the database, not something you assemble in application code.
Stratum takes the opposite stance on where tenancy lives. It's an MIT-licensed library that runs over your existing PostgreSQL — RDS, Supabase, Neon, or self-hosted — so there's no database to migrate to and no vendor to depend on. On top of that Postgres it adds the application-layer tenancy model Nile doesn't aim to cover: nested tenant hierarchy, config inheritance with lockable keys, permission delegation, and GDPR export/purge workflows.
So the choice is less feature-by-feature and more about ownership. Nile asks you to adopt a database; Stratum asks you to keep yours and drop in a layer. If nested tenancy, config inheritance, or compliance operations matter to you, those are Stratum's territory regardless of which Postgres you run.
| Capability | Nile | Stratum |
|---|---|---|
| What it is | Hosted tenant-aware Postgres | Library over your Postgres |
| Runs on existing DB | Adopt their database | RDS, Supabase, Neon, self-hosted |
| Per-tenant isolation | Yes — at the DB | RLS, schema, database |
| Nested tenant hierarchy | Flat tenants | 20-level tree, ltree-backed |
| Config inheritance | No | Root-to-leaf, lockable keys |
| Permission delegation / ABAC | No | Delegation modes + ABAC policies |
| GDPR export + purge | No | Article 20 export, Article 17 purge |
| Lock-in / licensing | Vendor-hosted | No lock-in, MIT |
Choose by ownership: greenfield and happy to host your data with a startup database vendor → Nile is a genuinely elegant fit. Existing Postgres, or you need nested tenancy, config inheritance, or compliance workflows → Stratum layers onto what you already run.
Stratum vs Oso / Permit.io
Oso and Permit.io are authorization engines: policy-as-code for evaluating who can do what. Stratum is a tenancy layer that happens to include scoped permissions. They overlap at one edge and diverge everywhere else.
Oso and Permit.io are built to answer one question extremely well: given a subject, an action, and a resource, is it allowed? They give you a policy language, ReBAC/ABAC evaluation, and a place to centralize app-wide authorization logic. If your access rules are rich and cross-cutting, a dedicated policy engine is the right tool.
What they don't provide is the tenancy substrate: the tenant data model, the isolation strategies (RLS, schema, database), config inheritance down a tenant tree, tenant lifecycle operations like onboarding, archive, and purge, or an audit trail of tenant data mutations. A policy engine decides whether an action is allowed; it doesn't store, isolate, or manage the tenants themselves.
There is one honest overlap. Stratum's permission delegation and ABAC cover permissions within a tenant hierarchy — delegation modes with cascade revocation, and ABAC policies that inherit down the tree. That's narrower and more opinionated than a general policy engine, and for tenancy-scoped access it's usually enough on its own.
| Capability | Oso / Permit.io | Stratum |
|---|---|---|
| General policy-as-code authz | Yes — core product | Tenancy-scoped only |
| ReBAC / ABAC evaluation | Yes, general-purpose | ABAC + hierarchical inheritance |
| Tenant data model | No | Hierarchy, ltree-backed |
| Isolation strategies | No | RLS, schema, database |
| Config inheritance | No | Root-to-leaf, lockable keys |
| Tenant lifecycle | No | Onboard, archive, purge |
| Data mutation audit log | No | Every mutation, before/after state |
| Licensing | Open core / SaaS | Open source, MIT |
Choose by scope: complex, app-wide authorization policy → pair an authz engine like Oso or Permit.io with Stratum's tenant layer. Permissions that only ever run within your tenant hierarchy → Stratum's built-in delegation and ABAC are usually enough on their own.
The short version
The DIY approach works until it doesn't. Stratum gives you the infrastructure you'll need at month 18, from day one.
Different layer of the stack. Use them for auth. Use Stratum for data. They complement each other.
ABP is great for .NET. Stratum fills the same role for Node.js. If you're writing TypeScript, there's no equivalent — until now.
They own auth and org membership. Stratum owns the tenant data layer beneath the token — isolation, config, compliance. Compose them.
Nile is a database you host with them. Stratum is a library over the Postgres you already run — plus nested tenancy and compliance. No lock-in.
Policy engines evaluate authz; they don't model tenants. Pair one with Stratum for app-wide policy, or use Stratum alone for tenancy-scoped permissions.
See how Stratum works with your stack
Stratum integrates with the ORM and database you already use. No migration required.
Start with Stratum today
npm install @stratum-hq/lib pg