Data Analytics

How to choose a data warehouse: BigQuery, Snowflake, Redshift, Athena and Databricks compared

How to choose a data warehouse: a vendor-quoted matrix of the five, and a real month of one analytics project's queries replayed under a bytes meter and a time meter.

Data AnalyticsIevgen Krasovytskyi14 min read

How to choose a data warehouse: BigQuery, Snowflake, Redshift, Athena and Databricks compared

Choose a data warehouse by where your data and your team already live, by the billing meter that matches how you query, and by the cost controls you can actually set – then put a governed layer on top, because the warehouse alone does not make anyone trust the numbers. The five platforms compared here differ most in what they charge for.

A head of marketing we worked with once described his situation in a sentence: a couple of reports were already built on warehouse tables, and nobody had any confidence in that data. The warehouse held the data and answered queries; it could not tell him which number to believe. The warehouse decides where data lives and what queries cost; the trust comes from the model on top.

Note: Originally published in March 2026. Fully updated in October 2026 with a vendor-quoted comparison matrix of the five platforms, a reporting query billed 16.7 times what it read, and a real month of one analytics project’s query log, split by AI assistant, service accounts and a person, replayed under both billing meters.

How to choose a data warehouse in three questions

How to choose a data warehouse in three questions

If you are signing off on a warehouse rather than running it, ask your analyst to answer three questions in writing.

  1. Where does the data and the team already live? Data already in Google Cloud points to BigQuery. Data in Amazon S3 and an AWS team point to the AWS data warehouse options, Redshift (Serverless or provisioned) and Athena. An existing Databricks contract points to Databricks SQL. Snowflake’s documentation says “a Snowflake account can be hosted on” AWS, Google Cloud or Microsoft Azure (Snowflake docs, October 2026), which makes it the usual pick when no cloud has won inside the company.
  2. What does the meter charge for, and does it match how we query? One meter charges for bytes scanned (BigQuery on-demand, Athena); the other for compute time while something runs (Snowflake credits, Redshift RPU-hours, Databricks DBUs).
  3. What cost limit can we set, and does it stop spend or only report it? You want at least one hard stop before the first dashboard goes live.

For marketing and product reporting, SQL dialect, connectors and BI support matter less than the meter: that data storage holds mostly plain tables read by a few dashboards. Still deciding whether you need a warehouse at all? Start with databases vs data warehouses vs data lakes.

Data warehouse comparison matrix: the five side by side

Data warehouse comparison matrix: the five side by side

This cloud data warehouse comparison uses only what each vendor states on its own pages, read on 15 October 2026. It holds no prices: rates change by region and contract. Where a vendor states nothing, the cell says so.

Google BigQuery Snowflake AWS Redshift AWS Athena Databricks SQL
Billing meter On-demand: “the number of bytes processed by each query” Credits: warehouses “consume credits as they execute queries” Serverless: RPU-hours, per second. Provisioned: nodes, “On-Demand Instances with hourly billing” “the number of bytes scanned per query” DBUs; idle warehouses “continue to accumulate DBU and cloud instance charges until they are stopped”
Capacity alternative Capacity pricing: slots (virtual CPUs) over time “Capacity or On Demand” account types; terms not stated on the docs we read Serverless reservations; provisioned Reserved Instances Capacity Reservations in DPUs, with no charge for data scanned; from 4 DPU Discounts for committing to “certain levels of usage”
Minimum billing unit On-demand: 10 MB per table referenced and 10 MB per query, rounded up to the MB. Capacity: per second, one-minute minimum (opt-in fluid scaling has none) Per second, 60-second minimum, which “starts over” on every resume Serverless: per second, 60-second minimum. Provisioned: one-second increments after a status change Rounded up to the MB, 10 MB minimum per query. Capacity: 1-minute minimum No minimum found for SQL warehouses; the platform pricing page says per-second granularity
Compute model Serverless: no provisioning or manual scaling; reservations can autoscale slots Virtual warehouses you size and resize while running; auto-suspend on by default; multi-cluster auto-scale; Adaptive Compute (Enterprise Edition, select regions) Serverless provisions, scales, starts and shuts down by itself. Provisioned: you choose the nodes and pause the cluster Serverless, scales automatically, queries data directly in S3 Serverless, pro and classic types; you set cluster size and min/max clusters; Auto Stop when idle
Open table formats Apache Iceberg managed tables (formerly BigLake tables for Apache Iceberg in BigQuery), in your own buckets, with DML writes Apache Iceberg tables for Snowflake; Snowflake-managed tables read and write Reads Iceberg tables in the AWS Glue Data Catalog; writes Iceberg to S3 on both Serverless and provisioned Read, time travel, write and DDL on Iceberg (version 1.4.2) Delta Lake native; UniForm adds Iceberg metadata to Delta tables; managed Iceberg tables in Unity Catalog
Cost control you can set Maximum bytes billed per query; custom daily quotas per project or per user that stop queries Resource monitors suspend a warehouse at a credit limit (warehouses only) Serverless: usage limits on RPUs that can turn off user queries; AWS recommends a max RPU-hours cap. Provisioned: usage limits cover add-ons such as Spectrum Per-query limit cancels the query; per-workgroup limit on total data scanned Budgets monitor usage; Auto Stop is the warehouse-level control

