Skip to content

GCP Cell Architecture

This document describes Provisionr’s multi-tenant infrastructure cell architecture on Google Cloud Platform. It covers how tenant workspaces are isolated, how cells scale with demand, and how regional boundaries are enforced.

Provisionr hosts customer workspaces on shared infrastructure organized into cells. Each cell is a single GCP project containing the compute, database, and supporting services needed to run tenant workloads. Customers choose a geographic region when creating a workspace. Fleet Control, the internal placement service, assigns that workspace to a cell in the chosen region that has available capacity.

Cells are not per-customer. A single cell serves many tenants. When a cell in a region approaches its capacity limits, a new cell is provisioned in that region and Fleet Control begins routing new tenants to it. Existing tenants remain on their original cell.

Customer requests workspace in "US" region
|
v
Fleet Control checks capacity of US cells
|
v
Assigns to provisionr-us1kb (has capacity)
|
v
Creates Cloud Run service + Cloud SQL database for tenant

All Provisionr infrastructure lives under a single GCP organization. The folder hierarchy separates headquarters infrastructure from customer-facing workspaces, and further isolates workspaces by geographic region.

organizations/590238363521
|
+-- hq/ Provisionr internal infrastructure
|
+-- workspaces/ All customer workspace cells
|
+-- au/ (Australia) Cells: (none yet)
+-- br/ (Brazil) Cells: (none yet)
+-- ca/ (Canada) Cells: (none yet)
+-- eu/ (European Union) Cells: provisionr-eu1kc
+-- in/ (India) Cells: (none yet)
+-- jp/ (Japan) Cells: (none yet)
+-- lp/ (Launchpad) Cells: provisionr-lp1ka (internal/dev)
+-- mx/ (Mexico) Cells: (none yet)
+-- us/ (United States) Cells: provisionr-us1kb

Each region folder is a GCP folder resource. GCP IAM policies, organization policy constraints, and audit configurations can be applied at the folder level, meaning all cells within a region inherit the same security posture without per-project configuration.


Each cell is a GCP project with a fixed set of enabled APIs. Inside, downstream Terraform and Fleet Control provision:

ResourcePer-tenant or sharedPurpose
Cloud Run serviceOne per tenantRuns the tenant’s workspace application
Cloud SQL databaseOne per tenantTenant-specific relational data
Cloud SQL instanceShared across tenantsHosts multiple tenant databases
Redis instanceShared across tenantsCaching and session state
VPC / networkingSharedPrivate connectivity between services
Secret Manager secretsPer tenantTenant-specific credentials and configuration
Artifact RegistrySharedContainer images for workspace deployments

The GCP project itself provides the billing, IAM, and API boundary for the cell.


Tenants within a cell are isolated at the application and data layers, not at the GCP project layer.

Each tenant workspace runs as its own Cloud Run service. Cloud Run services are isolated from each other by default — they run in separate containers with independent scaling, networking, and IAM service identities. One tenant’s service cannot invoke or access another tenant’s service unless explicitly configured.

Each tenant gets a dedicated database on a shared Cloud SQL instance. Database-level access controls ensure one tenant cannot query another tenant’s database. Credentials are stored in Secret Manager and scoped to the individual tenant.

Cells share the following resources across tenants:

  • GCP project quotas and limits — all tenants in a cell draw from the same Cloud Run, Cloud SQL, and API quotas
  • Cloud SQL instance compute — database instances are shared; a poorly-performing tenant query can affect instance-level resources (mitigated by Cloud SQL resource controls and monitoring)
  • Networking — tenants share the same VPC within a cell
  • GCP project-level IAM — service accounts with project-level roles can see all resources in the project

For workloads requiring stronger isolation (dedicated compute, dedicated database instances, or a dedicated GCP project), this architecture supports promoting a tenant to a single-tenant cell — a cell with only one tenant assigned.


Regional isolation is enforced at three levels:

