Put the placement decision behind a directory
For a SaaS application that must move customers between deployment cells, keep tenant placement in a directory that maps a stable tenant identifier to an active cell. Check tenant authorization again inside that cell. Routing answers where a request goes; authorization answers whether the caller may perform the requested action on the resource. A correct address does not establish permission.
This recommendation assumes that customers may eventually need a different region, capacity allocation or deployment schedule. A small application with one database and no credible relocation requirement may need only a clean lookup interface around its current configuration. Operating a distributed placement service before there is a second destination adds a failure dependency without creating a useful choice.
The decision record below is a proposed design for a fictional business application. Its distinctive requirement is controlled movement: an outdated router must not send a successful write to the previous location after ownership changes. The downloadable record makes that requirement explicit enough to review before anyone selects a cloud service.
Separate the boundaries that teams often combine
A deployment cell is an independently operated group of application resources serving an assigned set of tenants. A cell can contain a shared database, separate tenant databases or a mixture. Those choices describe different boundaries and need separate decisions.
| Boundary | Question it answers | Evidence needed for the decision |
|---|---|---|
| Tenant authorization | May this caller access this tenant's resource? | A checked resource scope and explicit permission policy |
| Data placement | Which store contains the authoritative records? | A tenant directory and a documented ownership transition |
| Capacity isolation | Which tenants compete for the same resources? | Workload measurements and enforced resource controls |
| Deployment isolation | Which customers receive this release? | Independently deployable units and compatible interfaces |
Microsoft's deployment stamps guidance describes repeated units that serve subsets of tenants, including the difficulty of moving data between them. Its multitenant architecture overview distinguishes shared and dedicated stamps. Neither arrangement removes the need to define the application's own access rules.
A dedicated database can simplify one customer's restore while leaving application workers shared. A dedicated application cell can separate release schedules while still calling a shared identity service. Write those shared dependencies onto the architecture diagram. Otherwise the phrase "isolated tenant" will mean a different thing to the security reviewer, the database team and the person handling an outage.
Record the smallest useful placement contract
Our proposed directory entry has a stable tenant ID, an active cell, a placement epoch and a lifecycle state. The epoch is a monotonically increasing ownership version for this tenant. It changes when write ownership changes; it is not a cache timestamp and should not be reset when a cell is recreated.
{"tenant_id":"tenant-42","active_cell":"cell-west-b","epoch":18,"state":"active"}The authenticated request establishes the tenant context through a trusted membership or service identity. A hostname can help locate a customer but should not become the sole authority for that context. The router looks up the placement entry, attaches the expected epoch through a protected internal interface and forwards the request. The cell compares that epoch with its own authoritative write-ownership state before accepting a mutation.
For this contract to work, the final mutation must participate in the ownership check. Checking an epoch in application memory and then writing later leaves a race between those operations. One implementation can keep the ownership row and the affected records in a transactionally checked store. Another may require a storage service that enforces a fencing value. The ADR does not prescribe either implementation without knowing the data model.
Avoid putting customer business records in the directory. The router needs enough information to choose a destination and reject an invalid placement state. Expanding that lookup into a second copy of customer configuration makes ordinary account edits part of the routing system's availability problem.
Move a tenant without creating two writers
Consider a move from cell-east-a at epoch 17 to cell-west-b at epoch 18. The numbers are illustrative identifiers, not measurements. Copying records and changing a routing entry is insufficient: a router may still hold epoch 17, a request may already be in flight and an old background worker may wake after the switch.
The proposed procedure gives the source an explicit write-stop point. Stop new source mutations, wait for accepted transactions to finish and capture the final data position. Transfer changes through that position and verify the destination. Only then grant the destination epoch 18 and activate its directory entry. Requests that reach the source with epoch 17 after the write-stop point must fail with a retriable relocation response or be safely redirected through a fresh lookup. They must not silently succeed.
This design deliberately includes a write pause. A product that cannot tolerate that pause needs a different migration design with a proven conflict or ownership protocol. Calling a copy process "online" does not resolve concurrent writes by itself. The pause duration must be measured using the tenant's actual data volume and final-change transfer procedure before it becomes a customer commitment.
| Observation during cutover | Required behavior in this proposed contract |
|---|---|
| An old router selects the source | Source rejects mutations after its write-stop point |
| A source worker resumes late | Its write is rejected by the same ownership guard |
| Destination verification fails before activation | Source may resume only through an explicit abort transition |
| Destination has accepted a new mutation | Returning to the source requires data reconciliation and a new epoch |
| Directory lookup is unavailable | A cached route is usable only under a documented freshness policy and cell-side ownership enforcement |
The fourth row is the rollback boundary. Before destination writes, an abort may restore the original service state. After destination writes, flipping the directory back can discard or hide new data. A return is another move, with reconciliation and a fresh ownership version.
Decide what can continue when the control plane fails
Placement belongs to the control plane: the machinery that provisions tenants and changes their assigned resources. Application requests belong to the data plane. Keeping those responsibilities distinct helps identify which operations can continue when the directory or provisioning workflow is unavailable.
For an already active tenant, a cached placement may preserve request routing if the destination still enforces current ownership. For a new tenant with no confirmed placement, guessing a default cell can create data in the wrong location. For a tenant in the middle of relocation, a cached "active" state may be stale. These cases should have separate operational behavior and separate alerts.
Do not describe the cache as an availability guarantee. A reachable cell may have lost access to its own ownership state. A shared identity provider may be unavailable. A region-level failure may affect both the directory replica and the tenant's data. Document the dependencies that remain on the critical path and define how long a cached route may be used under each state.
Capacity pressure is a different decision. Moving tenants may eventually relieve it, but a cutover procedure is rarely a fast admission-control mechanism. Use the noisy-neighbor analysis to decide how competing workloads are limited while a placement change is being prepared.
Review the ADR against the next real relocation
Download the tenant placement decision record and cutover review checklist. Both are proposed artifacts for adaptation. They contain no production benchmark, vendor configuration or claim about Dreamtsoft product capabilities.
Ask the team to name the storage operation that rejects an obsolete epoch, the person authorized to resume the source after an abort and the evidence that proves the destination reached the final source position. If those answers are missing, the move protocol is incomplete even if every arrow on the diagram has a service name.
Revisit the decision when the business requires uninterrupted writes during relocation, when customers need active writes in multiple regions or when a shared dependency prevents cells from failing independently. Those changes alter the ownership problem. Adding more directory replicas alone will not satisfy them.
Sources
Documentation checked .