Sources, all read 15 October 2026: Google – pricing, introduction, Iceberg tables, cost best practices. Snowflake – compute cost, warehouses, Iceberg tables, resource monitors. AWS Redshift – pricing, Serverless billing, usage limits, Iceberg writes. AWS Athena – pricing, Iceberg, cost controls. Databricks – pricing, SQL warehouses, Iceberg.

Three things in the matrix change the decision more than the rest:

  • BigQuery and Athena share a 10 MB floor on demand: per query on Athena, per query and per table referenced on BigQuery.
  • Every time-based meter has a floor too. Snowflake’s 1-minute minimum starts over on every resume; Redshift Serverless bills at least 60 seconds.
  • The hard stops differ. BigQuery quotas stop queries once reached, Athena cancels a query over its limit, Redshift Serverless can turn off user queries and Snowflake suspends a warehouse. On Databricks, the budget page’s blocking option applies to Unity Gateway, so the control a team sets on a SQL warehouse is Auto Stop.

For deeper two-way comparisons, see Snowflake vs BigQuery, Snowflake pricing and cost control and Databricks pricing.

The Turning Point

OWOX Data Marts

See your first report built in real time. 15 minutes.

  1. Connect your data warehouse
  2. Pick your metrics
  3. Get a live Google Sheets report

In the time it takes to write a ticket. Then imagine never writing that ticket again.

Book a Demo

We'll use your actual use case

What the meter does to real queries

What the meter does to real queries

Here is what the rules did to queries we ran on Google BigQuery on-demand, using BigQuery’s own processed and billed byte counts. The first run is on owox-demo, a synthetic demo dataset; the second is real: a month of one analytics project’s query log.

A one-month spend report billed 16.7 times what it read

ecommerce.ad_performance is a view that unions seven ad-platform tables (Facebook, Google, TikTok, Microsoft, LinkedIn, Reddit, X) into one spend table. The question a marketing leader asks every month – spend by source for September – looks like this:

SELECT source, SUM(spend) AS spend
FROM `owox-demo.ecommerce.ad_performance`
WHERE date BETWEEN '2026-09-01'
  AND '2026-09-30'
GROUP BY source
ORDER BY spend DESC
Query Processed Billed
Spend by source, all dates 6,432,670 bytes (6.4 MB) 73,400,320 bytes (73.4 MB)
Spend by source, September 2026 4,384,382 bytes (4.4 MB) 73,400,320 bytes (73.4 MB)

The September query read 4.4 MB and was billed 73.4 MB. 73,400,320 is exactly 7 × 10,485,760: seven tables referenced, a 10 MB minimum for each, as Google’s pricing page states. The date filter cut what was read and changed nothing on the bill. Athena’s pricing page states a 10 MB minimum per query; we did not run the query there.

A dashboard that fires many small queries over a view with many source tables pays for the minimums, not for the data. The other half of the bytes meter – how column choice and table layout change what a query reads – is measured in step 5 of the implementation guide.

A real month of one project’s queries under both meters

Whether the floor matters depends on the whole workload, so we took a real one: the BigQuery job log of one OWOX analytics project, 15 September to 14 October 2026, successful SELECT jobs only. Not demo data: an AI assistant, scheduled service accounts and a person all queried it. The first query summarises it under the meter it was billed on:

