Custom fields without DDL
Each tenant attaches its own attributes — store them, query them, index the hot ones.
A B2B SaaS has 5,000 tenants, each defining custom fields on projects. Storing them as columns means 5,000 ALTER TABLE migrations; storing them as JSON in a sibling table means glue code. RedDB documents put them on the row itself, indexable by tenant via a generated column.
sql
CREATE TABLE projects (
id UUID PRIMARY KEY,
org_id UUID NOT NULL,
name TEXT NOT NULL,
custom JSONB DEFAULT '{}'::jsonb
);
-- Promote the most-queried tenant's hot field to a column.
ALTER TABLE projects ADD COLUMN priority TEXT
GENERATED ALWAYS AS (custom->>'priority') STORED;
CREATE INDEX idx_projects_org_priority
ON projects (org_id, priority)
WHERE custom->>'priority' IS NOT NULL;
-- App-tier code keeps writing free-form JSON; the report query above
-- now hits a composite BTree.