{"id":10470,"date":"2026-09-19T07:20:00","date_gmt":"2026-09-19T05:20:00","guid":{"rendered":"https:\/\/www.lukaswojcik.com\/blog\/?p=10470"},"modified":"2026-09-09T17:09:45","modified_gmt":"2026-09-09T15:09:45","slug":"bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads","status":"publish","type":"post","link":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/","title":{"rendered":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run"},"content":{"rendered":"<p>The GA4 export is charged by the byte, and the byte count has almost nothing to do with the answer. A query returning forty rows and a query returning four million can read exactly the same amount, because what is billed is what had to be opened on the way &#8211; not what came back at the end.<\/p>\n<p>Two details decide it: how many of the daily tables the engine has to open, and how many columns it has to read inside them. Both are settled before a single row is produced, and both can be read off in advance.<\/p>\n<figure class=\"lw-diagram\">\n<img decoding=\"async\" src=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/diagrams\/partitionen-lesen-en.png\" width=\"1120\" height=\"580\" loading=\"lazy\" alt=\"Ninety tiles for ninety daily tables: with a _TABLE_SUFFIX filter thirty-one are lit, with an event_date filter all ninety are lit\"><figcaption>The same month, the same rows, the same result. Only the filter is written differently.<\/figcaption><\/figure>\n<h2>Reading Is Billed, Returning Is Free<\/h2>\n<p>The most expensive misunderstanding in this area is <code>LIMIT<\/code>. A limit is applied after the data has been read; it caps the result set and changes the cost by nothing at all. The same is true of <code>ORDER BY<\/code> and of anything else that happens once the rows exist.<\/p>\n<p>Which means the habit of exploring with <code>SELECT * ... LIMIT 10<\/code> &#8211; reasonable in almost every other database &#8211; is the most expensive way to look at a GA4 export. Ten rows of every column across every table in the wildcard is a full scan with a small window at the end.<\/p>\n<h2>Why event_date Does Not Prune Anything<\/h2>\n<p>The daily tables are addressed by a wildcard, and <code>_TABLE_SUFFIX<\/code> is the part of the table name that follows it. Filtering on it selects tables, and selection happens before reading &#8211; the engine simply never opens the rest.<\/p>\n<p><code>event_date<\/code> looks like it does the same thing and does the opposite. It is a column inside every table, so to find out whether a table contains matching rows, the table has to be opened and the column read. The filter is applied correctly, the result is identical, and the bill covers the whole wildcard.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code># prunes: the suffix is part of the name\nWHERE _TABLE_SUFFIX BETWEEN '20260801' AND '20260831'\n\n# does not prune: the column lives inside the tables\nWHERE event_date BETWEEN '20260801' AND '20260831'\n\n# both return the same rows<\/code><\/pre>\n<p>The same logic explains why the wildcard also matches <code>events_intraday_*<\/code> and why the suffix filter excludes it: <code>intraday_<\/code> sorts after any eight-digit date, so a range ending in a date leaves it outside. That is a side effect worth knowing rather than relying on &#8211; for the current day, the intraday table is queried on purpose and separately.<\/p>\n<h2>Columns Are the Second Lever<\/h2>\n<p>Within the tables that do get opened, the cost is the sum of the columns the query names. This is where the export&#8217;s shape matters: <code>event_params<\/code> is one nested column holding every parameter of every event, and a query that pulls a single parameter out of it reads the whole column.<\/p>\n<p>There is no way to read only <code>page_location<\/code> from inside that array. Which is not an argument against using it &#8211; it is an argument for naming columns explicitly rather than reaching for <code>SELECT *<\/code>, because the columns that are genuinely large are exactly the ones nobody needs: <code>user_properties<\/code>, <code>items<\/code>, <code>collected_traffic_source<\/code> and the device and geo structures.<\/p>\n<h2>What Each Measure Actually Changes<\/h2>\n<table style=\"width:100%;border-collapse:collapse\">\n<thead>\n<tr>\n<th style=\"vertical-align:top\">Measure<\/th>\n<th>Effect on bytes read<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\"><code>_TABLE_SUFFIX<\/code> instead of <code>event_date<\/code><\/td>\n<td>from every table in the dataset down to the ones in range<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\">naming columns instead of <code>SELECT *<\/code><\/td>\n<td>proportional &#8211; often the largest single saving<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\"><code>LIMIT 100<\/code><\/td>\n<td>none<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\">a filter on an event parameter<\/td>\n<td>none &#8211; <code>event_params<\/code> is read whole either way<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\">a filter on <code>event_name<\/code><\/td>\n<td>depends on how the tables are clustered &#8211; the dry run says<\/td>\n<\/tr>\n<tr>\n<td style=\"white-space:nowrap;vertical-align:top\">a slim table written once per day<\/td>\n<td>a fraction, permanently, for every query that follows<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The clustering row is deliberately not answered here. Whether a filter on <code>event_name<\/code> reduces bytes depends on the dataset, and guessing about it is unnecessary when the exact answer is one keystroke away.<\/p>\n<h2>The Dry Run Is Free and Exact<\/h2>\n<p>BigQuery computes the byte estimate from table metadata without executing anything, which makes it both free and precise. The editor shows it in the corner before the query is sent; the command line has the same thing as a flag.<\/p>\n<pre class=\"wp-block-kevinbatdorf-code-block-pro\"><code>bq query --use_legacy_sql=false --dry_run 'SELECT ...'\n\nQuery successfully validated.\nAssuming the tables are not modified,\nthis query will process 41,203,847,552 bytes of data.<\/code><\/pre>\n<p>Forty-one gigabytes is a number a decision can rest on. Running the query first and finding out afterwards is the same information at a worse moment, and the difference between the two habits is one line in front of the statement.<\/p>\n<h2>What Repeats Belongs in a Narrow Table<\/h2>\n<p>The last lever is structural rather than syntactic. An analysis that runs every morning against ninety days re-reads eighty-nine days that have not changed since yesterday.<\/p>\n<p>A scheduled query that writes the handful of fields actually used into its own table, once per day, turns that into reading one day and then querying something small. The daily job costs what one day costs; everything downstream costs a fraction of what it did. It is the same trick as a materialised view and worth reaching for as soon as a query has been run by hand three times.<\/p>\n<div class=\"lw-quellen\">\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/cloud.google.com\/bigquery\/pricing\" target=\"_blank\" rel=\"noopener noreferrer\">BigQuery pricing<\/a><\/li>\n<li><a href=\"https:\/\/developers.google.com\/analytics\/devguides\/collection\/ga4\" target=\"_blank\" rel=\"noopener noreferrer\">Google Analytics 4 developer guide<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>BigQuery bills the bytes it reads, not the rows it returns. Which tables are opened and which columns are touched is decided by two details, and both are visible before the query is sent.<\/p>\n","protected":false},"author":1,"featured_media":15182,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[91333,91258],"class_list":["post-10470","post","type-post","status-publish","format-standard","hentry","category-digital-analytics","tag-bigquery","tag-google-analytics-4"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog<\/title>\n<meta name=\"description\" content=\"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog\" \/>\n<meta property=\"og:description\" content=\"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/\" \/>\n<meta property=\"og:site_name\" content=\"Lukas Wojcik - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-09-19T05:20:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Lukas Wojcik\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lukas Wojcik\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/\"},\"author\":{\"name\":\"Lukas Wojcik\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"headline\":\"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run\",\"datePublished\":\"2026-09-19T05:20:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/\"},\"wordCount\":804,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-10470-what-a-query-costs-before-it-runs-n.png\",\"keywords\":[\"BigQuery\",\"Google Analytics 4\"],\"articleSection\":[\"Digital Analytics\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/\",\"name\":\"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-10470-what-a-query-costs-before-it-runs-n.png\",\"datePublished\":\"2026-09-19T05:20:00+00:00\",\"description\":\"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-10470-what-a-query-costs-before-it-runs-n.png\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/hero-10470-what-a-query-costs-before-it-runs-n.png\",\"width\":1200,\"height\":630,\"caption\":\"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/en\\\/digital-analytics\\\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/\",\"name\":\"Lukas Wojcik - Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/#\\\/schema\\\/person\\\/895f7604f9b6b71aad9bba33af28d0f9\",\"name\":\"Lukas Wojcik\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"url\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"contentUrl\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\",\"width\":424,\"height\":636,\"caption\":\"Lukas Wojcik\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/lw-x2.jpg\"},\"sameAs\":[\"https:\\\/\\\/www.lukaswojcik.com\\\/blog\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog","description":"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/","og_locale":"en_US","og_type":"article","og_title":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog","og_description":"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.","og_url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/","og_site_name":"Lukas Wojcik - Blog","article_published_time":"2026-09-19T05:20:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png","type":"image\/png"}],"author":"Lukas Wojcik","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lukas Wojcik","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#article","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/"},"author":{"name":"Lukas Wojcik","@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"headline":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run","datePublished":"2026-09-19T05:20:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/"},"wordCount":804,"commentCount":0,"publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png","keywords":["BigQuery","Google Analytics 4"],"articleSection":["Digital Analytics"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/","url":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/","name":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run - Lukas Wojcik - Blog","isPartOf":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#primaryimage"},"image":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#primaryimage"},"thumbnailUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png","datePublished":"2026-09-19T05:20:00+00:00","description":"Why LIMIT does not make a query cheaper, why event_date does not prune tables, and how a free dry run answers the cost question exactly.","breadcrumb":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#primaryimage","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/09\/hero-10470-what-a-query-costs-before-it-runs-n.png","width":1200,"height":630,"caption":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run"},{"@type":"BreadcrumbList","@id":"https:\/\/www.lukaswojcik.com\/blog\/en\/digital-analytics\/bigquery-costs-for-the-ga4-export-which-tables-and-columns-a-query-reads\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.lukaswojcik.com\/blog\/"},{"@type":"ListItem","position":2,"name":"BigQuery Costs for the GA4 Export: Which Tables and Columns a Query Reads and the Free Dry Run"}]},{"@type":"WebSite","@id":"https:\/\/www.lukaswojcik.com\/blog\/#website","url":"https:\/\/www.lukaswojcik.com\/blog\/","name":"Lukas Wojcik - Blog","description":"","publisher":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.lukaswojcik.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.lukaswojcik.com\/blog\/#\/schema\/person\/895f7604f9b6b71aad9bba33af28d0f9","name":"Lukas Wojcik","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","url":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","contentUrl":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg","width":424,"height":636,"caption":"Lukas Wojcik"},"logo":{"@id":"https:\/\/www.lukaswojcik.com\/blog\/wp-content\/uploads\/2026\/07\/lw-x2.jpg"},"sameAs":["https:\/\/www.lukaswojcik.com\/blog"]}]}},"_links":{"self":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/10470","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/comments?post=10470"}],"version-history":[{"count":4,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/10470\/revisions"}],"predecessor-version":[{"id":16867,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/posts\/10470\/revisions\/16867"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media\/15182"}],"wp:attachment":[{"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/media?parent=10470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/categories?post=10470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lukaswojcik.com\/blog\/wp-json\/wp\/v2\/tags?post=10470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}