WITH jobs AS (
  SELECT
    total_bytes_processed AS read_b,
    total_bytes_billed AS billed_b,
    cache_hit,
    TIMESTAMP_DIFF(end_time, start_time,
      MILLISECOND) AS ms
  FROM `region-us`.INFORMATION_SCHEMA
    .JOBS_BY_PROJECT
  WHERE creation_time >= '2026-09-15'
    AND creation_time < '2026-10-15'
    AND job_type = 'QUERY'
    AND statement_type = 'SELECT'
    AND state = 'DONE'
    AND error_result IS NULL
)
SELECT
  COUNT(*) AS jobs,
  COUNTIF(billed_b > 0) AS billed_jobs,
  COUNTIF(cache_hit) AS cache_hits,
  ROUND(SUM(read_b) / 1e9, 1) AS gb_read,
  ROUND(SUM(billed_b) / 1e9, 1) AS gb_billed,
  COUNTIF(billed_b > 0
    AND billed_b > 2 * read_b) AS over_2x,
  COUNTIF(billed_b = 10485760) AS at_floor,
  COUNTIF(billed_b > 0
    AND read_b < 10485760) AS read_lt_10mb,
  APPROX_QUANTILES(ms, 100)[OFFSET(50)]
    AS p50_ms,
  APPROX_QUANTILES(ms, 100)[OFFSET(90)]
    AS p90_ms,
  COUNTIF(ms < 60000) AS under_60s,
  ROUND(SUM(ms) / 1000, 1) AS runtime_s
FROM jobs
Bytes meter (actual bill) Result
SELECT jobs / billed jobs 1,878 / 1,625 (84 cache hits; the rest billed nothing)
Read / billed 792.0 GB / 834.9 GB: the floors added 5.4%
Billed jobs charged more than 2x what they read 806 of 1,625 (49.6%)
Billed exactly the 10 MB floor / read under 10 MB 515 / 817
Runtime: median / 90th percentile 680 ms / 4.7 s; 1,877 of 1,878 jobs under 60 s
Total query runtime 3,845.5 s (1.07 hours)

Half the billed jobs paid more than twice what they read, yet the floors added only 5.4% to the month. Who sent the queries explains why. Splitting the same jobs by their label (jobs an AI assistant sends through Google’s BigQuery MCP server carry the label goog-mcp-server) and by user:

SELECT
  CASE
    WHEN EXISTS (SELECT 1 FROM UNNEST(labels)
      WHERE key = 'goog-mcp-server')
      THEN 'AI assistant via MCP'
    WHEN user_email
      LIKE '%gserviceaccount.com'
      THEN 'Service accounts'
    ELSE 'A person, directly'
  END AS who,
  COUNT(*) AS jobs,
  COUNT(DISTINCT user_email) AS users,
  COUNTIF(total_bytes_billed > 0)
    AS billed_jobs,
  ROUND(SUM(total_bytes_processed) / 1e9, 1)
    AS gb_read,
  ROUND(SUM(total_bytes_billed) / 1e9, 1)
    AS gb_billed,
  ROUND(100 * (SUM(total_bytes_billed)
    / SUM(total_bytes_processed) - 1), 1)
    AS floors_pct,
  COUNTIF(total_bytes_billed > 0
    AND total_bytes_billed
      > 2 * total_bytes_processed) AS over_2x
FROM `region-us`.INFORMATION_SCHEMA
  .JOBS_BY_PROJECT
WHERE creation_time >= '2026-09-15'
  AND creation_time < '2026-10-15'
  AND job_type = 'QUERY'
  AND statement_type = 'SELECT'
  AND state = 'DONE'
  AND error_result IS NULL
GROUP BY who
ORDER BY jobs DESC
Who Jobs Read / billed Floors added Billed > 2x read
AI assistant via BigQuery MCP 1,269 434.9 / 475.4 GB 9.3% 619
Service accounts (scheduled loads, connectors) 403 160.6 / 162.5 GB 1.2% 180
A person, directly 206 196.6 / 197.0 GB 0.2% 7

The floors are an exploration cost. The assistant’s many small probe and metadata queries paid 9.3% on top of what they read; the person’s mostly large reads paid 0.2%. A team that puts AI agents on a bytes-metered warehouse should expect the floors to matter.

The second query asks what the same month would cost on a time-based meter. It is a model, not a measurement: it replays the real start and end times against the rules Snowflake and Redshift Serverless state – per-second billing with a 60-second minimum that restarts on every resume – and an auto-suspend setting of 60 or 600 seconds. Jobs that start before the previous ones have finished plus the idle setting share one busy window; each window bills its length plus the idle tail, at least 60 seconds. It assumes one compute unit and BigQuery’s own runtimes; another engine would run the same queries faster or slower.

