Skip to content
← Back to the blogAI

How we cut our Snowflake bill by 25% and won back our engineering time

Andy Beyerly · September 17, 2026

Our Snowflake bill grows every year, and most of that is healthy: more data, more users, more of the business running on the warehouse. Underneath that, though, we were paying for two things we couldn't explain - tables that were poorly optimized, and jobs running on compute far larger than the data they were processing needed.

The same workloads were costing us more without providing any additional benefits, so we took two different AI driven approaches: implementing Espresso AI, which sits under our queries and decides what compute they run on, and a Snowflake Cortex agent that works inside our repo and optimizes the models themselves.

The treadmill

Warehouse optimization is never finished. A model that was well-tuned in January is badly tuned by June, because the data underneath it grew, the access pattern shifted, or someone added a join that broke pruning. Nothing was wrong with the original work - it just expired.

Warehouse optimization was taking 10 to 20 percent of our engineering time, and at the end of it our models did exactly what they did before. Just for less money.

The same work would always come back around. Someone would notice a warehouse running hot, or a nightly job creeping past its window, and the tuning pass would start over. Ultimately this meant that expensive engineering time was spent holding a line rather than moving one.

An example of where this hurt us - in March 2025 we identified one of our product models as being a major bottleneck for our data pipeline. We pushed a change to materialize this model incrementally which vastly improved performance, but ended up causing some downstream side effects which broke some of the models that depended on this. After several of our engineers spent most of a day working through that problem and fixing it, we pushed a second optimization PR several weeks later to finally resolve it.

None of it moved the team forward or gave our business users anything new. It was time spent on tech debt that we would rather have spent building.

We decided to get off the treadmill of eternal optimization and go after the two costs underneath it separately.

Solution one: Espresso AI

Espresso AI runs as a proxy in front of Snowflake, and it decides what warehouse each query actually lands on and how those warehouses scale. It operates directly within Snowflake and not against our codebase.

What it optimizes is the gap between the compute we provisioned and the compute the query actually needs. That gap is invisible in our dbt project, because it isn't a property of our SQL - it's a property of the moment the query runs.

Using this tool alone is saving us roughly 25% on our Snowflake bill by allowing us to run more queries on smaller warehouses and having warehouses scale horizontally as traffic increases.

Solution two: Cortex agents

A weekly job runs a Cortex Code agent against our dbt project. During this job it reads from our Snowflake query history and looks at how a table is physically laid out against how it's actually being queried, finds where those disagree, and opens a pull request. The PR explains what it changed and shows the build timings before and after. Most importantly, we have special instructions for the agent in place to make sure that no data values are changing as part of this optimization.

It's a similar process to what we were doing manually before, but with two big differences. First, this job is proactive, so it's identifying models before they become a problem and before someone notices that they're an issue. Second, because it's reading from the query history, it's looking at how the usage of this table has changed over time and optimizes for how that table is being used more recently.

With this job, we've already seen some of our heavy-hitting models drop considerably in runtime and cost. One of our main models that contains information about our shop and registry purchase data dropped from a 20-minute runtime to about a 4-minute runtime because of this optimization created by the agent.

How the two compare

Here's a quick breakdown of how these different solutions work:

Espresso AI Cortex Code
Layer Compute routing and scaling Model code
Sees Query history and warehouse metadata Query history and our dbt repository
Output Queries land on warehouses that are right-sized for the workload they contain Pull request(s) in GitHub
Runs Continuously for each query Weekly
Human in the loop Monitoring and SLA tuning Code review
Fixes Over-provisioned compute Bad partitioning, pruning, materialization

For more insight into what we did, here's a quick video Snowflake produced highlighting our relationship with them and Espresso AI.

What's next

We're routing more of our Snowflake workload through Espresso AI. It started with our dbt jobs and now covers our Streamlit apps, our BI traffic, and our AI workloads.

On the code generation side, the Cortex agents optimize models that already exist. Where we're trying to get to now is figuring out how we can apply that same logic to newly created models and changed models to see if we can implement these optimizations before they ever become a problem.

At the end of the day, our Snowflake bill is always going to increase as our usage increases and our data gets bigger. What we're after is a bill that grows more slowly than the usage driving it, and these two solutions are how we're getting there.

Like how we work?

We're hiring engineers to build for millions of growing families.

See open roles