The question this answers
A class of my data may not leave its jurisdiction. What does that forbid, and what does it force?
What can be guaranteed technically is narrow and worth stating precisely: that every replica, backup, index, cache and log entry containing a residency-bound record resides on infrastructure located within the permitted jurisdiction, and that no request path causes such a record to be transmitted outside it. Whether that satisfies a given legal obligation is not an engineering determination.
Everything below is bought to hold this sentence. "Strongly consistent" with no scope attached is a slogan, not a guarantee — read what it actually covers, and what it explicitly does not.
A node knows which jurisdiction it is in and, if the design provides it, which jurisdiction a given record belongs to. It does not inherently know whether a field it is about to log, cache, index or emit in a trace is residency-bound — that classification has to be carried with the data, because a node cannot infer it from the bytes. Nearly every residency incident is a component acting on data whose classification it never received.
A node knows its own state and the messages that arrived. Everything else is inference from evidence that was already stale. "B has not replied in five seconds" is knowledge; "B is down" is a decision — and usually the bug.
The constraint is not "store it in region X"
The naive reading is that residency means putting a database in the right country. If that were all, it would be a deployment ticket. What makes it an architectural constraint is that every copy counts, and a running system makes far more copies than its architecture diagram shows.
The replica is obvious. The backup is usually remembered. After that the list gets uncomfortable: the read replica someone added for a dashboard, the search index, the analytics warehouse, the CDN cache, the message broker retaining a topic for seven days, the distributed trace carrying a request body, the application log line that included the payload for debugging, the error tracker with a serialised object attached, the machine-learning feature store, the exported CSV in an object bucket, and the third-party service the request was forwarded to.
So the useful formulation is not "where does the data live" but "enumerate every place a copy of this record can come to rest, and prove each one is inside the boundary." That enumeration is the actual work, it cuts across every team, and it is the reason residency cannot be retrofitted cheaply.
- Primary store and every replica — the part everyone gets right.
- Backups, snapshots and the retention of both, including the cross-region copy someone made for disaster recovery.
- Secondary indexes and search clusters — an index is a copy of the indexed fields.
- Caches at every tier, including CDN edge nodes, which are by design outside every boundary.
- Message brokers and event streams, which retain payloads for their retention window.
- Logs, traces and error reports — the most common leak, because they are added by an engineer debugging at 2 a.m. and never reviewed.
- Analytics pipelines and warehouses, which typically ship everything everywhere by default.
- Any third-party API the data is sent to, whose own topology you do not control.
It can forbid the topology you would have chosen
This is the part that surprises architects, and it is why this lesson sits in a distributed systems module rather than in a compliance appendix.
It forbids a global quorum. A five-node consensus group spread across Frankfurt, Dublin, Virginia and Singapore is a design that puts a copy of every committed record in all four places — that is what replication *is*. For residency-bound data, that group cannot exist. What you can have is a per-jurisdiction consensus group: five nodes inside the EU, across EU availability zones and EU regions. Which means the availability of that data is bounded by the availability of that jurisdiction’s infrastructure, and a design that assumed global quorum resilience quietly loses a failure domain.
It forbids a hash-partitioned global keyspace. Consistent hashing spreads keys across the ring by hash, which is precisely a scheme for placing data without regard to geography. For residency-bound data the partitioning key must be, or must be prefixed by, the jurisdiction — which means you get [[range-partitioning]] semantics whether you wanted them or not, with their [[hot-partitions]] behaviour, their rebalancing characteristics, and a partition count set by the map rather than by your load.
It forbids a global secondary index. An index over a field is a copy of that field placed wherever the index lives. A global uniqueness index over email addresses across jurisdictions is exactly the thing residency prohibits — and it is also, awkwardly, exactly the thing [[distributed-uniqueness]] needs. Reconciling those two is real design work, usually resolved by indexing a salted hash rather than the value, and accepting that even that may be in scope.
It forbids follow-the-sun operations for some data. An engineer on call in Singapore may not be permitted to query an EU production database, which turns [[distributed-debugging]] into a genuine problem: the person awake cannot see the data. The answer is that correlation ids, structured metadata and aggregate metrics must be sufficient to diagnose most incidents without payloads — a discipline worth having anyway.
The pattern that usually works: split the record
Faced with a system that needs both global operations and jurisdiction-pinned data, the design that most often survives contact with reality is to split each record in two.
A globally replicable stub holds what the rest of the system genuinely needs everywhere: an opaque identifier, the owning jurisdiction, a status, timestamps, and nothing else. A jurisdiction-pinned payload holds everything that is residency-bound and never leaves. Global operations — routing, listing, aggregate counting, authorization checks — run against stubs. Anything needing the payload executes inside the owning jurisdiction and returns a result rather than the data.
This composes cleanly with [[multi-region-write-models]]’s partitioned ownership: the stub *is* the ownership directory, so a design that already homes data per tenant is most of the way there. It also makes the residency boundary auditable, because there is one table whose contents you must defend rather than a diffuse property of the whole schema.
Two honest complications. First, the stub is not automatically out of scope: an identifier that can be correlated back to a person may itself be regulated, and "we only replicated the user id" is not a defence anyone should rely on without asking. Second, the two-part read is a real cost — a global list view now shows stub data and must fetch payloads per jurisdiction, which is a scatter-gather with [[fan-out-tail-latency]] behaviour, and is usually the moment somebody proposes "just cache the payloads centrally".
- EU cell (Frankfurt + Dublin) — payloads for EU subjects; quorum entirely inside the EU
- US cell (Virginia + Oregon) — payloads for US subjects; quorum entirely inside the US
- Global stub directory — id → jurisdiction, status, timestamps. No regulated payload.
- Edge API (anywhere) — resolves via stub, then calls into the owning cell
- dirbelieves “I hold no regulated data”✕ and it is false
- apibelieves “reading a stub is always safe from any region”✕ and it is false
Every node above is acting on what it believes. Nothing in the cluster tells the mistaken one that it is mistaken.
Residency, sovereignty and localisation are three different requirements
The words are used interchangeably in conversation and they impose different designs, so it is worth separating them before a design review rather than during one.
Residency is about where data is stored. It permits processing elsewhere in some regimes and not in others, and it is satisfiable with careful placement. Sovereignty adds a claim about which government can compel access, which is a statement about the *operator* as much as the location — the same rack under a different corporate parent may satisfy one and not the other, and no amount of topology fixes it. Localisation is the strictest: the data must be stored and processed in-country, sometimes on infrastructure operated by a domestic entity, which can rule out your cloud provider entirely and force a genuinely separate deployment.
The design consequence: residency can usually be met by a cell per jurisdiction inside one provider. Sovereignty may require a different provider or a sovereign-cloud offering for one cell. Localisation frequently requires a fully independent stack, at which point the honest architecture is separate instances of the product that share code and share nothing else — no cross-instance replication, no global control plane holding regulated data, and a release process that can deploy to an environment your team cannot log into.
That last shape is unglamorous and is what most mature multi-jurisdiction products converge on. It is worth reaching it deliberately rather than by a series of exceptions.
| Requirement | What it constrains | Typical architecture | What it forbids |
|---|---|---|---|
| Residencysimplified | Where bytes at rest are located | One storage cell per jurisdiction, global stub directory | Cross-jurisdiction replicas, backups and indexes |
| Sovereigntysimplified | Who can be compelled to hand data over | Cell operated by a legally separate entity, keys held locally | Provider-managed keys and any global operator access path |
| Localisationsimplified | Where storage *and processing* happen, and by whom | A fully independent deployment of the product in-country | Shared control planes, shared observability, cross-instance replication of any kind |
What it costs, stated plainly
Residency multiplies operational surface by the number of jurisdictions. Every cell needs its own deployment, its own capacity planning, its own on-call visibility, its own backup verification and its own upgrade path — and they will drift, in the same way an unexercised standby drifts. A four-jurisdiction system is four systems that happen to share a repository.
It also removes a failure domain you may have been relying on. Data pinned to the EU cannot be failed over to Virginia, so its disaster recovery story must be satisfied entirely with EU infrastructure. That is achievable — multiple EU regions exist — but it must be designed for, and it is a common gap in systems where residency was added after the DR plan.
And it changes the cost profile. Small jurisdictions get cells that are far below efficient scale, so per-customer infrastructure cost varies by an order of magnitude across the fleet. That is a business fact, not a technical one, and it is worth surfacing early because it determines whether serving a given market is viable at all.
Key points
- Residency constrains every copy, not just the primary — indexes, caches, brokers, backups, logs, traces and analytics all count.
- It can forbid a global quorum, a hash-partitioned global keyspace, and a global secondary index. Those are architectural prohibitions, not configuration options.
- The partitioning key becomes jurisdiction-prefixed whether or not that suits your load distribution.
- Availability of pinned data is bounded by the jurisdiction’s infrastructure; you lose the option of failing over elsewhere.
- The workable pattern is a globally replicated stub plus a jurisdiction-pinned payload, with global operations running against stubs only.
- The stub is not automatically out of scope — a correlatable identifier may itself be regulated.
- Residency, sovereignty and localisation are three different requirements demanding three different architectures.
- Logs and traces are the most common leak, because they are added during debugging and never reviewed.
The chain, answered
Every field here is required, which is why no lesson in this domain can recommend a design without naming what an operator sees when it fails, what survives the partition, what repairs it afterwards, and the simpler thing to consider first.
- • Classify the data: which fields, for which subjects, are bound to which jurisdiction. This is a legal input to an engineering design, not an engineering decision.
- • Attach the classification to the record so that every downstream component can act on it without inferring it.
- • Choose a partitioning scheme whose key is prefixed by jurisdiction, so placement is a function of the key rather than of a hash.
- • Place a complete storage cell — primary, replicas, quorum, backups, indexes — inside each permitted jurisdiction.
- • Split each record into a globally replicable stub and a pinned payload; route global operations through stubs.
- • Constrain the observability pipeline: correlation ids and metadata cross freely, payloads do not, enforced by redaction at the emitter rather than at the collector.
- • Verify placement continuously — enumerate the actual storage locations of every copy, rather than trusting the intended configuration.
- • A new feature adds a cache, an index or an export that nobody assessed against the classification.
- • A debug log line includes a payload and ships to a central log cluster in another jurisdiction.
- • A backup policy replicates snapshots cross-region for durability, which is good practice and a violation.
- • A distributed trace carries request bodies to a collector outside the boundary.
- • A third-party dependency changes its own processing location, moving your data without any change on your side.
- • A user or tenant relocates and their existing data must be migrated between cells, which is an ownership handoff plus a deletion.
- • Leak via observability: an EU customer’s personal data appears in a US log index. The operator discovers it during an audit or a search, months later, and the remediation includes deleting from backups of the log store — which is usually the hardest part.
- • Silent cross-region backup: snapshot policy has replicated EU database backups to a US bucket since the system was built. Nothing fails, nothing alerts, and the finding arrives from a compliance review rather than from engineering.
- • Availability gap: the EU cell’s only DR target was in a US region, so when residency was enforced the DR plan was quietly removed. The operator sees no signal at all until the incident that needed it.
- • Cross-jurisdiction feature failure: a global search returns results only for the caller’s own cell, and users report "search is broken" while every service reports healthy. The behaviour is correct and the product expectation was not updated.
- • Migration stall: a tenant relocating between cells has data in both for days because the deletion side of the migration failed silently, so the record now resides in two jurisdictions rather than one.
- • Small-cell fragility: a jurisdiction with a handful of customers runs on the minimum viable footprint, so its p99 latency and its failure behaviour are materially worse than the fleet’s, and fleet-wide dashboards hide it entirely.
- • Cross-jurisdiction coordination is what the constraint is designed to prevent, so any operation needing global agreement over pinned data is either impossible or must be restructured to agree over stubs.
- • Uniqueness across jurisdictions is the sharpest instance: a global unique index is a global copy. The workable versions are a salted hash index, per-jurisdiction namespacing that makes global uniqueness unnecessary, or accepting collisions and resolving them — and each is a product decision.
- • Within a jurisdiction, ordinary consensus and quorum reasoning applies unchanged; you simply have several independent clusters instead of one.
- • Tenant migration between cells requires a coordinated handoff — copy, verify, switch ownership, delete — with the deletion being the step that must not be best-effort.
- • A jurisdiction’s cell failing takes that jurisdiction’s data with it; there is no cross-jurisdiction failover, by design.
- • Global operations degrade to the cells that are reachable, which means a partial result — and the product must express partial results honestly rather than silently omitting a jurisdiction.
- • The stub directory failing takes down routing everywhere, which makes it the highest-criticality component in the design despite holding the least data.
- • Compliance properties hold through failures: a failover that would move data outside the boundary must fail rather than succeed, which is the one place where
fail-open-vs-fail-closedhas an unambiguous answer.
- • Detect: continuously enumerate where copies actually are — object bucket regions, snapshot locations, index cluster placement, log destinations — and diff against the permitted set. Configuration intent is not evidence.
- • Contain: on a suspected leak, stop the flow first (disable the exporter, the log field, the trace attribute) before attempting deletion, since the source keeps producing.
- • Recover: delete the out-of-boundary copies, including from backups of the systems that held them — the step that determines how long the remediation actually takes.
- • Reconcile: re-verify each cell’s completeness after any migration, particularly that the source-side deletion completed.
- • Verify: sample records and prove their location, and keep the evidence.
audit-logsis the mechanism for showing what was accessed from where.
- • A continuous inventory of storage locations per data class, generated from the infrastructure rather than from documentation.
- • Redaction coverage in the observability pipeline: the proportion of log and trace fields that have an explicit classification, and alerts on unclassified fields appearing.
- • Cross-jurisdiction request counts per endpoint — any nonzero rate on a path that should be jurisdiction-local is a finding.
- • Per-cell health, capacity and backup verification separately from fleet aggregates, since small cells vanish in the average.
- • Tenant migration completion, specifically the source-side deletion step, tracked to zero rather than to "initiated".
- • When the requirement exists, which is not optional — designing for it up front is dramatically cheaper than retrofitting, because retrofitting means finding every copy in a running system.
- • As a forcing function for good hygiene: knowing which fields are sensitive and preventing them from reaching logs is valuable independently of any regulation.
- • When it aligns with partitioned ownership you wanted anyway, in which case the residency boundary and the ownership boundary are the same line and cost little extra.
- • When applied to data that is not actually in scope, multiplying cells and cost for no benefit. Over-classification is expensive and common.
- • When the product genuinely needs global operations — cross-tenant search, global analytics, a worldwide leaderboard — because those become partial, asynchronous, or impossible.
- • When the number of jurisdictions grows faster than the team, so each cell gets a decreasing share of operational attention and drifts.
- • When it is treated as a storage problem and the observability, analytics and third-party paths are left unassessed — in which case the design provides confidence without protection, which is worse than knowing you are exposed.
- • Do not hold the data at all: tokenise or reference it, so the regulated value stays with a system already inside the boundary. The cheapest solution to a residency problem is frequently a deletion.
- • Keep the payload in-jurisdiction and move the computation to it —
[[data-locality]]— so results cross the boundary and data does not. - • Encrypt with keys held in-jurisdiction so that copies elsewhere are unreadable. This helps for some obligations and not others, and the determination is legal rather than architectural.
- • Aggregate before export: statistics and counts often satisfy the analytics requirement without any record leaving.
- • Run genuinely separate product instances per jurisdiction, sharing code and nothing else — the honest endpoint when localisation rather than residency is the requirement.
Every copy counts: indexes, caches, brokers, backups and logs
- EU cell (Frankfurt + Dublin) — payloads for EU subjects; quorum entirely inside the EU
- US cell (Virginia + Oregon) — payloads for US subjects; quorum entirely inside the US
- Global stub directory — id → jurisdiction, status, timestamps. No regulated payload.
- Edge API (anywhere) — resolves via stub, then calls into the owning cell
- dirbelieves “I hold no regulated data”✕ and it is false
- apibelieves “reading a stub is always safe from any region”✕ and it is false
Every node above is acting on what it believes. Nothing in the cluster tells the mistaken one that it is mistaken.
| What it constrains | Typical architecture | What it forbids | |
|---|---|---|---|
| Residencysimplified | Where bytes at rest are located | One storage cell per jurisdiction, global stub directory | Cross-jurisdiction replicas, backups and indexes |
| Sovereigntysimplified | Who can be compelled to hand data over | Cell operated by a legally separate entity, keys held locally | Provider-managed keys and any global operator access path |
| Localisationsimplified | Where storage and processing happen, and by whom | A fully independent deployment of the product in-country | Shared control planes, shared observability, cross-instance replication of any kind |
What people believe, and what is true
Residency means putting the database in the right region.
It means every copy is in the right region — replicas, backups, indexes, caches, brokers, logs, traces and analytics. The database is the easy one and rarely the one that fails an audit.
Encryption solves residency.
It may satisfy some obligations and not others, and whether ciphertext held abroad counts as data held abroad depends on the regime and on who holds the keys. It is a legal determination that engineers should not make on their own.
We can still fail over to another region in an emergency.
If the data may not leave, the emergency does not create an exception. The DR plan must be satisfiable inside the boundary, which usually means multiple regions within the jurisdiction, planned in advance.
It only affects the storage team.
It affects anyone who emits a log line, adds a trace attribute, builds an index, exports to a warehouse or calls a third party — which is everyone.
We are compliant because the configuration says so.
Compliance here is a property of where bytes actually are. The evidence has to be an inventory generated from the running infrastructure, because the gap between intended and actual placement is exactly where the findings come from.
Go deeper
Only the levels this lesson can honestly fill — a missing level is a claim nobody had.
Overview
Some data may not leave its jurisdiction. That constrains every copy — replicas, backups, indexes, caches, logs — and forbids global quorums, global hash partitioning and global indexes. Plan one storage cell per jurisdiction.
Practical
Split each record into a globally replicable stub and a jurisdiction-pinned payload; run global operations against stubs. Prefix the partitioning key with the jurisdiction. Redact at the emitter, not the collector, so payloads never enter the observability pipeline. Then build the inventory that proves where copies actually are, because intended configuration is not evidence, and make sure each jurisdiction has a DR story that does not leave it.
Advanced
Residency is best understood as an externally imposed placement constraint on the partitioning function — one that the workload did not choose and cannot renegotiate. That reframing makes its consequences predictable rather than surprising: because placement is fixed, load balancing across the constraint is unavailable, so hot jurisdictions cannot be spread; because replicas must stay inside, quorum size and failure independence are bounded by the jurisdiction’s available regions; and because indexes are copies, any global index over pinned fields is prohibited, which removes global uniqueness as a primitive. Systems that survive this well are the ones that already practised partitioned ownership, since the residency boundary can be made to coincide with an ownership boundary they already maintained. Systems that hash-partitioned a global keyspace generally cannot be adapted and are rebuilt as cells.
Apply it
- 🔧 Build the copy inventory for one data class: every replica, backup, index, cache, broker topic, log destination and analytics sink. Mark which are outside the boundary.
- 🔧 Design the stub schema for your main entity — the minimum a global router needs — and argue for each field that it is safe to replicate.
- ⚡ A team adds distributed tracing with request-body capture to debug a payment issue. Trace the residency consequence and the remediation, including backups.
- ⚡ A new market requires in-country processing by a domestic operator. Explain why the existing multi-region design cannot be extended and what replaces it.
- 💬 EU customer data may not leave the EU. List everywhere a copy of it currently exists in a system you know.
- 💬 Why does residency forbid a global secondary index, and what do you do about global uniqueness?
- 💬 What is the disaster recovery plan for data that cannot leave its jurisdiction?
- 💬 A tenant moves from the EU cell to the US cell. Describe the migration, including the step most likely to fail silently.