Skip to content

Multi-Region

Regions represent geographic or logical deployment zones. Each region can have its own database URL, control plane URL, and lifecycle status. Tenants can be migrated between regions to satisfy compliance requirements or optimize latency.

interface Region {
id: string;
display_name: string; // "EU West (Frankfurt)"
slug: string; // "eu_west"
control_plane_url: string; // "https://eu.stratum.example.com"
database_url: string; // stored but never exposed in API responses
is_primary: boolean;
status: "active" | "draining" | "inactive";
metadata: Record<string, unknown>;
}
active ──> draining ──> inactive
Status Description
active Accepting new tenants, serving traffic
draining No new tenants, existing tenants being migrated out
inactive Empty, can be safely deleted
const eu = await stratum.createRegion({
display_name: "EU West (Frankfurt)",
slug: "eu_west",
control_plane_url: "https://eu.stratum.example.com",
is_primary: false,
metadata: { provider: "aws", az: "eu-west-1" },
});
const us = await stratum.createRegion({
display_name: "US East (Virginia)",
slug: "us_east",
is_primary: true,
});

Via the API:

Terminal window
curl -X POST http://localhost:3001/api/v1/regions \
-H "X-API-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "EU West (Frankfurt)",
"slug": "eu_west",
"control_plane_url": "https://eu.stratum.example.com",
"is_primary": false,
"metadata": {"provider": "aws", "az": "eu-west-1"}
}'

Move a tenant to a different region:

await stratum.migrateRegion("tenant-uuid", eu.id);

Via the API:

Terminal window
curl -X POST http://localhost:3001/api/v1/tenants/TENANT_UUID/migrate-region \
-H "X-API-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"region_id": "EU_REGION_UUID"}'

The migration checks:

  • Tenant exists and is not archived
  • Target region exists
  • Target region status is active (not draining or inactive)
Terminal window
curl http://localhost:3001/api/v1/regions \
-H "X-API-Key: YOUR_KEY"

Drain a region before decommissioning:

Terminal window
curl -X PATCH http://localhost:3001/api/v1/regions/REGION_UUID \
-H "X-API-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "draining"}'

Deletion fails if any active tenants are assigned to the region:

Terminal window
curl -X DELETE http://localhost:3001/api/v1/regions/REGION_UUID \
-H "X-API-Key: YOUR_ADMIN_KEY"

For GDPR data residency compliance, create regions per jurisdiction and assign tenants accordingly:

// Create jurisdiction-specific regions
const eu = await stratum.createRegion({
display_name: "EU (Frankfurt)",
slug: "eu_frankfurt",
});
const us = await stratum.createRegion({
display_name: "US East (Virginia)",
slug: "us_east",
is_primary: true,
});
// EU customer data stays in EU
await stratum.migrateRegion("eu-tenant-uuid", eu.id);
// US customer data stays in US
await stratum.migrateRegion("us-tenant-uuid", us.id);

Region slugs follow the same rules as tenant slugs:

  • Lowercase letters, digits, and underscores only
  • Must start with a letter
  • Maximum 63 characters
  • Pattern: ^[a-z][a-z0-9_]{0,62}$
Route Required Scope
GET /api/v1/regions read
POST /api/v1/regions write
PATCH /api/v1/regions/:id write
DELETE /api/v1/regions/:id write
POST /api/v1/tenants/:id/migrate-region admin

The database_url field is stored internally but never exposed in API responses. This prevents accidental leakage of database credentials through the API.