Compare

Stratum + MySQL

The world's most popular open-source relational database

MySQL is the default database for millions of applications, from WordPress to Laravel to legacy enterprise systems. @stratum-hq/mysql brings Stratum's tenant isolation to MySQL with three strategies: shared table (WHERE tenant_id filtering), table-per-tenant (separate tables per tenant), and database-per-tenant (full database isolation). The control plane (tenant hierarchy, config inheritance, audit log) remains in PostgreSQL via @stratum-hq/lib. MySQL carries your application data, scoped per tenant through structured query methods or ORM integrations.

Feature comparison

Capability MySQL Stratum
Isolation strategies Manual WHERE tenant_id on every query 3 strategies: shared table, table-per-tenant, database-per-tenant
Tenant scoping Application-level only Structured methods auto-inject tenant_id into all queries
View-based isolation Manual CREATE VIEW with session variables Built-in createTenantView() with session variable management
Config inheritance Not available Built-in via PostgreSQL control plane
GDPR purge Build it yourself purgeTenantData() for all 3 strategies
ORM support TypeORM, Knex, Sequelize (manual tenant logic) TypeORM subscriber, Knex helper, Sequelize adapter included
Control plane None PostgreSQL via @stratum-hq/lib (tenant hierarchy, config, audit)
Security enforcement Application-level (no RLS in MySQL) Application-level for shared/table; DB-level for database-per-tenant

Getting started

mysql-with-stratum.ts
import mysql from "mysql2/promise";
import { Stratum } from "@stratum-hq/lib";
import { MysqlSharedAdapter } from "@stratum-hq/mysql";

// Control plane: tenant hierarchy lives in PostgreSQL
const stratum = new Stratum({ pool });
await stratum.initialize();

// MySQL adapter for application data isolation
const mysqlPool = mysql.createPool(process.env.MYSQL_URL);
const adapter = new MysqlSharedAdapter({
  pool: mysqlPool, databaseName: "myapp",
});

// Tenant created in PG control plane
const tenant = await stratum.createTenant({
  name: "Acme", slug: "acme"
});

// Scoped queries auto-inject tenant_id
const users = await adapter.scopedSelect(tenant.id, "users");
// only returns this tenant's rows

Things to know

Start building with MySQL + Stratum

npm install @stratum-hq/lib pg