The request arrives as a sentence: our data has to stay in this region. It sounds like a deployment decision, and the first response is usually to stand up a database in the named region and consider the matter handled.
Then somebody traces a single request and finds the copies. Application logs shipped to a central aggregator. An error tracker holding a payload. A queue with a retained message. A search index. An analytics warehouse. A support tool that renders customer records for your own staff. Each of those is a copy of the data in a place the promise did not cover.
Decide what the promise covers
Not everything can stay in region, and pretending otherwise produces a commitment you will breach. The workable division is between content and metadata: the customer's records, files and documents live in their region, while a minimal amount of routing information — which region a tenant belongs to, which addresses map to which tenant — has to be globally reachable or nobody can be routed anywhere.
Write that distinction down in the terms, in the documentation and on the page a reviewer will read. A precise, narrow promise you keep is worth far more than a broad one that unravels the first time somebody asks about your error tracker.
- Content in region; a small, documented routing layer that is not
- Enumerate every sink: logs, traces, errors, queues, indexes, warehouses, support tooling
- Backups and their replicas inherit the residency requirement
- Third-party processors need a region story too, or they become the leak
A narrow promise you keep is worth more than a broad one that fails at your error tracker.
Region is a property of the tenant, chosen once
The design that stays comprehensible attaches a region to the organisation at creation time and never moves it. Every request resolves the tenant, discovers the region, and is routed there — ideally at the edge, so the data never transits a stack in the wrong place on its way to the right one.
Migrating a tenant between regions afterwards is possible and it is a project: an export, an import, a cutover, an authoritative deletion at the origin. Build the mechanism eventually if you must, but do not design as though moving is routine, because the code that assumes a tenant can be anywhere is the code that reads from the wrong place.
The features that cross the line
Some functionality is inherently global and needs an explicit answer. A sign-in flow that must resolve which region a person belongs to before it knows who they are. Search across organisations. Billing, which usually consolidates. Outbound email, which passes through a provider with its own geography. Your own support access, which is a person in one country reading data in another.
Handle each deliberately rather than discovering it during a review. Some can be made regional at a cost, some can be reduced to metadata, and some have to be disclosed as an exception. The last option is legitimate — an exception a customer agreed to in advance is a term of the contract, while the same exception found later is a finding.
- Resolve region at the edge, before the request touches a regional stack
- Regional sign-in needs a global lookup that holds no content
- Staff access across regions is a transfer; log it and disclose it
- Test the promise: pick a field and hunt every place it lands
Everything here, already built
Sign-in, enterprise SSO, directory provisioning, roles and an audit trail behind one API. Start with the quickstart and have a working sign-in this afternoon.