Each region is a separate GCP folder. Cells in one region are in a different folder than cells in another region. Folder-level IAM policies, organization policy constraints (such as restricting allowed locations), and VPC Service Controls can be applied per-region without affecting other regions.

Each workspace region maps to specific GCP compute regions:

Workspace regionPrimary GCP regionSecondary GCP region
Australia (au)australia-southeast1australia-southeast2
Brazil (br)southamerica-east1southamerica-west1
Canada (ca)northamerica-northeast1northamerica-northeast2
European Union (eu)europe-west1europe-southwest1
India (in)asia-south1asia-south2
Japan (jp)asia-northeast1asia-northeast2
Mexico (mx)northamerica-south1southamerica-west1
United States (us)us-central1us-west1

Resources within a cell are deployed to the primary and secondary GCP regions associated with the cell’s workspace region. Data does not leave the region pair. The secondary region provides redundancy for disaster recovery and high availability.

Tenant data is placed in a specific region at workspace creation time and stays there. Fleet Control only assigns tenants to cells within their chosen region. There is no mechanism for data to flow between regions at the infrastructure level — cross-region access would require explicit application-level integration that does not exist today.

This architecture supports data residency requirements by ensuring:

  • A customer choosing the eu region has their Cloud Run service, Cloud SQL database, and all associated data within europe-west1 / europe-southwest1
  • A customer choosing the ca region has their data within northamerica-northeast1 / northamerica-northeast2
  • GCP organization policies can enforce location restrictions at the folder level, preventing resources from being created in disallowed regions even if Terraform or application code attempts it

The hard capacity boundary for a cell is the Cloud Run limit of 1,000 services per GCP project. Since each tenant gets one Cloud Run service, a single cell can host up to 1,000 tenants.

Cloud SQL has a limit of 500 databases per instance (when properly sized). Multiple Cloud SQL instances within a cell are used to distribute tenant databases. The exact number of instances per cell and the allocation strategy (round-robin) are determined by downstream infrastructure, not this repository.

ResourceLimitBinding constraint
Cloud Run services1,000 per projectHard ceiling per cell
Cloud SQL databases500 per instanceSoft ceiling, scaled by adding instances
Cloud SQL instancesConfigurable per cellManaged by downstream Terraform

When existing cells in a region approach the 1,000-service limit, a new cell is added:

  1. A platform engineer generates a new cell ID (region code + ULID timestamp segment) and adds it to the Terraform configuration
  2. Terraform creates the new GCP project in the appropriate region folder with all required APIs, labels, and billing
  3. Downstream Terraform provisions Cloud Run, Cloud SQL, networking, and other infrastructure inside the new cell
  4. Fleet Control begins assigning new tenant workspaces to the new cell
  5. Existing tenants on older cells are not affected and are not moved
Region: US
Cell capacity
provisionr-us1kb [|||||||||||||||||||| ] ~800/1000 tenants
provisionr-us1kn [|||| ] ~200/1000 tenants (new)
Fleet Control routes new US tenants --> provisionr-us1kn

At current provisioning rates, a region with one cell will need a second cell when it reaches approximately 1,000 active tenants. With 9 workspace regions available, the architecture supports:

  • Near-term: 1 cell per active region, ~1,000 tenants per region
  • Medium-term: 2-5 cells per high-demand region, handling thousands of tenants per region
  • Long-term: The cell ID scheme supports over 1 million unique cell IDs (32^4 ULID timestamp values x 9 regions), and each cell supports up to 1,000 tenants

Regions without active demand (e.g., br, jp) have no cells provisioned — the folder exists but remains empty until a customer requests capacity in that region.


Cells are assigned to one of two billing accounts based on purpose:

Cell typeBilling accountAccount ID
Production (all regions except lp)COGS018476-F8A9B4-58324B
Launchpad / internal dev (lp only)OPEX014691-0BBBCC-3E9B65

This separation ensures customer-serving infrastructure costs are tracked as cost of goods sold, while internal development and testing costs are tracked as operating expenses.

