One SQL statement across all your databases.
Your orders are in MySQL. Your customers are in PostgreSQL. The targets everyone argues about live in a SQL Server box at head office. A federated query lets you write one ordinary SELECT that reads all three at once and hands you a single table — no exports, nothing copied anywhere, and nothing new to open on your firewall.
On every plan, including Free · Free runs 2 sources and 250 result rows — the ceilings grow with your tier
38 database connectors — join across any of them, in any combination







Alongside them in Query Streams: 8 API connectors, queried with the same SQL

53 sources in total. Your API connectors are queried with SQL like everything else — and a federated statement joins your database connections. See the API Connector
Put the connection name in front of the table
That is the only new idea on this page. Each highlighted name below is a different database, in a different place, reached by a different Network Agent — and it is still one query.
-- one federated query · nothing copied anywhere
SELECT c.region,
COUNT(*) AS orders,
SUM(o.total) AS revenue,
t.target
FROM mysql_prod.shop.orders1 o
JOIN pg_crm.public.customers2 c ON c.id = o.customer_id
JOIN mssql_erp.dbo.region_targets3 t ON t.region = c.region
WHERE o.placed_at >= DATE '2026-07-01'
GROUP BY c.region, t.target
ORDER BY revenue DESC;mysql_prod, pg_crm and mssql_erp are simply the names you gave your own connections — the three parts are connection, schema, table. This is what people mean by a federated database: three separate databases answering one question, with nothing merged and nothing moved. Illustrative schema; your tables will be your tables.
Where each name resolves
mysql_prod
MySQL · shop.orders
Cloud agent
Filters to July itself, then totals revenue per customer before sending anything.
pg_crm
PostgreSQL · public.customers
Regional agent
Returns just the id and region columns — the only two the query names.
mssql_erp
SQL Server · dbo.region_targets
Head office agent
Hands over the target per region, written as T-SQL so it runs natively.
Three agents, three networks, one statement — and none of them opened a port to do it.
More reach, not more exposure
Reading two databases at once uses exactly the same path as reading one. Nothing new is opened up to get it.
Outbound only
The agent opens one encrypted connection out to Query Streams and carries both the request and the results over it. No inbound port, no VPN, no firewall change — and your credentials never leave your network.
Read-only, every piece
Each piece of the query is checked before it goes anywhere: SELECT, WITH and EXPLAIN only. A federated query cannot write to any of your databases, and anything rejected never reaches them at all.
It cannot run away with your server
There is a ceiling on how much any one database may hand over for a single query, and the agent stops the moment it is reached. A mistake in a WHERE clause costs you an error message, not an afternoon.
Three steps, and none of them is a data pipeline
Pick your connections
Choose two or more of the connections your team already set up. Two is the minimum — that is what makes a query federated. Nothing gets copied and no new passwords are created.
Write one statement
Name each table as connection.schema.table, then write normal SQL. Before you run it you can read the plan: which database is being asked what. Or describe the question and let Nova draft it.
Save it like any other query
Once it works, it is a saved query — so it can be shared, given filters, sent as a weekly report, published as an API endpoint or pulled into a spreadsheet.
Each database does its own share of the work
The lazy way to join two databases is to drag both tables across the network and sort it out afterwards. That is slow, and it means far more of your data leaves your building than the question needed.
So we do the opposite. Filtering, picking columns and counting up totals are handed back to each database to do itself, in its own language. A report that groups millions of rows sends back the handful of grouped totals — not the millions of rows behind them.
Whatever is left over, we do — and we show you which is which. Joining across databases is our job, because no single one of them can see the others. The plan spells out what each database was asked for and what we finished off, so an expensive query is obvious before you run it.
It would rather refuse than quietly be wrong
Here is the awkward truth about joining separate databases: they do not always agree with each other. Two of them can be handed the same question and come back with answers that differ in the last decimal place, or in what counts as equal, or in what “first ten” means.
If you are new to this, the short version: a database is not just a bucket of rows. It has its own opinions about how to add up money, how to sort words, and where empty values belong. Ask two different databases to sort the same list of customer names and you can genuinely get two different orders — not because one is broken, but because they were built with different rules. Any tool that joins databases has to deal with that. Most quietly pick one answer and hope. We do not.
What we do instead has exactly two outcomes, and the Query Builder shows you which one you got: a plan pill that reads ready or refused as you type, and a Plan tab with the full working.
When the disagreement is about how a calculation is done, we stop asking your database to do that part and do it in the stitch step, where there is one consistent set of rules. It costs a little speed. It costs you no accuracy and no attention — you are not asked to do anything.
- Money and precision. Databases widen and round decimals differently once totals get large. If adding up in-source could round differently from adding up centrally, we bring the numbers back and add them up ourselves.
- Sorting text. Whether
acomes beforeB, and how accents compare, is a per-database setting. Comparisons that depend on it are settled centrally, not pushed down. - Ranking and running totals. Window functions — row numbers, running totals, “top 3 per region” — are always computed after the pieces arrive, because no single source can see the others.
When carrying on would change which rows come back — not just how fast — there is no safe way to guess. So the query does not run, and the message names the exact expression and the exact database, in your own SQL, so you know what to edit.
- A function that source cannot do. If your filter uses something we cannot faithfully express in that database’s dialect, the only alternatives are to send it a wider query than you wrote or to invent an equivalent. Both are wrong answers, so we refuse.
- Row limits inside a piece. A
LIMITorTOPapplied to one source before the join returns an arbitrary handful of rows, then joins those — a plausible-looking table of nonsense. Limits belong to the finished result. - A moved goalpost. If a connection was re-pointed at a different database since the query was planned, the stored plan is stale and we ask for a re-plan rather than run yesterday’s plan against today’s data.
Three refusals, and what each one is telling you
Cannot push LOWER(c.email_domain) = ? down to mssql_erp: function not in the pushdown allowlist.
In other words: your filter wraps a column in a function that source cannot be trusted to apply the same way we would, so we cannot guarantee it returns the same rows. What to do: compare the plain column instead, or move that condition outside the source — the message tells you which source to look at.
LIMIT 100 cannot be applied to a single source before the join: the result would be 100 arbitrary rows, not the first 100 of your answer.
In other words: “first 100” only means something once everything has been joined and sorted. What to do: leave the limit on the statement as a whole, which is where it does what you expect.
Source 2 now points at a different connection or database than when this query was planned.
In other words: somebody changed what pg_crm refers to. What to do: open it in the Query Builder and re-plan — one click, and you can see the new plan before running it.
The rule underneath all of it: if a query would come back wrong, we refuse. If it would merely come back slowly, we run it and warn you. Wrong data is never a trade-off we make on your behalf.
You are not left to fix a refusal alone, either. Nova sits beside the editor in the Query Builder and speaks this whole system fluently: ask, and it explains the refusal in plain words, rewrites the statement so it runs, and checks the new plan for you. And if you would rather skip writing the SQL at all, describe the question and Nova drafts the federated statement itself.
And for anyone who wants the detail rather than the reassurance: the Query Builder’s Plan tab lists every source, the query it was actually sent, which of your conditions it applied itself, and which parts we finished off centrally. Nothing about the decision is hidden — including the parts where we chose the slower, safer route.
A federated query is just a query
It is not a separate product with its own rules. Once it is saved, every other part of Query Streams treats it like anything else you have written.
Query Builder
Write it in the same editor, with the same schema tree beside you. A Plan tab shows what each database was asked for; an Insights tab charts how each one performed.
Nova AI
Describe the question in English and Nova reads your schemas and drafts the statement — including which connection each table belongs to. It can run it and chart the result too.
Google Sheets
Pick the saved query in the add-on and the combined results land in your cells, formatted and refreshable — the same as any single-database query.
Excel
Same story in Excel: run one or run a whole sheet of them, with frozen headers, filters and in-place updates that leave your own formula columns alone.
Database REST API
Publish the cross-database result as a JSON endpoint with a key, and whoever consumes it never needs to know it came from three systems.
MCP for AI assistants
Claude and other assistants can list and run your federated queries through MCP, so “how did each region do last week” is answerable in chat.
Reports & alerts
Put it on a schedule and the combined figures arrive in Slack, Google Chat, Discord, Telegram or email — or set a threshold and only hear about it when something moves.
Automation & sharing
Sync the result into a spreadsheet on a schedule, or share the query with a colleague who only sees filters and a Run button — never your SQL or your connections.
The reports that used to be two exports and a VLOOKUP
Almost nobody has one database. There is the ERP, the shop, the CRM, and whatever the last acquisition ran on.
Orders here, customers there
The shop writes orders into MySQL; the CRM keeps customers and regions in PostgreSQL. “Revenue by region” stops being two exports and a lookup, and becomes one saved query anyone can re-run.
After an acquisition
Two companies, two stacks, one board pack due Friday. You get the combined view on day one, while the real migration takes the eighteen months it always takes.
Stock against sell-through
Stock levels live in the warehouse system in another country; sales live in the shop database. One statement puts them side by side — and the same statement can then arrive every Monday as a report.
One database per site, one number
The same schema deployed per country, per tenant or per shop floor. Add them up in one statement instead of maintaining a script that runs the query five times and totals it by hand.
Federated database, data federation, data virtualization
Three names for overlapping ideas, and plenty of marketing has blurred them. Here is what each one means, and which bit we actually do.
A federated database
A federated database (or federated database system) makes several separate databases behave like one, without merging them. Each keeps its own storage, its own engine and its own owner; a layer above them takes your query and works out who answers which part.
That layer is what Query Streams is. There is no new database underneath, and nothing is copied into one.
Data federation
Data federation is the approach itself: leave data where it was written and query across it when you need it, instead of extracting everything into a central copy first. The alternative is a pipeline plus a warehouse — move it all overnight, then only ever query the copy.
Both are legitimate. Federation wins when the question spans systems, when the data has to stay put, or when a warehouse project would cost more than the answer is worth. A warehouse still wins for heavy historical analysis over enormous volumes.
Data virtualization
Data virtualization is the bigger enterprise category built on federation — usually federated querying plus a modelling layer, caching and governance tooling, sold as a platform of its own.
We are deliberately the narrow, honest slice of that: federated querying over the connections you already have, inside the tool your team already writes queries in. No modelling project, no server of your own to run, no consultants.
Federated query FAQ
What is a federated query?
A federated query is one SQL statement that reads from more than one separate database and gives you a single combined result. Nothing is copied first: your statement is split into a small query per database, each one answers the part it can, and the pieces are joined into the answer. In Query Streams a statement becomes federated as soon as it names two or more of your connections.
Do my databases need to be in the same place?
No. They can be in different offices, different cloud accounts, different countries, or a mix of all three — one in a server room, one in a private cloud network, one on a machine in a warehouse. Each location runs a Network Agent, and each agent reaches Query Streams by dialling out. As far as your firewall is concerned that is just an ordinary outbound connection, so there is nothing to open and no VPN to build.
You can also point several databases on one server at the same agent; one agent per location is normal, not one per database.
Do I need a data warehouse or an ETL pipeline as well?
Not for this. There is nothing to load and no schedule to babysit — the query reads your live databases at the moment you run it, so the answer cannot be stale the way last night’s copy can. What federation does not replace is heavy historical analysis over very large volumes; that is still a warehouse’s job. Rough test: if the question spans systems and needs to be current, federate it.
Which databases can I join together?
Any of your database connections, in any mix: SQL Server, PostgreSQL, MySQL, MariaDB, Oracle, Snowflake, BigQuery, SQLite, Access and DuckDB. Each database is asked in its own dialect, so the same statement can send TOP to SQL Server and LIMIT to PostgreSQL without you thinking about it.
Databases genuinely differ in what they can compute and how they sort and round, so not every combination of every expression can be answered exactly. When that happens you get a specific message naming the expression, rather than a number that is nearly right.
Is it slower than querying one database?
It depends on how much of the work each database can do for itself — which is exactly what we optimise for, and exactly what the plan shows you. When the filtering and grouping all happen inside your databases, very little data moves and it feels like a normal query. When a big join has to be finished off by us, more moves, and the plan says so before you run it. Each database also has a ceiling per query, so a mistake stops early instead of grinding.
Is it safe to point one query at several production databases?
It uses the same security model as every other query you run here. Each piece travels through your own Network Agent over one encrypted outbound connection — no inbound port, no VPN, no firewall change — and your database credentials never leave your network. Every piece is checked read-only (SELECT, WITH, EXPLAIN), a federated query cannot write anywhere, and each database only ever sees a query touching the columns you named.
How is this different from Trino, Presto or Denodo?
The idea is the same one Trino and Presto made popular: one SQL statement, pushed down to many sources. The difference is what you have to run and learn. Those are clusters you deploy, tune and wire into your network; the data-virtualization platforms add a modelling layer and a licence to match. Ours is the same capability delivered inside the tool your team already queries with, reaching the connections you already set up, with no server of your own to operate.
The other difference is that we refuse. Where databases disagree in a way that could change a figure, we stop and name the expression we could not handle instead of returning something plausible.
What can I do with the result?
Everything you can do with any saved query, because that is what it is. Save it, share it with your team, give it filters, schedule it as a report into Slack or email, publish it as a REST endpoint, or pull the results into Excel and Google Sheets. Nova can also read your schemas and draft the statement if you would rather describe the question than write the joins.
Your databases stay where they are. The question stops caring.
Name two connections, write one statement, read the plan before you run it. No pipeline, no warehouse, no firewall ticket.
Federated queries are on every plan, including Free