WITH jobs AS (
  SELECT start_time, end_time
  FROM `region-us`.INFORMATION_SCHEMA
    .JOBS_BY_PROJECT
  WHERE creation_time >= '2026-09-15'
    AND creation_time < '2026-10-15'
    AND job_type = 'QUERY'
    AND statement_type = 'SELECT'
    AND state = 'DONE'
    AND error_result IS NULL
),
idle AS (SELECT n FROM UNNEST([60, 600]) AS n),
marked AS (
  SELECT n, start_time, end_time,
    IF(TIMESTAMP_DIFF(start_time,
      MAX(end_time) OVER (
        PARTITION BY n ORDER BY start_time
        ROWS BETWEEN UNBOUNDED PRECEDING
          AND 1 PRECEDING),
      MILLISECOND) < n * 1000, 0, 1) AS new_win
  FROM jobs CROSS JOIN idle
),
numbered AS (
  SELECT *, SUM(new_win) OVER (
    PARTITION BY n ORDER BY start_time) AS w
  FROM marked
),
windows AS (
  SELECT n, w,
    TIMESTAMP_DIFF(MAX(end_time),
      MIN(start_time), MILLISECOND) / 1000
      AS busy_s
  FROM numbered
  GROUP BY n, w
)
SELECT n AS auto_suspend_s,
  COUNT(*) AS resumes,
  ROUND(SUM(GREATEST(busy_s + n, 60))
    / 3600, 2) AS billed_hours
FROM windows
GROUP BY n
ORDER BY n
Time meter (model) Resumes Billed compute hours Against 1.07 h of query runtime
Auto-suspend after 60 s 511 11.53 h 10.8x
Auto-suspend after 600 s 264 61.7 h 57.7x

On the bytes meter, the floors added 5.4%. On a time meter, the idle tails would be billed 10.8 to 57.7 times the query runtime, depending on one setting. The two are different units – extra bytes over bytes read, idle hours over runtime – and neither is a price. They show where each meter’s waste comes from: short queries with gaps between them feed a time meter mostly idle minutes.

The decision rule

If your workload is mostly… A bytes-scanned meter (BigQuery on-demand, Athena) A time-based meter (Snowflake, Redshift, Databricks SQL)
Wide scans, SELECT *, filters on unpartitioned columns Punishes it: you pay for every byte read Indifferent to bytes; pays for the minutes the scan takes
Many tiny queries over many small tables Punishes it: in our month, +9.3% for the AI assistant’s queries, +0.2% for the person’s Fine while compute is already running
Short queries with gaps all day (ad-hoc, AI assistants) Fine: nothing runs between queries Punishes it: in our model, 10.8x–57.7x the runtime in idle tails and per-resume minimums
Steady, all-day dashboard load Can add up; compare with capacity pricing Predictable: compute stays busy, little idle tail

Match the meter to your query pattern, not to a benchmark. Before signing, have your analyst run the two queries above on your own job log. If the floors add a few percent and the busy windows are mostly idle, a bytes meter fits. If the windows are nearly full, a time meter with a short auto-suspend fits. That is your data warehouse cost comparison, on your own workload.

Which data warehouse fits which team

Which data warehouse fits which team

The same warehouse can work well for one team and badly for another. What decides it is who will run it and what they will run on it in the next 12–24 months:

Team What it mostly runs What to look for
Marketing-led analytics Daily dashboards on ad spend, sessions and orders; a few analysts The cloud your sources already land in; a hard cost stop; date-partitioned tables if the meter is bytes-scanned
Product analytics Event tables, funnels, cohorts over long history Event data is wide and long: partitioning and column discipline matter more than the vendor; on a time-based meter, size compute for the funnel queries
Data engineering-led Scheduled pipelines, heavy transformations, SLAs Compute you can size and isolate per job; open table formats if the lake in S3 or GCS is the core asset
Data science and AI Notebooks, Python, large historical sets The platform the data scientists already use; Iceberg or Delta tables shared with the SQL side

So what is the best data warehouse for product analytics? The one where your event data already lands, with tables laid out by date. On Google’s public GA4 sample, the same one-day question read 0.34 MB or 99 MB depending on layout alone (step 5 of the implementation guide linked above); no vendor choice recovers that.

Internal dashboards plus an external analytics feature, with workload isolation. Put the two on separate compute with separate limits. Snowflake’s documentation says each virtual warehouse is an independent compute cluster. On Athena, workgroups carry their own data-scanned limits; on Redshift Serverless and BigQuery, check how usage limits and reservations split by workload before you commit.

Data warehouse vs a serverless query engine for ad-hoc analytics on object storage. For occasional questions over files in S3, a serverless engine such as Athena queries them in place with no infrastructure to set up, per AWS’s documentation. Once the same queries feed daily dashboards, per-query minimums and scan charges add up, and a warehouse or shared Iceberg tables become the better deal. AWS Athena explained and data lakehouse architecture go deeper on both paths.

The warehouse stores the numbers; the model makes them trustworthy

The warehouse stores the numbers; the model makes them trustworthy