Every cell has labels for cost allocation and reporting:

LabelPurposeExample
prv-envEnvironment classificationprd or dev
prv-teamOwning teamplt
prv-costCost center (region-level)prv-plt-cat-gcp-prd-us
prv-cost-dimCost dimension (cell-level)prv-fin-cat-plt-gcp-prd-us1kb-prj

The prv-cost-dim label uniquely identifies each cell for per-cell cost analysis. Combined with GCP billing exports, this enables tracking infrastructure cost per cell and, by extension, per-tenant cost attribution.


All cell provisioning is managed through Terraform with the following controls:

  • Version-controlled configuration — all changes go through GitLab merge requests with full audit trail
  • Static analysis — Checkov SAST scanning on every merge request
  • Plan reviewterraform plan output is available for review before any apply
  • Stale plan rejection — plans older than 4 hours are automatically rejected to prevent applying outdated changes
  • Restricted apply — only platform administrators (prv-plt-admin-*@prv.systems) can trigger terraform apply

Cells and region folders are protected against accidental deletion:

ResourceProtection mechanism
Cell projectsdeletion_policy = "PREVENT" — Terraform refuses to delete
Region foldersdeletion_protection = true — GCP refuses to delete

Decommissioning a cell requires explicitly changing the deletion policy, migrating all tenants to other cells, and obtaining approval from the platform team lead.

Every cell project is created with:

  • No default VPC (auto_create_network = false) — networking is explicitly provisioned
  • Deprivileged default service account (default_service_account = "deprivilege") — the GCP default service account has reduced permissions, preventing over-privileged defaults
  • Deterministic project IDs (random_project_id = false) — project names are predictable (provisionr-{cell_id}), simplifying audit and monitoring rules

Each cell has a fixed set of APIs enabled. Only the APIs required for workspace workloads are activated — no additional APIs can be enabled without a Terraform change through the merge request process:

  • artifactregistry.googleapis.com
  • cloudbilling.googleapis.com
  • cloudkms.googleapis.com
  • cloudresourcemanager.googleapis.com
  • compute.googleapis.com
  • iam.googleapis.com
  • logging.googleapis.com
  • monitoring.googleapis.com
  • orgpolicy.googleapis.com
  • redis.googleapis.com
  • run.googleapis.com
  • secretmanager.googleapis.com
  • servicenetworking.googleapis.com
  • serviceusage.googleapis.com
  • sqladmin.googleapis.com
  • storage-api.googleapis.com
  • vpcaccess.googleapis.com

Cells are identified by a 5-character cell ID that encodes both the deployment region and provisioning era:

us1kb
^^~~~
|| |
|| +-- ULID timestamp segment (Crockford Base32, ~9.3 hour resolution)
++------Region code
Cell IDRegionMeaning
eu1kcEuropean UnionEU cell provisioned in 1kc time window
lp1kaLaunchpadInternal/dev cell provisioned in 1ka time window
us1kbUnited StatesUS cell provisioned in 1kb time window

Cell IDs are immutable after creation. They appear in GCP project names (provisionr-{cell_id}), Terraform state, cost labels, monitoring dashboards, and log entries. Renaming a cell ID would destroy and recreate the GCP project, deleting all tenant workloads inside it.


RegionCellsStatus
Australia (au)Region folder exists, no cells provisioned
Brazil (br)Region folder exists, no cells provisioned
Canada (ca)Region folder exists, no cells provisioned
European Union (eu)provisionr-eu1kcActive, production
India (in)Region folder exists, no cells provisioned
Japan (jp)Region folder exists, no cells provisioned
Launchpad (lp)provisionr-lp1kaActive, internal/dev
Mexico (mx)Region folder exists, no cells provisioned
United States (us)provisionr-us1kbActive, production

The Launchpad region is a non-production environment used for internal testing and development. It is billed to the OPEX account and labeled as dev.