How to connect Snowflake to Google Sheets and control what it costs
Connect Snowflake to Google Sheets and cut cost with warehouse sizing, auto-suspend and batched refreshes, plus credentials for jobs.
On this page
- What we'll cover
- Key takeaways
- Compute time, not bytes
- Auto-suspend and the wake-up cost
- Building it with CodeWords
- Warehouse sizing for a report
- Credentials for a scheduled job
- Network policies
- How to make the extract trustworthy
- Reading from a model, not a raw table
- How to make the job reliable
- Limits of the integration
- What to set up first
- Frequently asked questions
- Related reading
To connect Snowflake to Google Sheets and control the cost, run one scheduled query on a small, dedicated warehouse with a short auto-suspend, and let people read the sheet instead of triggering refreshes. Snowflake charges for compute time, not for data scanned (Snowflake documentation, 2026). A query that takes eight seconds on an extra-small warehouse is nearly free, but the same query triggered forty times a day by people opening a sheet is not.
Three settings decide the bill: warehouse size, auto-suspend, and how often something wakes the warehouse. None of them is about SQL, which is why teams overlook them.
What we'll cover
- Compute time, not bytes
- Auto-suspend and the wake-up cost
- Building it with CodeWords
- Warehouse sizing for a report
- Credentials for a scheduled job
- Network policies
- How to make the extract trustworthy
- Reading from a model, not a raw table
- How to make the job reliable
- Limits of the integration
- What to set up first
- Frequently asked questions
Key takeaways
- Snowflake bills for the time a warehouse runs, so idle time and repeated wake-ups cost more than the queries themselves.
- Use a small, dedicated reporting warehouse with a short auto-suspend, and cluster report schedules into one window.
- Authenticate unattended jobs with key pair authentication on a dedicated user whose role can only read specific views.
- Point the extract at a view or modelled table, so business definitions live in one reviewed place.
- Write the run time into the sheet, because a stale sheet looks identical to a current one.
Compute time, not bytes
Snowflake bills for compute time, so cost depends on how long a warehouse runs, not on how much data a query reads.
Credits accrue while a warehouse is running. Billing uses fine increments with a minimum charge each time the warehouse starts.
A larger warehouse costs proportionally more per second and finishes proportionally faster. For a parallelisable query the total can be similar. For a small report the larger warehouse is simply more expensive.
Idle time is charged until the warehouse suspends. Most avoidable cost sits here.
Results are cached. An identical query against unchanged data can return from cache without running the warehouse, so repeated identical reads cost almost nothing while small query variations cost full price.
Batch the work. One scheduled query that does everything beats twelve queries that each wake the warehouse, because the wake-ups are the cost.
Auto-suspend and the wake-up cost
Auto-suspend is the setting that decides whether a reporting workload is cheap. It controls how long a warehouse stays running after its last query.
| Auto-suspend | Effect | Suits |
|---|---|---|
| Long | Keeps the warehouse warm; wastes idle time | A stream of interactive queries |
| Short | Saves idle time; each run pays the start-up minimum | A report that runs once or twice a day |
Use a dedicated warehouse for reporting: small, with a short auto-suspend, and separate from interactive work so a heavy report does not slow an analyst mid-query.
Cluster your schedules. If several reports run each morning, run them in the same window so one wake-up serves all of them.
Watch for the trickle pattern. A sheet that refreshes on open, used by a handful of people through the day, keeps a warehouse alive almost continuously for a few dozen seconds of actual work.
Building it with CodeWords
CodeWords connects to 3,000+ integrations (CodeWords integrations page, 2026), and each connection is made once and reused.
- Open CodeWords and start a new automation.
- Describe what should happen in plain language to Cody, the automation builder: which query, on which warehouse, how often, and which sheet it lands in.
- Authorize the connection with a dedicated Snowflake user using key pair authentication, restricted to a reporting role and warehouse, plus access to the target spreadsheet.
- Describe the exceptions: a query returning nothing, a result larger than the sheet can hold, a warehouse that is suspended and slow to resume.
- Run it against a copy of the sheet and confirm the figures for a period you already know.
You describe the outcome; Cody builds it, connects it, and deploys it. The Free plan costs $0, Pro costs $39 per month and Business costs $100 per month (CodeWords pricing page, 2026). Details are on the pricing page.
Warehouse sizing for a report
Size a reporting warehouse at the smallest size and increase it only with evidence.
Start at the smallest size. Most reporting queries against modelled tables gain nothing from more. The instinct to size up usually solves a modelling problem with money.
Size up only with evidence. A query that spills to disk or queues is a reason. A query that is slow because it scans a badly clustered table is not.
Separate reporting from transformation. On a shared warehouse, a report competes with a nightly build, and both look intermittently slow.
Set a resource monitor on the reporting warehouse, so a runaway job hits a ceiling instead of producing a surprise bill.
Query the account usage views for credits by warehouse and by query. A single expensive report becomes visible there, and nobody looks unless an automation reports it.
Credentials for a scheduled job
Credentials for a scheduled job should use key pair authentication on a dedicated user. Teams most often get this step wrong.
Use key pair authentication for anything unattended, not a password.
Create a dedicated user for the integration, not a person's account. The integration then survives staff changes, and its activity is attributable.
Grant a role with select on the specific views it reads, plus usage on one warehouse. Reporting needs nothing more.
Rotate keys on a schedule, and confirm the next scheduled run succeeded. A rotation that silently breaks a Monday report is discovered on Wednesday.
Never let the report's role own objects, so a mistake cannot drop anything.
Network policies
A network policy is the most common reason the connection fails before anything else matters. Network policies restrict which addresses may connect, and many organisations have one.
Confirm which addresses your automation connects from before requesting an allowlist entry. The request depends on that detail.
Check early whether private connectivity is required. It is a larger piece of work than an allowlist entry.
Test the connection before building the query. A failed connection at the end of a build is the same problem found later, and the conversation with whoever owns the policy takes longer than the code.
Log enough to tell errors apart. Authentication and network errors look similar from the outside.
How to make the extract trustworthy
A trustworthy extract shows when it ran, what produced it, and when it has nothing to report.
Write the run time into the sheet, visibly. A stale sheet looks identical to a current one.
Name the query or the model that produced the data, so a disputed number can be traced.
Replace a named range, not append, unless the sheet is deliberately a log.
Report an empty result instead of writing an empty sheet, because an empty sheet reads as zero.
Flag implausible magnitudes before writing. A silently halved figure is worse than a failure.
Reading from a model, not a raw table
Read from a view or a modelled table, because the source determines how often the extract breaks.
Point at a view or a modelled table, not at raw ingested data. Raw tables change shape when a source system changes, and nobody thinks of the spreadsheet when that happens.
Let the modelling layer own the definitions. If a view defines "active customer", every report agrees. If each extract defines it in its own SQL, reports diverge and somebody spends a morning working out which is right.
Ask for a view if none exists. A reporting view built for the purpose is a small request and makes the extract stable.
Avoid SQL that reimplements business logic. An extract with a hundred lines of case statements is a model nobody reviews, sitting outside the place where models are reviewed.
Version the query with your other code, so a change to the definition has an author and a diff.
Name the source model in the sheet, so a disputed number leads back to a definition, not to an argument.
How to make the job reliable
A reliable job has timeouts, tolerates the resume delay and writes idempotently.
Set a query timeout and a statement timeout on the role. Both are free and stop a runaway query holding a warehouse open.
Handle the resume delay. A suspended warehouse takes a moment to start, and a short client timeout treats that as a failure.
Make writes idempotent by replacing a range, not appending.
Handle schema changes in the source view by reporting clearly, not by writing a sheet with a missing column.
Report the outcome: rows written, execution time and the warehouse used. The last two keep the cost conversation grounded.
Limits of the integration
Five limits shape the design.
Sheets has a total cell limit, which wide results reach faster than people expect.
Sheets API writes are rate limited, so large writes need chunking.
Result caching needs an identical query and unchanged data. A query containing a timestamp never hits the cache.
Snowflake bills a minimum per warehouse start, so very frequent small queries cost disproportionately more.
Account usage views have a latency, so credit figures are not real-time and a cost report looks backwards.
What to set up first
Set up credit consumption reporting by warehouse and by query, delivered weekly. The report is read-only, runs on the smallest warehouse, and turns an unexplained bill into a named report that somebody can decide about.
Two habits make the difference. Report the change week on week, not the total, because a new expensive query is what you want to catch. And include the warehouse each query ran on, because a report competing with transformation jobs needs a different fix from a report that is simply expensive.
Frequently asked questions
Why is our Snowflake bill higher than the query time suggests?
Idle time and wake-ups cause the gap. Credits accrue while a warehouse runs, with a minimum charge at each start, so a trickle of small queries through the day keeps the warehouse alive for far longer than the work itself takes. Batch the queries and shorten auto-suspend.
Should I use a bigger warehouse for reporting?
No, start at the smallest size and increase it only with evidence of spilling or queuing. A report that is slow because of how the data is modelled will not get meaningfully faster on a larger warehouse, and the larger warehouse will cost more per second.
What auto-suspend setting should a reporting warehouse have?
A short one, on a warehouse dedicated to reporting, with schedules clustered so several reports share one wake-up. A long auto-suspend suits interactive work and wastes credits on a report that runs twice a day, because the warehouse sits idle while still billing.
How should credentials be handled?
Use key pair authentication on a dedicated user. Give that user a reporting role with select on specific views and usage on one warehouse. Never use a person's account, and never use a role that owns objects, because a mistake could then drop something.
Why can the automation not connect at all?
A network policy is the most common cause. Confirm which addresses your automation connects from and get them allowlisted. Establish early whether private connectivity is required, because that conversation with the policy owner usually takes longer than building the extract itself.
Why does the first query of the day take so long?
The warehouse was suspended and is resuming. The same mechanism saves money the rest of the time, so allow for the delay in the client timeout instead of treating it as a failure. A short timeout turns a normal start-up into a false error.
How do I stop the same report being run repeatedly?
Schedule the report once and have people read the sheet, instead of letting each viewer trigger a refresh. That single change converts a per-viewer cost into a fixed cost, and it is usually the largest saving available for a shared report.
Should the extract query raw tables?
No. Point the extract at a view or a modelled table. Raw tables change shape when a source system changes, and business logic inside an extract becomes a model that sits outside the place where models are reviewed, so errors go unnoticed.
Why do two reports disagree about the same metric?
Each report almost always defines the metric in its own SQL. Move the definition into a view that both reports read, and name the view in the sheet. A dispute then leads back to one definition instead of an argument between two queries.