None of the five platforms knows that your spend feed stopped. On our demo data, every row-level check passed while ad spend ended five days before orders, so that week’s ROAS divided revenue by zero spend (step 7 of the implementation guide). That is the head of marketing’s problem from the opening, and no warehouse choice fixes it. It is fixed by a data model: agreed definitions of spend, orders and revenue, each owned by someone, with checks on every Data Mart run before the number reaches a slide.

OWOX Data Marts builds that layer on the warehouse you choose. It runs on all five storages compared here – Google BigQuery, Snowflake, AWS Redshift, AWS Athena and Databricks – so the warehouse decision and the trust decision stay separate. An analyst defines each Data Mart in SQL, with a description, an owner and its relationships to other Data Marts, and reports are built on those definitions rather than on raw tables. How to build a governed Data Mart library shows where to start: with the numbers people already argue about. You can try it on your own warehouse at OWOX Data Marts.

Your New Normal

Turn your data into decisions.

Governed data marts give you the clean foundation ML needs to actually work.

  • No AI hallucinations
  • Analyst-governed definitions
  • Every number traces to SQL
Get started free

FAQ

Frequently Asked Questions

How does a Data Mart layer help AI and advanced analytics?

An AI assistant or a model is only as reliable as the tables it reads. A Data Mart is a dataset an analyst defines in SQL, with a description, an owner and its relationships to other Data Marts. When AI tools and analysts read those definitions instead of raw connector tables, the same question resolves to the same agreed metric, and a stale or broken source is caught at the Data Mart rather than in someone's answer.

What does a data warehouse not do on its own?

A warehouse stores tables and runs queries. It does not decide what "spend" or "revenue" means, notice that a source stopped loading, or keep two reports consistent. In our demo data every row-level check passed while ad spend ended five days before orders, so any ROAS for that week divided by zero spend. Definitions and checks on every Data Mart live in the data model you build on top.

How does the type of team change the warehouse choice?

Marketing-led teams should favour the cloud their sources already land in, a hard cost stop and date-partitioned tables. Product analytics teams need layout discipline for wide event tables. Data engineering teams want compute they can size and isolate per job, plus open table formats. Data science teams should pick the platform they already use and share Iceberg or Delta tables with the SQL side. In every case, match the billing meter to how the team queries.

What are the signs that an organization is ready for a data warehouse?

You are ready when the same question gets different answers from different tools, reports are rebuilt by hand from several exports, and someone can own the warehouse: write SQL, set a cost limit and check that sources keep loading. Without that owner, a warehouse becomes another place where numbers disagree. Budget for both the warehouse bill and the modelling work that makes its tables trustworthy.

Why build a governed Data Mart layer on top of the warehouse?

Because the warehouse decides where data lives and what queries cost, not whether anyone trusts the numbers. Governed Data Marts give each metric one definition and one owner, and reports are built on those definitions rather than raw tables. OWOX Data Marts runs on Google BigQuery, Snowflake, AWS Redshift, AWS Athena and Databricks, so the warehouse choice and the trust layer stay separate. See how to build a governed Data Mart library.

How do BigQuery, Snowflake, Redshift, Athena and Databricks compare?

By what they bill for. BigQuery on-demand and Athena charge for bytes scanned, with 10 MB minimums (per table and per query on BigQuery, per query on Athena). Snowflake credits, Redshift RPU-hours and Databricks DBUs charge for compute time, and Snowflake and Redshift Serverless have 60-second minimums. Scan meters punish wide scans and many small tables; time meters punish idle compute and frequent resumes. Pick the meter that matches your query pattern, per vendor pages read in October 2026.

What does a cloud data warehouse do in an analytics stack?

It stores your tables in one place, runs the SQL that joins and aggregates them, and serves the results to dashboards, spreadsheets and analysts. It also sets your cost model: some warehouses bill for bytes scanned, others for compute time. What it does not do is define metrics or check that every source is fresh; that belongs to the data model and Data Marts built on top of it.

How do I know if my analytics team needs a data warehouse?

If your weekly reports mean pulling exports from several ad platforms, a shop and an analytics tool and reconciling them by hand, you need one place where those tables can be joined. Other signs: reports that disagree on the same metric, spreadsheets that hit their limits, and questions that cross channels. A warehouse makes the join possible; a data model on top makes the answer consistent.

Who wrote this

Ievgen Krasovytskyi

Ievgen Krasovytskyi · Head of Marketing

Ievgen Krasovytskyi is the Head of Marketing at OWOX, leading strategy across content, SEO, product marketing, and AI-powered automation. With deep expertise in analytics infrastructure, data warehouses, and marketing technology, he builds systems that connect marketing performance to business outcomes. Ievgen writes about SaaS growth, analytics workflows, and the future of AI in marketing operations.