Checking whether a fix landed in staging, whether a config row matches across three production shards, or whether two environments really are identical usually means opening three database clients and running the same query three times. The FoxSchema SQL Editor lets you run one SQL query against multiple database servers at once and read the answers side by side.
Why One Query, Many Servers Matters
Schema comparison tells you how two databases differ structurally. It doesn't tell you whether the feature_flags table holds the same values in staging and production, or which of your regional servers is missing a reference row. That's a data question, and it's the one that tends to come up at the worst possible moment — mid-incident, when you're trying to work out which environment is the odd one out.
Running the query once per server works, but you end up comparing results by eye across windows, and it's easy to misattribute a result to the wrong environment. Executing once against every server, with results labelled by connection, removes that class of mistake.
How Multi-Destination Execution Works
The SQL Editor is part of the FoxSchema web UI — run foxschema locally to open it, or self-host the Docker container. Under Destinations, you check one or more of your saved connections — the same SQL then runs against every checked server. Results come back grouped by connection, and you can lay them out stacked or side by side. Sibling grids from the same run sync their vertical scroll by row index, so comparing row 400 across three servers doesn't mean scrolling three grids independently.
Destinations don't have to share a dialect. FoxSchema supports PostgreSQL, MySQL, MariaDB, SQL Server, Azure SQL, Oracle, IBM Db2, SQLite, ClickHouse, and Amazon Redshift, and the editor reuses the connections you've already saved for schema work.
Controlling What Actually Runs
Broadcasting a statement to several production servers deserves more care than firing off a single query, so the editor is deliberate about what executes:
- Statement strip — a buffer with ten statements shows all ten below the editor, and you enable or disable each one before hitting Run
- Run selection — highlight any SQL in the editor and Run executes only that text
- Safe mode — when enabled, write and DDL statements require an extra confirmation before they run
- Row caps — each statement returns a capped page of rows (200 by default), with Next/Prev paging that caches visited pages in memory rather than re-querying
Variables and Per-Connection Overrides
The awkward part of querying several environments is that the identifiers rarely match — the tenant ID in staging isn't the tenant ID in production. Variables handle this. You define a named value, reference it as ${{name}}, and set a per-connection override so each destination substitutes its own value in the same run.
Variables can also be captured from results. Put -- @set orderid immediately above a SELECT and the run captures that value for later statements; right-clicking a result cell or column header does the same interactively. Statements run sequentially, so later SQL can use values captured earlier. Substitution is textual — values are pasted into the SQL before it's sent, not passed as bind parameters — and variables marked as secret are masked in the UI and kept session-only.
Mixing SQL With Code Cells
Sometimes the comparison you want isn't expressible in SQL, particularly across dialects. Code cells let you fence a block with -- @js or -- @ts (running in your browser) or -- @node (running on the FoxSchema server) and post-process results in JavaScript or TypeScript. A cell receives last — the previous statement's grid — plus your variables, and returns either { columns, rows } or an array of objects. A short allowlist of bundled imports is available: lodash, lodash-es, and date-fns. Python isn't supported yet.
One caveat worth stating plainly: -- @node cells execute on the server host. On a personal or desktop install that's the point. If you host FoxSchema for a team, treat the ability to run Node cells as roughly equivalent to shell access on that host, and only expose it to people you'd trust at that level. Browser cells carry no such risk.
Where It Fits Alongside Schema Diff
The editor complements schema comparison rather than replacing it. Use the diff to find structural differences and generate migration SQL — see comparing two schemas and generating migration SQL — then use the editor to confirm the data side. It's a practical follow-up when you're chasing schema drift and need to know whether a discrepancy is structural, data-level, or both. Full details are in the documentation.
The SQL Editor ships with the FoxSchema web UI — install the CLI with npm or Homebrew and run foxschema to open it locally, or deploy the container using the self-hosting guide.