Operations
Partitioning guidance
When and how to partition the go-sequent event store inside the shared-schema, tenant_id model: partition_key, triggers, recommended steps, optional RLS and the example SQL.
Partitioning guidance
Model: one shared schema with tenant_id columns and hooks. It is not schema-per-tenant and not database-per-tenant.
Physical partitioning is optional and stays inside that shared schema. The migrations create non-partitioned tables. The SQL in the repository under docs/ops/sql/ is guidance only. Apply it deliberately, after a capacity review. store.Migrate and go-sequent migrate never run it.
When to partition
| Symptom | Candidate |
|---|---|
events is far beyond tens of GB, or vacuum is hot |
Partition by partition_key, often tenant_id or tenant_id:shard |
Very large commands |
Range partition by time, or hash by id |
| Cross-tenant scans are rare | Prefer prune-friendly keys that match your load filters |
go-sequent already stores events.partition_key and aggregates.events_partition_key. Set the partition key from tenancy.PartitionKey or tenancy.PartitionKeyHashed:
key := tenancy.PartitionKey(tenantID) // tenantID is a uuid.UUID
// or, to spread one large tenant over several buckets, add a shard string:
hashed := tenancy.PartitionKeyHashed(tenantID, shard)
See Tenancy for the other helpers.
Recommended approach
- Keep logical multi-tenancy through
tenant_idon commands, events, aggregates and projections. - Set
partition_keytotenant_id, or to tenant plus a hash, for stream locality. - If needed, convert
eventsinto a partitioned parent. Use one partition per tenant hash bucket, or one per tenant for very large tenants. aggregate_unique_keysstays global within the schema. Include the tenant in unique-key scopes withtenancy.UniqueScope.- Do not create per-tenant schemas as the product model.
Row Level Security
Row Level Security on tenant_id is optional and adds depth. Keep enforcing the tenant match in the repository and on load as well. See Tenancy.
Interaction with HA and backups
- Partition pruning helps the primary and the replicas. Rebuild workers should filter by partition ranges.
- Backups remain cluster-level. See Backup and restore.
Example SQL
The file docs/ops/sql/events_partition_by_tenant_hash.example.sql in the repository is an illustration of hash partitioning by tenant. It is not applied automatically.
Related
Docs track the go-sequent library. When APIs drift, the source wins.