Query Routing
A Rust proxy that parses every Snowflake statement, classifies it against your sync state and policy markers, and runs it on the cheapest engine that returns the same result. Same drivers, same SQL, same answers — most reads never touch a warehouse.
Query Routing in three steps.
Parse
Every statement that arrives at the proxy is parsed with sqlparser-rs against the Snowflake dialect — including IFF, QUALIFY, FLATTEN, semi-structured access, time-zone arithmetic, and stored-procedure calls.
Classify
The router runs three checks against the AST: is_write (DML, DDL, GRANT/REVOKE, MERGE, TRUNCATE), uses_snowflake_features (Snowpark calls, GENERATOR, INFORMATION_SCHEMA, Time Travel), and extract_tables (resolves 1-, 2-, 3-part names against the session’s database/schema).
Look up sync, policy, and scan stats
For the resolved table set, the router fans out three concurrent catalog reads in a single Postgres round trip: tables_exist against the lakehouse catalog, policy_markers, and estimate_scan_bytes from the per-table statistics maintained by sync.
Drop in. Same drivers. Lower bill.
Cost lands where the work lands
Most analytics queries scan well under a gigabyte.
One connection-string change, no SQL rewrites
Melt speaks the same Snowflake REST shape your drivers already speak.
Per-query auditability
Every routing decision is exported to /metrics with route, reason, and backend labels, written as a structured log line, and reproducible offline via melt route "<sql>".
Frequently asked questions.
What is query routing in Melt?
Query routing is a per-statement decision the Melt proxy makes for every incoming SQL statement: route to the lake (DuckDB on Iceberg or DuckLake), pass through to Snowflake, or run as a dual-execution plan. Eligible reads — read-only, all referenced tables synced and active, scan under the configured byte cap, no policy violations — run on the lake; everything else forwards to Snowflake unchanged. The same drivers and the same SQL get the same answers; only the engine changes.
Does query routing rewrite my SQL?
The original statement is forwarded verbatim when the route is Snowflake. When the route is the lake, the proxy applies dialect rewrites only — IFF to CASE WHEN, DATEADD normalisation, QUALIFY lowering, PARSE_JSON and FLATTEN rewrites — so a Snowflake-dialect query runs against DuckDB. If the translator cannot produce a safe rewrite, the statement falls through to Snowflake rather than guessing.
What kinds of queries route to the lake versus Snowflake?
Read-only queries against synced and active tables, scanning under [router].lake_max_scan_bytes, with no policy markers and no Snowflake-only features (Snowpark, GENERATOR, INFORMATION_SCHEMA access, Time Travel), route to the lake. Writes — DML, DDL, MERGE, TRUNCATE, GRANT, REVOKE — and Snowflake-only constructs, oversize scans, policy-protected tables, and parser bailouts all pass through to Snowflake. The router never silently downgrades a query to a different answer.
How do I see why a specific query was routed where it was?
melt route "<sql>" runs the entire decision pipeline offline and prints the chosen route, the typed reason (for example UnderThreshold, WriteStatement, UsesSnowflakeFeature("FLATTEN"), AboveThreshold, TranslationFailed), and the translated DuckDB SQL. The same route, reason, and backend labels are exported on the melt_router_decisions_total Prometheus counter, so live traffic is observable in any Grafana board without scraping logs.
Get up and running in 5 minutes.
Connect your Snowflake account, swap your connection string, and watch your warehouse credits drop.