Data Architecture in Practice: Isolation, Governance, and Lifecycle
Thesis: data architecture is not about choosing a database. It is about deciding, for each piece of data, who the owner is, where it lives, who can see it, and when it ceases to exist. Anything without an owner, boundary, and expiration date becomes a liability.

- The memo applied to data
I use the same three questions for every structural decision, and they work especially well with data:
- Who pays for this? What business requirement, legal restriction, or risk mitigation justifies the decision?
- What does it cost me? What complexity, operational cost, or rigidity am I buying?
- What would make me undo it? What evidence would prove that the chosen model has stopped serving?
In this article I apply these questions to a problem that every multi‑client solution faces sooner or later: where each client’s data lives and how it is separated from the others. The case comes from three of my products, from the same ecosystem, which arrived at three different answers. None is wrong. What matters is why they are different.
About the case status: I describe recorded decisions and target architectures. When something is not yet implemented or validated, I say so. I do not publish measured results that I don’t have.
- Why it’s a data decision, not an infrastructure decision
Treating “one instance per client or multi‑tenant?” as an infrastructure choice underestimates it. The decision defines:
- the impact radius of any failure or exposure;
- how backup, restoration, and deletion of a specific client are performed;
- how LGPD is met in access and deletion requests;
- how the AI layer (vector indexes, context, cache) respects the boundaries;
- the operational cost of each new client;
- the version‑upgrade strategy.
None of these items is an implementation detail. All are properties of the data.
The spectrum
It is not a binary choice. They are dimensions of sharing (application, database, schema, and resources) that can be combined and that condition each other:
| Model | How the data is separated | Strength | Cost |
|---|---|---|---|
| Shared with logical isolation | Same structures, scope by client identifier, imposed in layers | Low marginal cost, single operation | Isolation failure has a wide radius |
| Database or schema per client | Separate structures on the same platform | More explicit separation, per‑client restoration | Multiplying migrations |
| Stack per client | Dedicated application, database, and dependencies | Reduced impact radius for failures limited to the stack | Operations and cost grow with the number of clients, and the shared host remains a common cause |
| Client‑owned installation | The product runs in the user’s environment | Direct client control over infrastructure and persistence | Less visibility and harder support |
The right question is not “which is best.” It is: what client profile, risk, and business does my product have?
- Three products, three answers
Each case follows the same format: promise, reason, cost, and reversal trigger.
Product A: an isolated stack per client
The product. An automation‑for‑service and CRM solution built on an open‑source CRM base, with a fork of the frontend as the only active development point.
The promise. Each client has a logically and operationally segregated stack, with its own application and database, although they share the physical VPS infrastructure. The decision was an isolated stack per client, on a single VPS, with a reverse proxy handling routing. This reduces exposure between clients but does not eliminate the risks of the shared host: a host failure can affect all, and a misconfiguration of volumes or permissions can breach the boundaries.
Why this. Service conversations are personal and sensitive by nature. Segregating by stack simplifies the privacy conversation, gives the client a clear commercial argument, allows independent configurations and versions without affecting others, and makes per‑client restoration more straightforward. Removing the stack simplifies de‑provisioning of active resources, but complete elimination depends on retention policies, derivative purging, and handling of backups, logs, and external services.
The cost. Operations grow with the number of clients. Updating becomes repeating the process per stack, and automation ceases to be optional. Each stack carries a base cost, and observability becomes fragmented, requiring deliberate aggregation. The shared host is a common cause of failure and of CPU, memory, and I/O contention among stacks.
What would make me undo it. The client count making deployment automation insufficient; the base cost per stack no longer fitting the price; or the need for a unified operational view outweighing the value of physical isolation.
Product B: multi‑tenant with layered isolation
The product. A management platform for HR consultancies, with client companies and candidates inside each consultancy. It serves freelance recruiters and small‑to‑medium businesses.
The promise. Data of one consultancy never appears to another. The decision was a shared multi‑tenant model, with isolation imposed in two layers: the application and the database itself.
Why this. The business profile flips the logic of Product A. There are many low‑value individual clients, and a stack per client would make the cost of serving each incompatible with the price. Measuring usage and charging uniformly assumes a single platform, and creating a new client with minimal friction matches logical provisioning.
The cost. In a shared model, isolation is no longer a design consequence but a property that must be proved continuously. The second layer exists because the first will fail someday. A point of honesty about the state: today production isolation relies on the application layer. Database‑level enforcement is the target architecture and only becomes a fulfilled promise when negative‑access tests demonstrate it.
The mechanism. Database enforcement relies on row‑level security policies on shared tables; on client identity derived from a trusted authenticated context; on connection roles without privilege to bypass them; on safe propagation of this context through asynchronous tasks, queues, and reused connections; and on negative tests with production‑representative credentials. An important caveat: the second layer is independent only if the client identity is not a manipulable value shared by both layers. If application and database trust the same tamperable identifier, they share a failure cause.
Data isolation is also not resource isolation. A client can consume processing, connections, or queues to the point of degrading others, which requires limits, quotas, and per‑client observability.
What would make me undo it. A client whose contract or regulation demands physical separation; the cost of maintaining isolation tests exceeding the cost of separating; or an isolation failure that reveals the layers share the same failure cause.
Product C: single instance and client‑owned installation
The product. A prospecting and commercial‑management solution for HR consultancies, defined as a CRM with a client‑flow pipeline, self‑hosted and single‑tenant.
The promise. The client retains direct control over infrastructure and data persistence because the product runs in their environment. Legal responsibilities for processing remain defined by controller/operator roles and applicable contracts, not by infrastructure location.
Why this. When there is a single organization per installation, the client‑to‑client isolation problem disappears and the question “where does the data live?” has a direct answer. Legal governance, however, does not simplify because of that. Complexity shifts to installation ease and updates, since the product must be operable by non‑infrastructure specialists.
The cost. Centralized visibility is lost, and support quality becomes dependent on an update process that works in environments you do not control.
What would make me undo it. Clients lacking the capacity to operate the installation; or support cost exceeding the value of offering data‑control.
- What the three cases show together
| Factor | Product A (stack per client) | Product B (multi‑tenant) | Product C (client‑owned installation) |
|---|---|---|---|
| Expected client count | Moderate | High | Variable |
| Value per client | Higher | Lower | Variable |
| Data sensitivity | High | High | High |
| Where isolation is guaranteed | Logical and operational stack segregation | Application and, in the target architecture, also the database | The installation itself |
| Marginal cost of a new client | Higher | Lower | Borne by the client |
| Greatest risk | Operations | Isolation failure | Support and updates |
Notice the sensitivity row: it is high in all three. The same privacy requirement produced three answers because the volume of clients, the value of each, and who bears the complexity changed. Copying another product’s model without comparing these factors copies the answer without the question.
- The data that AI creates
When the product uses AI with context retrieval, isolation must reach places that the relational model alone cannot. An explicit decision is warranted:
The promise. No data from another client is made available to the inference context, retrieval, tools, or cache of an unauthorized execution, and the application also validates access to persisted results and generated artifacts. This is a property verifiable by deterministic controls, not a promise about every probabilistic model output. For what escapes deterministic control, I adopt controls to reduce and detect improper exposure in responses: authorization validation before retrieval, context isolation, and continuous negative testing.
What this requires.
- Vector indexes with access control applied before any result reaches the application or model.
- Caches and contexts partitioned per client. A shared cache without partition could serve one client’s response to another.
- Content sent to vendors. What is retrieved and sent to the model is data processing and must be covered by governance, retention, and contract.
- Derivatives. Vector representations, summaries, and generated results are data with provenance and must be traceable back to it.
The authorization flow. The boundary spans storage, retrieval, and consumption:
- Authenticated request: identity, client, and permissions.
- Authorization layer: trusted scope and access policies.
- Operational data and vector search: authorized queries, with filters and access control applied at retrieval.
- Context for AI: only content permitted for that execution.
- Response and artifacts: delivery authorization, provenance, and retention.
Controls are applied in the systems that provide the data, not only in instructions given to the model.
The cost. In a stack‑per‑client setup, much of this is solved by stack segregation. In a shared model, each item becomes an explicit responsibility that requires testing and evidence.
What would make me undo it. A negative test that manages to retrieve another client’s content by any AI path. That result alone forces a review of the isolation decision for the whole set.
- The lifecycle: data also needs to end
Data without an expiration accumulates risk. The architecture must answer, for each data category:
- Why it exists and how long it needs to exist.
- How data‑subject rights are met: access, correction,

