Nobody sets out to run three clouds. You buy a company that standardised on Azure, a data science team picks BigQuery because the models were already there, and the core estate stays on AWS because that is where it has always been. Five years later the reporting layer has to span all three and nobody remembers deciding that.
This post is about what that means for BI specifically, and it starts with the only property that matters.
Portability is a property of the data, not the tool
Every BI vendor claims to run anywhere. Most of them mean their control plane runs anywhere while your data sits in their proprietary store. That is portability of the software, which is the half that does not help you.
The dashboards, the models and the engine can be redeployed elsewhere. The data is in a format only that vendor reads, so moving off means re-extracting everything from source and re-validating every number.
Extracts are Parquet in your own bucket. If InsightViz vanished, every file would still be readable by Spark, DuckDB, pandas, Snowflake, BigQuery and the next tool you buy.
The test is not “can this run on my cloud?”. It is “if I removed this product tomorrow, what would I still be able to read?”
What ports, and what does not
| Layer | Portable? | Why |
|---|---|---|
| The extracts | Fully | Parquet on object storage. The engine reads s3://, gs:// and az:// through the same code path, resolving credentials from each cloud’s default chain. |
| Dashboards and models | Fully | Readable, versioned documents. They reference metrics by name, not by physical location, so a model can be repointed without touching a dashboard. |
| Access policies | Fully | Rows in Postgres, applied at query compile time. Nothing cloud-specific. |
| The API container | Mostly | ECS, Container Apps or Cloud Run. One container, 1 vCPU / 4 GB. The differences are in deployment plumbing, not the application. |
| Which sources are live | Cloud-specific | Only PostgreSQL, MySQL and Redshift attach. Redshift is live on AWS; Synapse, Azure SQL and BigQuery are extract-only. This is the real difference between the clouds. |
| Identity | One provider, all clouds | Okta, Entra or Google covers every deployment. This is usually where multi-cloud estates are already unified, and it is the easiest part. |
| Egress between clouds | Not portable, and not free | Reading an extract in one cloud from a container in another means paying egress on every query. Do not do this. |
The pattern that works: one deployment per cloud, one vocabulary
The instinct is to run a single deployment and reach across. That is the expensive mistake, because it converts every dashboard open into cross-cloud egress and every latency problem into a network problem.
The arrangement that works is a deployment beside each estate, sharing the thing that actually needs to be shared — the definitions.
flowchart TB
subgraph aws["AWS"]
A1["API"] --> A2[("Extracts in S3")]
A3["Redshift, Aurora"] --> A2
end
subgraph az["Azure"]
B1["API"] --> B2[("Extracts in Blob")]
B3["Synapse, Azure SQL"] --> B2
end
subgraph gcp["Google Cloud"]
C1["API"] --> C2[("Extracts in GCS")]
C3["BigQuery"] --> C2
end
M["One set of business definitions
net revenue means one thing"] -.-> A1
M -.-> B1
M -.-> C1
style M fill:#e6f7f2,stroke:#9fd8c9
The definitions are the federation layer
This is the part people expect to be hard and find is not. A business model is a readable, versioned document. Promoting the same definition of net revenue into three deployments is a file copy, reviewed like any other change — not a distributed query engine, not a federation product, not a third vendor.
Three deployments, each beside its own data, nothing crossing a cloud boundary on a dashboard open. What crosses is one file: the business model. Group revenue means one thing in all three, because the same definition document was promoted into each.
The interesting part is what the group tried first. A single AWS deployment reaching across to Blob and GCS worked in testing and produced a cross-cloud egress line of roughly £3,100 in the first month, on a reporting workload of no particular size. Reading an extract across a cloud boundary means paying egress on every query, forever.
What actually goes wrong in a multi-cloud estate
Rarely the technology. Three things, in order of how often they bite:
| Problem | How it shows up | The fix |
|---|---|---|
| The same metric, three definitions | Each cloud’s estate grew its own. The acquired company’s revenue excludes something yours includes. | Settle the top ten metrics once and promote them. This is the whole project. |
| Three sets of access rules | Nobody can answer “who can see EMEA revenue” without checking three places. | One principal naming scheme across all three; review them together |
| Refresh cadences nobody agreed | The AWS extract is hourly, Azure is nightly, and a combined figure silently mixes them. | State the cadence on the dashboard; the product marks stale results |
| Cross-cloud egress on every query | A surprising line on the bill three months in. | Deploy beside the data. Never read an extract across a cloud boundary. |
Note that three of those four are governance problems wearing an infrastructure costume. Multi-cloud does not create metric drift — it multiplies an estate's existing drift by the number of clouds and makes it impossible to ignore. Why definitions diverge →

Consolidating: the sequence that works
- Deploy beside the largest estate first. Not the newest, not the tidiest — the one with the most dashboards people actually open.
- Import its real workbooks and settle its definitions. That gives you a vocabulary with an owner rather than a whiteboard exercise.
- Deploy beside the second estate and promote the same definitions. This is where the disagreements surface. Expect it to take longer than the deployment did, and to be the valuable part.
- Only then consider whether one deployment could serve two clouds. Usually the answer is no, and the question stops mattering once the definitions agree.
On-premises, and the case nobody asks about until they do
The storage layer also reads a plain filesystem, and the engine runs the same compiled SQL in a browser or a desktop application. For a regulated estate where an extract may not leave a building, that is a real deployment shape rather than a slide — though it trades away the scheduled refresh and most of the operational convenience.
What we have and have not proven
- AWS is production. We run it. Everything in that post is measured rather than designed.
- Azure and Google Cloud are supported by the code, not by our operational experience. The storage paths are real and exercised; the surrounding deployment is a design. Ask for a proof of concept rather than a commitment date.
- We have not run a three-cloud estate end to end. The architecture above is what the pieces support, argued honestly. If you are living this, we would rather hear about it than tell you about it.