Cut your Snowflake bill, change one connection string
Why we're building melt — an open-source proxy that sits in front of Snowflake and decides, per query, where it should run. The launch post.
There's a specific moment, a few weeks into any serious agent rollout, when somebody on the data team runs SELECT WAREHOUSE_NAME, SUM(CREDITS_USED) FROM QUERY_HISTORY and screenshots the result into Slack with a panicked emoji. The first time we saw that screenshot, in late 2025, we thought it was a one-off. By February it was every week, at every design partner. The bill curve had bent.
Melt is what we built to fix it.
Snowflake's billing assumes humans drive the workload. Analysts refresh dashboards a few times a day. dbt models materialise overnight. Somebody asks a question, somebody runs a query. Compute spins up, runs, suspends. The bill, mostly, makes sense.
Agents don't run on that cadence. A single prompt fans out into dozens of small filters, joins, and aggregates as the model iterates toward an answer. Multiply that across a fleet of agents and the warehouse never gets to spin down. The cluster keeps autoscaling. The credits compound. The line goes up.
We've spent the last few months looking at that bill query by query, alongside design partners who got there first. The pattern is consistent: most of the queries agents generate don't actually need Snowflake compute. They scan less than 200 MB of Parquet. They're single-table filters, counts, and aggregates that an embedded engine could answer against a local copy of the lake. But every one of them runs against a warehouse, because that's where the driver was pointed.
Melt is the routing layer that fixes that. It's an open-source proxy that sits in front of Snowflake — drop-in, self-hosted, Apache-2.0 — and decides per query where each statement should run. You change the host on your driver's connection string. That's the whole migration. The proxy speaks Snowflake's REST wire protocol, so the official driver, JDBC, ODBC, dbt, Looker, Sigma, Hex, and anything else you've already wired up keep working without modification.
There are two decisions melt makes on every query.
The first is query routing: should this statement run against the lake at all? If your data is already on S3 via Iceberg or DuckLake, DuckDB can answer most reads locally for cents. No warehouse spin-up, no credit burn, no minimum billing window. Writes, Snowflake-only features, and oversize scans pass through. Dual execution stitches plans that touch a mix of synced and remote tables, pushing some operators down to Snowflake and finalising the rest in DuckDB. Every decision is logged, exported to /metrics, and visible in melt route so a reviewer sees exactly where each query landed and why.
The second is warehouse routing, shipping next. Most accounts have a couple of warehouse sizes already provisioned and most queries land on the wrong one. Melt right-sizes per statement: XSMALL for the small filter, LARGE for the nightly aggregate. Per-statement, transparent to the driver. The customers who today only run lake routing tend to cut about half their bill. The ones who get both halves cut more.
We're being deliberate about what we're not doing. We don't rewrite SQL. We don't build a cost-prediction model trained on three years of QUERY_HISTORY. We don't auto-create or auto-resize warehouses. We never store query text. The data plane runs in your VPC. The router is open-source, and we'll keep arguing in pull requests about whether a particular optimisation is worth its parity risk.
Today, query routing is in the open repo: per-query routing, dual execution, the parity sampler, the three policy modes — passthrough, allowlist, enforce — and the metrics and audit surface. Warehouse routing — design doc shipped, Phase 1 in flight — is next.
If your warehouse bill has started feeling agent-shaped, talk to us. The repo is open. The contact form goes to a real human.
— Toby
Founder, Melt