Skip to content

Multi-Tenancy

ParticleDB supports namespace-based multi-tenancy where each tenant operates in an isolated namespace with configurable resource quotas. Namespaces provide schema-level isolation, usage tracking, and lifecycle management (suspend, resume, delete).

A namespace acts as an independent schema scope. Tables within a namespace are stored with a namespace.table_name prefix. The default namespace is public (PostgreSQL-compatible).

CREATE NAMESPACE tenant_acme;

Create a namespace with custom resource quotas:

CREATE NAMESPACE tenant_acme WITH (
max_tables = 50,
max_storage_gb = 5,
max_connections = 100,
max_rows_per_table = 10000000,
max_queries_per_minute = 500
);

Switch the session’s default namespace. All unqualified table names resolve within this namespace:

SET NAMESPACE 'tenant_acme';
SHOW NAMESPACES;

Returns all namespaces with their status, owner, quotas, and current usage.

ALTER NAMESPACE tenant_acme SET (max_connections = 200, max_queries_per_minute = 1000);
DROP NAMESPACE tenant_acme;

Dropping a namespace marks it as Deleted and removes all associated tables.

Each namespace enforces the following configurable quotas:

QuotaDefaultDescription
max_tables100Maximum number of tables in the namespace
max_storage_gb10Maximum total storage in GB
max_connections50Maximum concurrent connections
max_rows_per_table100,000,000Maximum rows per table
max_queries_per_minute1,000Rate limit (0 = unlimited)

When a quota is exceeded, the operation that would violate it is rejected with a descriptive error. Quotas are checked on every table creation, INSERT, and connection establishment.

Namespaces have three lifecycle states:

StateReadsWritesDescription
ActiveYesYesNormal operation
SuspendedYesNoReads allowed, writes blocked
DeletedNoNoMarked for removal

Temporarily block writes to a namespace (useful for billing holds or maintenance):

SUSPEND NAMESPACE tenant_acme;

Re-enable writes:

RESUME NAMESPACE tenant_acme;

The namespace manager tracks real-time resource consumption for each namespace:

MetricDescription
table_countCurrent number of tables
storage_bytes_usedTotal bytes consumed by table data
active_connectionsCurrent concurrent connections
total_rowsTotal rows across all tables
queries_this_minuteQueries executed in the current minute window

Usage events (table create/drop, row insert/delete, connection open/close, query execution) are recorded automatically and checked against quotas in real time.

When a namespace is active, unqualified table names are prefixed with the namespace:

SET NAMESPACE 'tenant_acme';
CREATE TABLE orders (id BIGINT PRIMARY KEY, amount FLOAT64);
-- Internally stored as: tenant_acme.orders
-- Explicit cross-namespace reference
SELECT * FROM tenant_beta.orders;

Query the namespace metadata directly:

SELECT * FROM __pdb_stat_namespaces;

This virtual table exposes namespace name, owner, status, creation time, quotas, and current usage in a single row per namespace.