# Experimental Support Matrix Everything here is off unless its `backend.jpa.experimental.*` flag is explicitly true, and none of it is part of the Stable composition. | Feature | Flag | State | |---|---|---| | Shared-schema multi-tenancy (column) | `backend.jpa.experimental.multitenancy-column` | Experimental | | PostgreSQL RLS multi-tenancy | `backend.jpa.experimental.multitenancy-rls` | Experimental | | Schema-per-tenant | `backend.jpa.experimental.multitenancy-schema` | Experimental | | Database-per-tenant | `backend.jpa.experimental.multitenancy-database` | Experimental | | Consistency-aware read replica | `backend.jpa.experimental.read-replica` | Experimental | | Jakarta Persistence 4.0 lane | `backend.jpa.experimental.jakarta-persistence-4` | Experimental | | Hibernate ORM 8 lane | `backend.jpa.experimental.hibernate-8` | Experimental | | PostgreSQL 19 lane | `backend.jpa.experimental.postgresql-19` | Experimental | Presence on the classpath is not consent. `ExperimentalFeatureGate` fails startup when a module is present and its flag is not set, because an experimental module can arrive transitively and a tenant-isolation feature that switched itself on would be the worst possible default. ## Known constraints - Tenant context is fail-closed. An unbound tenant in a shared-schema deployment means a query with no tenant predicate, which returns every tenant's rows. - A Hibernate filter is not the security boundary. It does not apply to native SQL, bulk DML, `getReference`, or the second-level cache. - RLS requires all three of: `ENABLE ROW LEVEL SECURITY`, `FORCE ROW LEVEL SECURITY` (the owner is otherwise exempt from its own policies), and a runtime role without `BYPASSRLS`. - Tenant bindings are transaction-local. A session-local setting survives the connection's return to the pool. - `readOnly=true` never routes to a replica on its own. Read-after-write uses a consistency token or the primary. - Unavailable replica lag evidence means the primary. Absence of evidence is not evidence of freshness. - Per-tenant pools are bounded globally. Fifty tenants with a modest pool each is five hundred connections against a server that permits a hundred. - Tenant ids never become metric tags. Tenant cardinality is unbounded by definition. ## Lanes never change Stable A compatibility lane publishes nothing and changes no Stable contract. If Hibernate 8 generates different SQL for the fetch-pagination gate, that is a finding about Hibernate 8 — the 7.x gate keeps asserting what 7.x must do, because that is what deployments run.