<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Bruin - Unified Analytics Platform]]></title><description><![CDATA[Bruin is a unified analytics platform that brings together transformation, data quality, observability and governance.]]></description><link>https://blog.getbruin.com</link><image><url>https://substackcdn.com/image/fetch/$s_!Wcbc!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d316914-a075-4284-90ec-3841c25a349f_1280x1280.png</url><title>Bruin - Unified Analytics Platform</title><link>https://blog.getbruin.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 10 Apr 2026 19:43:16 GMT</lastBuildDate><atom:link href="https://blog.getbruin.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Bruin Data Limited]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[bruindata@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[bruindata@substack.com]]></itunes:email><itunes:name><![CDATA[Burak Karakan]]></itunes:name></itunes:owner><itunes:author><![CDATA[Burak Karakan]]></itunes:author><googleplay:owner><![CDATA[bruindata@substack.com]]></googleplay:owner><googleplay:email><![CDATA[bruindata@substack.com]]></googleplay:email><googleplay:author><![CDATA[Burak Karakan]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[🚀 Launch: Bruin CLI]]></title><description><![CDATA[Bruin CLI is an open-source data pipeline tool built with Go, with built-in data ingestion, transformation, and data quality checks.]]></description><link>https://blog.getbruin.com/p/launch-bruin-cli</link><guid isPermaLink="false">https://blog.getbruin.com/p/launch-bruin-cli</guid><dc:creator><![CDATA[Burak Karakan]]></dc:creator><pubDate>Fri, 20 Dec 2024 11:51:03 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 424w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 848w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 1272w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 1456w" sizes="100vw"><img src="https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D" width="1200" height="801.6" data-attrs="{&quot;src&quot;:&quot;https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:2004,&quot;width&quot;:3000,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;worm's eye-view photography of ceiling&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-large" alt="worm's eye-view photography of ceiling" title="worm's eye-view photography of ceiling" srcset="https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 424w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 848w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 1272w, https://images.unsplash.com/photo-1488229297570-58520851e868?fm=jpg&amp;q=60&amp;w=3000&amp;ixlib=rb-4.0.3&amp;ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Over the past few years, the data world has convinced itself that it needs many different tools to extract insights:</p><ul><li><p>one tool to ingest data</p></li><li><p>another one to transform it</p></li><li><p>another one to check the quality</p></li><li><p>another one to orchestrate them all</p></li><li><p>another one for cataloging</p></li><li><p>another one for governance</p></li></ul><p>The result? A very fragile, expensive, and rigid infrastructure with a terrible experience. Teams have to build a lot of glue between these systems, and try to get different parts of these systems to talk to each other while trying to onboard analytical teams on them.</p><p>Does it work? No. </p><p>Are we ready to have that conversation? I hope so.</p><h1>Obsessing over impact</h1><p>The engineering work behind building a ticking machine is very satisfying: small pieces that each do their part, and they work like a clock. It feels like an engineering marvel:</p><blockquote><p><em>It is simple: you push code to the main branch, the backend automatically pulls the branch, pulls the DAGs and uploads them to S3. The sync sidecars on Airflow containers automatically pull from S3, which will then update the DAGs. When the DAG runs, for data ingestion jobs it will connect to our Airbyte deployment and trigger the ingestion from Airflow, then we create a sensor that waits until the ingestion is done. Then we connect to dbt Cloud to initiate some parts of the transformation jobs from the analytical team, if anything fails Airflow connects to our notification system to find the right team if they are defined on the catalog, if not we check our AD users and try to find a matching org to send a notification. Once the transformation is done then we execute our custom Python operators that do X and Y, then we provision a pod in our Kubernetes cluster to run quality checks. Our Kafka sinks are ingesting CDC data from the internal Postgres with Debezium in the meantime, then load them to the data lake in Parquet format, then we register them as Glue tables so that they can be queried, then the sensors in our Airflow clusters keep track of these states to run SQL transformations with the internal framework, and&#8230;</em></p></blockquote><p>Sounds ridiculous, doesn&#8217;t it? It certainly does to me, whereas this is a very common response when we ask engineering teams what their data infrastructure looks like. The joy they get out of building a house of cards is far more important than the business impact that is being delivered. In the meantime, the analytics teams, data analysts, data scientists, and the business teams are waiting for their questions to be answered, trying to understand why it takes 6 weeks to get a new chart on their sales dashboard.</p><p>I am not sure if this is due to <a href="https://www.ycombinator.com/library/LC-what-is-zirp-and-how-did-it-poison-startups">ZIRP</a> or not, but it is pretty easy to spot organizations where highly inefficient engineering teams, coupled with engineering leaders who don&#8217;t know what their teams are doing, are ruling the game, where the people that create real value with data is left alone. They have to jump through a billion different tools, trying to figure out why their dashboard didn&#8217;t update, and waiting for a response to their ticket from the central data team.</p><p>These are data analysts in business teams, a growth hacker running marketing campaigns over 5 different platforms, or an all-rounder data scientist who is trying to predict LTV. They are trying to create a real impact, but their progress is being heavily hindered by the internal <em>toys</em>.</p><p>We are building Bruin for these people: simpler data tooling for impact-obsessed teams.</p><h1>Bruin CLI &amp; VS Code Extension</h1><p>Bruin CLI is an end-to-end data pipeline tool that brings together data ingestion, data transformation with SQL and Python, and data quality in a single framework.</p><p><a href="https://github.com/bruin-data/bruin">https://github.com/bruin-data/bruin</a></p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;9a9e9aa0-eaea-47aa-8195-9b48efdb3dc5&quot;,&quot;duration&quot;:null}"></div><p>Bruin is batteries included:</p><ul><li><p>&#128229; ingest data with <a href="https://github.com/bruin-data/ingestr">ingestr</a> / Python</p></li><li><p>&#10024; run SQL &amp; Python transformations on <a href="https://bruin-data.github.io/bruin/#supported-platforms">many platforms</a></p></li><li><p>&#128208; table/view <a href="https://bruin-data.github.io/bruin/assets/materialization.html">materializations</a>, incremental tables</p></li><li><p>&#128013; run Python in isolated environments using <a href="https://github.com/astral-sh/uv">uv</a></p></li><li><p>&#128133; built-in data quality checks</p></li><li><p>&#128640; Jinja templating to avoid repetition</p></li><li><p>&#9989; validate pipelines end-to-end via dry-run</p></li><li><p>&#128119; run on your local machine, an EC2 instance, or <a href="https://bruin-data.github.io/bruin/cicd/github-action.html">GitHub Actions</a></p></li><li><p>&#128274; secrets injection via environment variables</p></li><li><p><a href="https://bruin-data.github.io/bruin/vscode-extension/overview.html">VS Code extension</a> for a better developer experience</p></li><li><p>&#128230; <a href="https://bruin-data.github.io/bruin/getting-started/introduction/installation.html">easy to install</a> and use</p></li></ul><p>This means using Bruin, teams can build end-to-end workflows without having to resort to a bunch of different tools. It is extensible enough with the usage of SQL and Python, while also guiding the users through its opinionated approach to build maintainable data pipelines.</p><h2>Code-first &amp; UI supported</h2><p>One of the things that accompany Bruin CLI is our open-source <a href="https://bruin-data.github.io/bruin/vscode-extension/overview.html">Visual Studio Code extension</a>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mx2d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mx2d!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 424w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 848w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 1272w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mx2d!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif" width="1446" height="732" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:732,&quot;width&quot;:1446,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Bruin Action Buttons&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Bruin Action Buttons" title="Bruin Action Buttons" srcset="https://substackcdn.com/image/fetch/$s_!mx2d!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 424w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 848w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 1272w, https://substackcdn.com/image/fetch/$s_!mx2d!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4066bc5c-734e-4786-858d-e22b5db31f18_1446x732.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The extension does a few stuff that makes it pretty unique:</p><ul><li><p>While everything in Bruin is driven with code, the extension adds a UI layer on top of it, which means you get:</p><ul><li><p>visual documentation</p></li><li><p>rendered queries</p></li><li><p>column &amp; quality checks</p></li><li><p>lineage</p></li><li><p>the ability to validate code &amp; run backfills</p></li><li><p>syntax highlighting</p></li></ul></li><li><p>everything happens locally, which means there are no external servers or systems that can access any of your data</p></li><li><p>extension visualizes a lot of the configuration options, which makes it trivial to run backfills, validations, and more.</p></li></ul><p>This is a good example of our <a href="https://bruin-data.github.io/bruin/getting-started/design-principles.html">design principles</a>: everything is version-controlled, while also giving a better experience through a thoughtful UI.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4fK3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4fK3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 424w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 848w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 1272w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4fK3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png" width="1406" height="836" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:836,&quot;width&quot;:1406,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Lineage Overview&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Lineage Overview" title="Lineage Overview" srcset="https://substackcdn.com/image/fetch/$s_!4fK3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 424w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 848w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 1272w, https://substackcdn.com/image/fetch/$s_!4fK3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f05c1d7-e8eb-4bf5-908f-db961f5d20e7_1406x836.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Bruin VS Code Extension can also display data lineage across all of your assets.</figcaption></figure></div><p>The extension is a first-class citizen of the Bruin ecosystem, and we intend to expand its functionality further to make it the easiest platform to build data workloads out there.</p><h2>Supported Platforms</h2><p>Bruin supports many of the cloud data platforms out of the box at the launch:</p><ul><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/athena">AWS Athena</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/databricks">Databricks</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/duckdb">DuckDB</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/bigquery">Google BigQuery</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/mssql">Microsoft SQL Server</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/postgres">Postgres</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/redshift">Redshift</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/snowflake">Snowflake</a></strong></p></li><li><p><strong><a href="https://bruin-data.github.io/bruin/platforms/synapse">Synapse</a></strong></p></li></ul><p>The list of platforms we support will grow more and more over time. We are always looking forward to hearing community feedback on these, so feel free to share your thoughts with us in <a href="https://join.slack.com/t/bruindatacommunity/shared_invite/zt-2dl2i8foy-bVsuMUauHeN9M2laVm3ZVg">our Slack community</a>.</p><h1>Bruin Cloud</h1><p>We are building Bruin for those obsessed with impact. You can go from zero to full data pipelines in minutes, and we are dedicated to making this experience even bigger. Using all of our open-source tooling you can build and run all of your data workloads locally, on <a href="https://bruin-data.github.io/bruin/cicd/github-action.html">GitHub Actions</a>, in Airflow, or anywhere else.</p><p>While we do believe there are many useful deployment options of Bruin CLI across different infrastructures, we are also obsessed with building the best managed-experience for building and running Bruin workloads on production. That&#8217;s why we are building <a href="https://getbruin.com">Bruin Cloud</a>:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oipz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oipz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 424w, https://substackcdn.com/image/fetch/$s_!oipz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 848w, https://substackcdn.com/image/fetch/$s_!oipz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 1272w, https://substackcdn.com/image/fetch/$s_!oipz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oipz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png" width="1456" height="799" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:799,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Lineage view on Bruin Cloud&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Lineage view on Bruin Cloud" title="Lineage view on Bruin Cloud" srcset="https://substackcdn.com/image/fetch/$s_!oipz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 424w, https://substackcdn.com/image/fetch/$s_!oipz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 848w, https://substackcdn.com/image/fetch/$s_!oipz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 1272w, https://substackcdn.com/image/fetch/$s_!oipz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc8d40ff-c77b-4f94-a8cd-f158d7cbba11_2432x1334.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It has quite a few niceties:</p><ul><li><p>managed environment for ingestion, transformation, and ML workloads</p></li><li><p>column-level lineage</p></li><li><p>governance &amp; cost reporting</p></li><li><p>team management</p></li><li><p>cross-pipeline dependencies</p></li><li><p>multi-repo &#8220;mesh&#8221;</p></li></ul><p>and quite a few more. Feel free to <a href="https://getbruin.com">drop your email</a> to get a demo.</p><h1>Share your thoughts</h1><p>We are very excited to share Bruin CLI &amp; VSCode Extension with the world, and we would love to hear from the community. We&#8217;d appreciate if you shared your thoughts on what would make Bruin more useful for your needs.</p><p><a href="https://github.com/bruin-data/bruin">https://github.com/bruin-data/bruin</a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UxnU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UxnU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UxnU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg" width="1280" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UxnU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 424w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 848w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!UxnU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620c1a5b-6af0-432f-8f98-cfb717ef51f3_1280x640.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[No-code data platform is a lie]]></title><description><![CDATA[The trade-offs between the different solutions, and graduating to a mature data organization.]]></description><link>https://blog.getbruin.com/p/no-code-data-platform-is-a-lie</link><guid isPermaLink="false">https://blog.getbruin.com/p/no-code-data-platform-is-a-lie</guid><dc:creator><![CDATA[Burak Karakan]]></dc:creator><pubDate>Tue, 01 Oct 2024 09:31:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!C0zC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!C0zC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!C0zC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 424w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 848w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!C0zC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png" width="728" height="408" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:816,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:7208133,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!C0zC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 424w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 848w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 1272w, https://substackcdn.com/image/fetch/$s_!C0zC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff334ed29-6e69-42e2-9c76-a9675dcd4a2a_2912x1632.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We often see data teams considering no-code solutions as a potential option in the early days of the journey. The whole thing sounds pretty nice on paper:</p><ul><li><p>a drag-and-drop UI to build workflows</p></li><li><p>visual representation of the pipelines</p></li><li><p>no need to install anything</p></li><li><p>even business users can build data products</p></li></ul><p>These are very exciting at their core, and quite understandably many teams take these promises for granted. My intention with this article is not to say they are not the right solution for certain problems, but to offer another perspective for growing teams.</p><h1>To be locked in or not to be locked in</h1><p>It all starts the same: you have a new platform, it has a beautiful UI, you can do the first steps without writing a single line of code, and you feel like you are making progress. In fact, you <em>are</em> making progress, but with some costs associated with it.</p><p>The UI-driven workflow tools will have certain ways of working, primarily driven through their UI, duh, and their own workflows. While clicking around in the UI has its benefits, especially when getting started, there&#8217;s a reason these tools ask you to do that. </p><ul><li><p>The workflows you build there will stay with them forever unless you are ready to do the same steps in another tool, which is often not feasible after a certain stage.</p></li><li><p>The ways of working cannot be extended other than the abilities of the platform, which means as you grow, you start hitting more and more of the rough edges and the lack of flexibility the business requires.</p></li><li><p>Moving away from these platforms require a significant effort and investment, which means in the best case you are left with a subpar solution, in the worst case the platform can decide to charge you 10x more.</p></li></ul><p>The inability to move away is the one that scared me the most always, let&#8217;s dive into that a bit more.</p><h2>The inability to move away</h2><p>Businesses change. Team structures change. Individuals change. Problems change. The tools, also, need to change.</p><p>Let&#8217;s think of the following scenario where we used a no-code data pipeline tool:</p><ul><li><p>Acme Corp, where Laura (Data Architect), Michael (Chief Data Officer), and <strong>Nina</strong> (Marketing Analyst) work, has a rather simple setup:</p><ul><li><p>They ingest data from Facebook Ads, Google Ads, and Shopify.</p></li><li><p>They do some data cleaning.</p></li><li><p>They put them in a report on PowerBI.</p></li></ul></li></ul><p>Simple enough, nice.</p><h3>Step 1: Initial implementation</h3><p>Laura, the Data Architect, was tasked with integrating a new data source, Amazon Marketplace, into their existing no-code data pipeline tool. The tool was already ingesting data from Facebook Ads, Google Ads, and Shopify, with basic data cleaning and reporting set up in PowerBI. Laura began by connecting the Amazon Marketplace data source to the no-code tool. The initial setup seemed straightforward, and the data started flowing into the pipeline.</p><h3>Step 2: First struggles</h3><p>As the marketing team ramped up their campaigns, the volume of data from all sources increased significantly. The no-code tool began to struggle with the increased load, leading to slower data processing times and delays in report generation. What used to take 4 minutes to build now takes 3.5 hours to process data every morning, increasing every day.</p><h3>Step 3: Michael&#8217;s business questions</h3><p>Michael, the Chief Data Officer, requested more complex data transformations to better analyze customer behavior across all platforms. He needed to understand cross-channel attribution, customer lifetime value, and segment performance more accurately to optimize marketing spend and improve customer targeting. These transformations required advanced calculations and custom logic that the no-code tool could not handle efficiently.</p><p>To address this, Nina decided to run the complex logic in Python. However, the no-code platform did not support running custom scripts natively. Nina had to collaborate with a software engineer to deploy the Python scripts on AWS Lambda. This solution allowed the custom logic to be executed, but it added an extra layer of complexity and dependency outside the no-code tool.</p><h3><strong>Step 4: Expanding Data Sources and Integrations</strong> </h3><p>As the business continued to grow, Michael saw the need to integrate additional data sources, including third-party customer data platforms (CDPs) and external market intelligence services. These sources were crucial for gaining deeper insights into customer behavior and staying competitive in the market.</p><p>However, the no-code tool struggled to handle the growing number of integrations. It lacked the flexibility to connect seamlessly with the wide variety of APIs and data formats required by these new sources. Laura had to write custom scripts to bridge the gaps, often relying on external services like AWS Lambda and AWS Glue for data transformation and ETL processes.</p><p>To complicate matters further, the no-code tool's interface became increasingly cluttered and difficult to manage as more data sources were added. This led to frequent errors and delays in the data pipeline, requiring constant troubleshooting and maintenance.</p><h3>Step 5: Data Governance</h3><p>As the company expanded into new markets, Michael needed to ensure that their data processing adhered to strict data governance and compliance requirements, such as GDPR and CCPA. The no-code tool offered limited features for managing data lineage, auditing, and encryption, making it difficult to maintain compliance across multiple jurisdictions.</p><p>Laura had to manually implement additional security measures and auditing processes outside the no-code platform, using a combination of AWS services and custom scripts. This made the pipeline even more complex and introduced new points of failure.</p><h3>Outcome</h3><p>As the data requirements became more complex, and the need for robust integrations, accurate segmentation, and compliance grew, the limitations of the no-code tool became a significant bottleneck. The team, including Nina, spent more time managing and troubleshooting the pipeline than deriving insights from the data.</p><div><hr></div><p>The story is far more common than you would think. We have spoken with hundreds of companies, and all of those that adopted a no-code solution for their data infrastructure had also gone through -or were going through- an offboarding process.</p><h1>Flexibility: yes-code</h1><p>We build software because we can shape it as we want, hence the &#8220;soft&#8221; in software. The things we dream of can turn into reality in skillful hands, and building data workloads is not an exception. </p><p>Well, except, if you are using a no-code tool.</p><p>The no-code platforms are optimized for 80% of the workloads: they take care of the common scenarios in a, supposedly, easy way, and you can build the remaining 20% yourself. </p><p>This would work really well if the effort for that 20% scaled in a way where it complements the no-code part. However, in reality, the additional effort to build that custom part requires a significant investment that is pretty much rebuilding the whole thing in itself.</p><p></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nL3h!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nL3h!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 424w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 848w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 1272w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nL3h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png" width="1456" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144596,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nL3h!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 424w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 848w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 1272w, https://substackcdn.com/image/fetch/$s_!nL3h!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0645edef-6fe0-48be-bb5c-49340d398354_2651x728.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">I wish it would add up to 100%, it doesn&#8217;t.</figcaption></figure></div><p>Why do we have to rebuild things again if I have my no-code platform already? Glad you asked.</p><p>There are quite a few questions that need to be answered for that custom part of your data workloads:</p><ul><li><p>Where do I run these workloads?</p></li><li><p>How do I deploy them?</p></li><li><p>How do I schedule them?</p></li><li><p>How do I get them to work with the existing parts of the no-code pipelines?</p></li><li><p>How do I get notified of failures?</p></li><li><p>How do I retry failures?</p></li></ul><p>So on and so forth&#8230;</p><p>Without having a clear strategy on how to build and run custom data workloads, i.e. your bespoke Python scripts, building and deploying the first custom stuff outside of the no-code platform means having to figure out all of these questions. This means setting up orchestration from scratch, figuring out a way to ingest data to another location, building a framework around all of these, deploying them somewhere, building notifications, etc.</p><h1>Governance? What is that?</h1><p>Data governance, even though it sounds too-enterprisey these days, is a concern that hits every company eventually. It doesn&#8217;t have to be a complicated process, data governance concerns start even in very early stages:</p><ul><li><p>What data do I store?</p></li><li><p>Where do I store that data?</p></li><li><p>Who can access that data?</p></li><li><p>Do I comply with the regulations?</p></li><li><p>How much do I pay for this data?</p></li><li><p>How often is it being used?</p></li><li><p>What&#8217;s the ROI of a specific piece of data?</p></li></ul><p>The list grows from here on. Some of these questions might be easy to answer, whereas some others are more challenging. In order to be able to answer these questions in an accurate and timely way, you will often need to access the raw source of the data workloads, a.k.a &#8220;the code&#8221;, and guess who doesn&#8217;t have &#8220;the code&#8221;? The no-code platform.</p><p>This simply means the governance questions are answered based on what&#8217;s available on the platform, rather than giving you access to the underlying code. Even if you had the engineering ability to analyze the underlying SQL queries yourself, you won&#8217;t be able to, since you don&#8217;t have the code available to you.</p><h1>Go for the code, always</h1><p>In the end, there&#8217;s a fundamental disagreement between myself and no-code tools: I think teams should not be deprived of their freedom when it comes to their own data.</p><p>The code is the representation fo the real world. It gives you the flexibility to represent all the intricate complexities of your business. There&#8217;s never going to be a piece of off-the-shelf software that can cover every complexity of your business, which means you might as well start the right way: go for the code.</p><p>This is even more significant when it comes to your data workloads: data grows faster than the software stack, which means the complexities and the processing of the data will grow faster as well, which means you need that freedom more with your data workloads than ever.</p><p>That&#8217;s why we are building <a href="https://getbruin.com">Bruin</a>, it is the platform that I wished always existed: just let me write the code for my business logic and take care of the rest. In practice, this means you write your data transformation code, you version-control it, you add quality checks, everything is in code, and the platform takes care of the generic problems such as running them at the right time and in the right order, reporting executions, notifying you on failures, and more.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://getbruin.com&quot;,&quot;text&quot;:&quot;Get Started with Bruin&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://getbruin.com"><span>Get Started with Bruin</span></a></p><p>There are already a lot of teams that have been bitten by the pains of the no-code tools, and I am very excited for a future where this doesn&#8217;t happen anymore.</p>]]></content:encoded></item><item><title><![CDATA[Summarising User Behaviour: Users Daily Table]]></title><description><![CDATA[Data Modeling for Google Analytics 4 and Firebase Analytics]]></description><link>https://blog.getbruin.com/p/summarising-user-behaviour-users</link><guid isPermaLink="false">https://blog.getbruin.com/p/summarising-user-behaviour-users</guid><dc:creator><![CDATA[Sabri Karagonen]]></dc:creator><pubDate>Mon, 03 Jun 2024 10:23:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f1eb41c1-8f25-49f6-8ba4-6db6a841e851_1792x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7-w2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7-w2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7-w2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:160188,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7-w2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!7-w2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F94aafaff-7aaf-44c9-9223-cf332843b9f3_1792x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It&#8217;s the third blog post of Modeling Google Analytics &amp; Firebase Data. You can find the previous posts:</p><ol><li><p><a href="https://blog.getbruin.com/p/exporting-firebase-data-to-bigquery">Exporting Firebase Data to BigQuery</a></p></li><li><p><a href="http://Firebase Events Table">Firebase Events Table</a></p></li></ol><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.getbruin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Bruin - Unified Analytics Platform! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>A healthy Data Warehouse (DWH) consists of a balanced combination of aggregated data models and raw event data. Aggregated models help in several ways:</p><ul><li><p><strong>Lower compute costs</strong> by reducing the volume of data processed.</p></li><li><p><strong>Higher performance</strong> and faster queries due to the smaller dataset size.</p></li><li><p><strong>Simplified querying</strong> with embedded business metrics and facts.</p></li><li><p><strong>Consistent analysis</strong> by standardizing metrics and data cleaning.</p></li><li><p><strong>Easy feature calculation</strong> for ML pipelines</p></li></ul><p>Probably the most common data model in clickstream events is daily user aggregates regardless of business/industry since most of the dashboards are built on daily granularity. I like naming tables by the primary keys since it makes it more semantic. So I&#8217;ll call this table `users_daily`.</p><p>This table will contain 1 row for each active user on a specific day. At the end, it will include all the user metrics and attributes to help us understand the business. It&#8217;s very easy to create dashboards on top of this dashboard, so you&#8217;ll love it.</p><p>In the previous <a href="https://blog.getbruin.com/p/unnesting-firebase-events-table">article</a> we created an `events.events` table, so `users_daily` will be built on top of this table. Let&#8217;s start by having the most simple metrics of <a href="https://developers.google.com/analytics/bigquery/app-gaming-demo-dataset">Google Analytics Sample Gaming Project</a>. </p><p>The starter template is:</p><pre><code>SELECT
    user_pseudo_id,
    dt,
    --- attributes
    --- metrics
FROM events.events
WHERE -- data cleaning
GROUP BY 1,2</code></pre><p>In this query, you can use user_pseudo_id instead of user_id, but the main idea is we should never add any other columns to the group by. This way, we&#8217;ll ensure the primary key (PK) is consistent.</p><h3>Where</h3><p>This table contains only user activity data. So I recommend excluding the data not relevant to user activity. For example, Firebase triggers app_remove, os_update, app_clear_data, app_update and app_exception events even the app is not open. </p><p>Also, if a row doesn&#8217;t have a user_id, it doesn&#8217;t make sense to aggregate them either. Let&#8217;s exclude them, too.</p><p>So now, our query looks like:</p><pre><code>SELECT
    user_id,
    dt,
    --- attributes
    --- metrics
FROM events.events
WHERE 
    user_id is not null
    and event_name not in ("app_remove", "os_update", "app_clear_data", "app_update", "app_exception")
GROUP BY 1,2</code></pre><h3>Metrics</h3><p>Metrics are the aggregates that shows what users did within the day. The simplest way to obtain the main metrics is to count the main events. </p><p>When I query the table, I see the events as metric candidates:</p><pre><code>SELECT event_name, count(*) as cnt
FROM `bruin-blog-firebase-demo.events.events_json` 
WHERE event_name not in ("app_remove", "os_update", "app_clear_data", "app_update", "app_exception")
group by 1</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UT-4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UT-4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 424w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 848w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 1272w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UT-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png" width="418" height="500.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:760,&quot;resizeWidth&quot;:418,&quot;bytes&quot;:105358,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UT-4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 424w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 848w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 1272w, https://substackcdn.com/image/fetch/$s_!UT-4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4027bee4-5cf1-4382-b68e-f867a0612099_760x910.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jbSR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jbSR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 424w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 848w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 1272w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jbSR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png" width="410" height="463.94736842105266" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:860,&quot;width&quot;:760,&quot;resizeWidth&quot;:410,&quot;bytes&quot;:106752,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!jbSR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 424w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 848w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 1272w, https://substackcdn.com/image/fetch/$s_!jbSR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff7d3e1d4-d89e-43a5-80cd-a06638fc4d50_760x860.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><pre><code><code>SELECT
    user_id,
    dt,
    --- attributes
    --- metrics
    count(*) as event_cnt,

    -- app monetization metrics
    countif(event_name="ad_reward") as ad_reward_cnt,
    countif(event_name="in_app_purchase") as iap_cnt,

    -- app engagement metrics
    countif(event_name = "level_start") as level_start_cnt,
    countif(event_name = "level_end") as level_end_cnt,
    countif(event_name = "level_complete") as level_complete_cnt,
    countif(event_name = "level_fail") as level_fail_cnt,
    countif(event_name = "level_retry") as level_retry_cnt,
    countif(event_name = "level_start_quickplay") as level_start_quickplay_cnt,
    countif(event_name = "level_end_quickplay") as level_end_quickplay_cnt,
    countif(event_name = "level_complete_quickplay") as level_complete_quickplay_cnt,
    countif(event_name = "level_fail_quickplay") as level_fail_quickplay_cnt,
    countif(event_name = "level_retry_quickplay") as level_retry_quickplay_cnt,
    countif(event_name = "level_up") as level_up_cnt,
    countif(event_name = "challenge_a_friend") as challenge_a_friend_cnt,
    countif(event_name = "challenge_accepted") as challenge_accepted_cnt,
    countif(event_name = "no_more_extra_steps") as no_more_extra_steps_cnt,
    countif(event_name = "use_extra_steps") as use_extra_steps_cnt,
    countif(event_name = "select_content") as select_content_cnt,
    
FROM events.events
WHERE 
    user_id is not null
    and event_name not in ("app_remove", "os_update", "app_clear_data", "app_update", "app_exception")
GROUP BY 1,2</code></code></pre><p>As you can see, I tried to add all the relevant events to the summary table. This will help us to monitor the user behavior in the dashboards very quickly.</p><p>In the second iteration of the metrics, we will use parameters. This process requires a good understanding the events and their parameters. For example:</p><p>level events have these parameters:</p><pre><code>SELECT event_name, ep as event_params
FROM `bruin-blog-firebase-demo.events.events_json` 
WHERE event_name like "level%"</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LLH2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LLH2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 424w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 848w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 1272w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LLH2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png" width="1250" height="392" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:392,&quot;width&quot;:1250,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LLH2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 424w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 848w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 1272w, https://substackcdn.com/image/fetch/$s_!LLH2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59b92e1e-69c1-4b60-a0ad-948bfb29f419_1250x392.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By using these events, we can obtain the min&amp;max level played on that day. To do it, we can just add these to the query:</p><pre><code><code>SELECT
    user_id,
    dt,

    min(level) as min_level,
    max(level) as max_level,

FROM events.events
WHERE ...
GROUP BY 1,2</code></code></pre><p>Here, you should be very careful that the level parameter is not used in other levels in another context. If it&#8217;s used, you can filter your query for specific metrics:</p><pre><code><code>    min(if(event_name like 'level_%', level, null)) as min_level,
    max(if(event_name like 'level_%', level, null)) as max_level,
    min(if(event_name = 'level_complete', level, null)) as min_level_completed,
    max(if(event_name = 'level_complete', level, null)) as max_level_completed,</code></code></pre><p>Let&#8217;s inspect the <strong>in_app_purchase</strong> event to add the revenue to our table:</p><pre><code>SELECT event_name, event_params, event_value_in_usd
FROM `bruin-blog-firebase-demo.events.events_json` 
WHERE event_name = "in_app_purchase"</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8HMx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8HMx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 424w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 848w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 1272w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8HMx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png" width="1456" height="368" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:368,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131459,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8HMx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 424w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 848w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 1272w, https://substackcdn.com/image/fetch/$s_!8HMx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc96a66c8-8cee-4ff1-9627-1e63eaee3b43_1766x446.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As you can see, there are currency and price parameters. However, since they have different currencies, using it is impossible. To solve this problem, Google Analytics provides the `event_value_in_usd` field. Let&#8217;s add it to our metrics as well:</p><pre><code><code>    sum(if(event_name="in_app_purchase", event_value_in_usd, 0)) as iap_revenue</code></code></pre><p>After that point, I recommend learning the product very well, deciding on the metrics with product managers, and adding all of them to the users_daily table. The only exception is, for calculated metrics, I recommend you to do it on the BI layer.</p><p>For example, if you want to calculate <strong>win_rate</strong>, it&#8217;s better to add <strong>level_start_cnt</strong> and <strong>level_complete_cnt</strong> to this table. By using <strong>level_complete_cnt / level_start_cnt</strong>, you can easily calculate the win rate.</p><h3>Attributes</h3><p>Attributes are non-aggregatable information that provides additional details about the user, such as the user&#8217;s device brand, country, OS version, and platform. To summarize these attributes, I recommend using two different methods based on their types:</p><ol><li><p><strong>Dynamic Values</strong></p></li><li><p><strong>Static Values</strong></p></li></ol><p>Let&#8217;s start with the country attribute. A user can use your app in more than one country during a single day. For such dynamic values, it makes sense to capture the first and last values of the day. Country, os_version, app_version are examples of this group.</p><p>To get them, you can use min_by and max_by functions.</p><pre><code><code>SELECT
    user_id,
    dt,

    MIN_BY(country, ts) as first_country,
    MAX_BY(country, ts) as last_country,

FROM events.events
WHERE ...
GROUP BY 1,2</code></code></pre><p>Some of the values don&#8217;t change for a specific user id. For example, <strong>user_pseudo_id</strong> is assigned right after installing the app. If you are using <strong>user_pseudo_id</strong> as the primary key, we expect device <strong>platform</strong>, <strong>brand</strong>, <strong>device model</strong> values to be stationary. For that kind of attributes, we can use any_value since it doesn&#8217;t change for a user.</p><pre><code><code>SELECT
    user_pseudo_id,
    dt,

    ANY_VALUE(platform) as platform,
    ANY_VALUE(device_brand) as device_brand,
    ANY_VALUE(device_model) as device_model,

FROM events.events
WHERE ...
GROUP BY 1,2</code></code></pre><p>If you are controlling your user ids from a backend system, I don&#8217;t recommend using ANY_VALUE, but FIRST/LAST since all the attributes become dynamic.</p><p>Lastly, I want to mention user behaviour attributes. They show user behaviour like metrics, but still they&#8217;re mostly strings, so summing, counting doesn&#8217;t make sense on them.</p><p>One example is screen or event_name. If you want to measure where the users leave your app, you might want to calculate the first/last screen and events.</p><pre><code><code>SELECT
    user_pseudo_id,
    dt,

    MIN_BY(event_name, ts) as first_event,
    MAX_BY(event_name, ts) as last_event,
    MIN_BY(screen, ts) as first_screen,
    MAX_BY(screen, ts) as last_screen,

FROM events.events
WHERE ...
GROUP BY 1,2</code></code></pre><p>When we bring everything together, you&#8217;ll have a query like:</p><pre><code>SELECT
    user_id,
    dt,

    MIN_BY(country, ts) as first_country,
    MAX_BY(country, ts) as last_country,
    MIN_BY(device_brand, ts) as first_device_brand,
    MAX_BY(device_brand, ts) as last_device_brand,
    MIN_BY(os_version, ts) as first_os_version,
    MAX_BY(os_version, ts) as last_os_version,
    MIN_BY(device_language, ts) as first_device_language,
    MAX_BY(device_language, ts) as last_device_language,

    count(*) as event_cnt,
    min(ts) as min_ts,
    max(ts) as max_ts,

    MIN_BY(event_name, ts) as first_event,
    MAX_BY(event_name, ts) as last_event,
    MIN_BY(screen, ts) as first_screen,
    MAX_BY(screen, ts) as last_screen,

    min(level) as min_level,
    max(level) as max_level,
    count(distinct timestamp_trunc(ts, minute)) as session_duration, 

    -- app monetization metrics
    countif(event_name="ad_reward") as ad_reward_cnt,
    countif(event_name="in_app_purchase") as iap_cnt,
    sum(if(event_name="in_app_purchase", event_value_in_usd, 0)) as iap_revenue,

    -- app engagement metrics
    countif(event_name = "level_start") as level_start_cnt,
    countif(event_name = "level_end") as level_end_cnt,
    countif(event_name = "level_complete") as level_complete_cnt,
    countif(event_name = "level_fail") as level_fail_cnt,
    countif(event_name = "level_retry") as level_retry_cnt,
    countif(event_name = "level_start_quickplay") as level_start_quickplay_cnt,
    countif(event_name = "level_end_quickplay") as level_end_quickplay_cnt,
    countif(event_name = "level_complete_quickplay") as level_complete_quickplay_cnt,
    countif(event_name = "level_fail_quickplay") as level_fail_quickplay_cnt,
    countif(event_name = "level_retry_quickplay") as level_retry_quickplay_cnt,
    countif(event_name = "level_up") as level_up_cnt,
    countif(event_name = "challenge_a_friend") as challenge_a_friend_cnt,
    countif(event_name = "challenge_accepted") as challenge_accepted_cnt,
    countif(event_name = "no_more_extra_steps") as no_more_extra_steps_cnt,
    countif(event_name = "use_extra_steps") as use_extra_steps_cnt,
    countif(event_name = "select_content") as select_content_cnt,
    
FROM events.events
WHERE 
    user_id is not null
    and event_name not in ("app_remove", "os_update", "app_clear_data", "app_update", "app_exception")
GROUP BY 1,2</code></pre><h3>Running on Production</h3><p>Since the previous days&#8217; data never changes, I recommend using an incremental flow for this table. You can find the full version of this pipeline <a href="https://github.com/bruin-data/bruin/blob/main/templates/firebase/assets/user_model/users_daily.sql">here</a>.</p><p>Also, you can use `bruin init firebase` in your terminal to bring all Firebase Analytics pipeline to your computer.</p><p>If you have questions about this article or running Bruin pipelines, don&#8217;t forget to <a href="https://join.slack.com/t/bruindatacommunity/shared_invite/zt-2cx3hk7ck-INfKbeFjCVrEDxiJ~S~hww">join our Slack community</a>.</p><p>If you need help to run your data pipelines, visit <a href="http://getbruin.com">Bruin</a> website. Bruin is an end-to-end data product platform that empowers your data analysts/scientists by 10x!</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.getbruin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Bruin - Unified Analytics Platform! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Unnesting Firebase Events Table]]></title><description><![CDATA[Get major cost savings from BigQuery by having a good data model on Firebase events table]]></description><link>https://blog.getbruin.com/p/unnesting-firebase-events-table</link><guid isPermaLink="false">https://blog.getbruin.com/p/unnesting-firebase-events-table</guid><dc:creator><![CDATA[Sabri Karagonen]]></dc:creator><pubDate>Mon, 08 Apr 2024 15:34:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/aaae9d51-0bf1-4028-8d07-78d776375847_1792x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the previous article, we created some functions to query events table and it helped to make it easier to query.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;58a40c5b-68b9-491d-8291-9c64e6d98225&quot;,&quot;caption&quot;:&quot;In our previous post, we explored the process of exporting data to BigQuery. Now, it's time to delve into the wealth of insights stored in this extensive table containing all your user events and detailed user information. While a comprehensive explanation of each column is available&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;lg&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Firebase Events Table&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:2357940,&quot;name&quot;:&quot;Sabri Karagonen&quot;,&quot;bio&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42b75c24-8348-4190-af67-f45e7b7ed721_909x896.png&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-02-23T09:41:33.115Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1a3de396-a685-4700-9eae-cb996c23956d_1792x1024.webp&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.getbruin.com/p/firebase-events-table&quot;,&quot;section_name&quot;:&quot;Tutorials&quot;,&quot;video_upload_id&quot;:null,&quot;id&quot;:141896356,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:2,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Bruin - Unified Analytics Platform&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d316914-a075-4284-90ec-3841c25a349f_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Even though these functions make our lives easier, we can make it even better. <em><strong>get_param</strong></em> and <em><strong>get_prop</strong></em> parameters require you to type a lot of characters, and also you have to remember the data type every time. Also, since <em><strong>event_params</strong></em> contains all the other parameters, querying it becomes very expensive.</p><p>To avoid this problem, I'll recommend a new data model to simplify querying.</p><h2>Problem 1 - Too many characters</h2><p>To be able to get a single parameter, let's say level, I have to type these all the time:</p><pre><code>fn.get_param_int(event_params, 'level') as level</code></pre><p>The problems here are:</p><ol><li><p>I have to repeat <code>fn.get_param_int</code> for every parameter</p></li><li><p>I have to repeat <code>event_params</code> every time</p></li><li><p>I have to know the data type of the level parameter (in this example <code>int</code>)</p></li></ol><h2>Problem 2- Query costs</h2><p>BigQuery charges per data scanned, and it costs a lot every time we access <code>event_params</code>.</p><p>To understand why, let's check an example <code>event_params</code> row:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lySm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lySm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 424w, https://substackcdn.com/image/fetch/$s_!lySm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 848w, https://substackcdn.com/image/fetch/$s_!lySm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 1272w, https://substackcdn.com/image/fetch/$s_!lySm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lySm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic" width="1456" height="651" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/426a734c-9d1c-4af4-81f1-a6177766faeb.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:651,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:87413,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lySm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 424w, https://substackcdn.com/image/fetch/$s_!lySm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 848w, https://substackcdn.com/image/fetch/$s_!lySm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 1272w, https://substackcdn.com/image/fetch/$s_!lySm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F426a734c-9d1c-4af4-81f1-a6177766faeb.heic 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here, even though the client sends only 1 parameter, <code>board</code>, Firebase automatically adds 3 other parameters.</p><p>Let's calculate the data size BigQuery scans only to access the parameter &#8220;<code>board</code>&#8221;.</p><p>Since <code>event_params</code> is an array, we have to scan all the details in the array (there are very small optimizations behind, but for now I ignore them)</p><h4>key column:</h4><p>firebase_screen_class<strong>:</strong> 21 characters<br>firebase_event_origin<strong>:</strong> 21 characters<br>firebase_screen_id<strong>:</strong> 18 characters<br>board<strong>:</strong> 5 characters<br><strong>total:</strong> 65 characters</p><h4>values.string_value column</h4><p>game_board: 10 characters<br>app+gtm: 7 characters<br>S: 1 character<br><strong>total:</strong> 18 characters</p><p>So just to get a single character, `S`, BigQuery had to scan 65 + 18 = 83 characters. So this query could be 83 times cheaper! </p><p>To make this calculation, I already ignored the int and float value columns.</p><p>Also, this event has only 4 parameters, but most have many more parameters.</p><p>So imagine there are 15 parameters with an average of 15 characters. It would mean scanning 225 characters just for a single character! It&#8217;s a crazy amount of savings. (1/225 = Only 0.4% of the total scans)</p><h2>Solution 1 - Unnested Events Table</h2><p>So how can we solve this problem?</p><p>If we had a column named board, it would be great, right?</p><p>Imagine all the parameters are already a column in the events table, and BigQuery autocompletes your query, and also it costs much much less...</p><p>In this approach, we run an unnesting query periodically, so this query only runs once and then the rest of the queries are done on the new table.</p><p>An example unnested events query would be like:</p><pre><code>CREATE TABLE events.events 
PARTITION BY dt CLUSTER BY event_name
AS
SELECT
&#9;app_info.id AS app,
&#9;platform,
&#9;PARSE_DATE('%Y%m%d', event_date) AS dt,
&#9;TIMESTAMP_MICROS(event_timestamp) AS ts,
&#9;TIMESTAMP_MICROS(user_first_touch_timestamp) AS install_ts,
&#9;user_pseudo_id,
&#9;user_id,
&#9;lower(event_name) as event_name,
&#9;app_info.version AS app_version,
&#9;device.advertising_id,
&#9;device.vendor_id,
&#9;geo.country AS geo_country,
&#9;device.category AS device_type,
&#9;device.mobile_brand_name AS device_brand,
&#9;device.mobile_marketing_name AS device_marketing_name,
&#9;device.mobile_model_name AS device_model,
&#9;device.mobile_os_hardware_model AS device_hardware_model,
&#9;device.language AS device_language,
&#9;CASE lower(device.is_limited_ad_tracking)
&#9;&#9;WHEN 'yes' THEN True
&#9;&#9;WHEN 'no' THEN False
&#9;END AS device_limited_ad_tracking,
&#9;device.operating_system AS device_os,
&#9;device.operating_system_version AS device_os_version,
&#9;event_server_timestamp_offset / 1000 AS event_server_timestamp_offset,
&#9;device.time_zone_offset_seconds / 3600 AS device_time_zone_offset_seconds,
&#9;func.get_param_str(event_params, 'firebase_screen') AS screen,
&#9;func.get_param_str(event_params, 'firebase_screen_class') AS screen_class,
&#9;func.get_param_int(event_params, 'ga_session_id') AS session_id,
&#9;func.get_param_int(event_params, 'ga_session_number') AS session_number,
&#9;func.get_param_int(event_params, 'board') AS board,
FROM `firebase-public-project.analytics_153293282.events_*`</code></pre><p>In this query, you can add all your event parameters and user properties, then schedule it to run once a day. You will have a very clean events table and it will be much cheaper to query.</p><p>However, this approach has a problem. As your events evolve and you send more and more parameters, it will be hard to maintain this table. </p><p>For every new parameter, you have to create a new column like this, first:</p><pre><code>ALTER TABLE events
ADD COLUMN new_column INT64;</code></pre><p>If you are late adding the new parameters to the table, you have to backfill it for the previous days.</p><h2>Solution 2- Json Events Table</h2><p>In previous years, BigQuery introduced a relatively new datatype: <strong>JSON</strong>.</p><p>JSON datatype gives flexibility in terms of new keys/parameters, and also it's stored as columnar in the storage layer. So, if you access a parameter in a JSON field, it would still be very cheap compared to the <code>event_params</code> column.</p><p>Here, I come up with another function:</p><pre><code>CREATE OR REPLACE FUNCTION `fn.event_params_to_json`(
event_params ARRAY&lt;STRUCT&lt;
key STRING,
value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64&gt;
&gt;&gt;
)
AS ((
with t1 as
(
&#9;select
&#9;&#9;array_agg(p.key) as keys,
&#9;&#9;array_agg(coalesce(
&#9;&#9;&#9;p.value.string_value,
&#9;&#9;&#9;cast(p.value.int_value as string),
&#9;&#9;&#9;cast(coalesce(p.value.double_value, p.value.float_value) as string)
&#9;&#9;)) as vals
&#9;from unnest(event_params) as p
&#9;where key not in ("firebase_screen", "firebase_screen_class", "ga_session_id", "ga_session_number", "engaged_session_event", "engagement_time_msec", "firebase_event_origin", "firebase_previous_id", "firebase_screen_id")
)
select case when array_length(keys) &gt; 0 then json_object(keys, vals) end
from t1
));</code></pre><p>This function converts all the parameters to string and then creates a JSON object from them.</p><p>The reason I converted all of them to string is that BigQuery doesn't allow creating a JSON object with different data types.</p><p>At the end, you'll have a dictionary like:</p><pre><code>{
"firebase_screen_class": "game_board",
"firebase_event_origin": "app+gtm",
"firebase_screen_id": "-8894705......",
"board": "S"
}</code></pre><p>To create a JSON <code>event_params</code> column, you can use this query:</p><pre><code>CREATE TABLE events.events_json
PARTITION BY dt CLUSTER BY event_name AS
SELECT
&#9;app_info.id as app,
&#9;platform,
&#9;PARSE_DATE('%Y%m%d', event_date) as dt,
&#9;TIMESTAMP_MICROS(event_timestamp) as ts,
&#9;TIMESTAMP_MICROS(user_first_touch_timestamp) as user_first_touch_ts,
&#9;user_pseudo_id,
&#9;user_id,
&#9;lower(event_name) as event_name,
&#9;fn.parse_version(app_info.version) as app_version,
&#9;fn.event_params_to_json(event_params) as ep,
FROM `firebase-public-project.analytics_153293282.events_*`</code></pre><p>And then, you can use this query to access the <code>board</code> parameter:</p><pre><code>SELECT lax_string(ep.board) as board
FROM events.events_json</code></pre><p>With this query, we gained flexibility but lost query comfort. Now, we have to type more characters. To fix it, I recommend creating a view on top of this table, so it will be very similar to solution 1, but also flexible. <strong>Views don't occupy space in the storage</strong> but use the underlying tables to retrieve data.</p><p>To create the view, you can use this query:</p><pre><code>CREATE OR REPLACE VIEW events.events AS
SELECT
&#9;* except(up, ep),
&#9;lax_string(ep.board) as board,
FROM events.events_json</code></pre><p>So every time you query the table <code>events.events</code>, it actually goes through <code>events.events_json</code> table and retrieves the recent data. In the case there is a new parameter, the only thing you need to do is add it to <code>events.events</code> view. </p><h2>Running this pipeline on production</h2><p>Event tables are incremental tables and older days' data is not updated. If you're using intraday, it doesn't backfill older data, if you're using batch export, every day it updates the last 3 days of data. Based on my personal experience, added data to previous days tends to be ~1-2% of the total events, so you might choose to ignore it.</p><p>Since data is only added incrementally, you don't have to create the whole <code>events</code> table every day, and instead run incremental pipelines. While incremental strategies can go a long way, it is pretty simple for our article: you can just read yesterday&#8217;s data and append it to the current table. This way, your ETL costs will decrease significantly, and your ETL process will be completed much faster.</p><p>I only shared the <code>CREATE</code> queries above to keep it short, but in <a href="https://github.com/bruin-data/bruin/tree/main/templates/firebase">this</a> repo, you can find how to make them incremental using <a href="https://github.com/bruin-data/bruin">Bruin</a>.</p><h3>Running Bruin</h3><p>To run the pipeline steps in the right order, you need what&#8217;s called an &#8220;orchestrator&#8221;. Bruin is an open-source orchestrator that allows you to define your data pipelines as a collection of assets, and run them in your data warehouse.</p><p>You can install Bruin CLI by following the instructions <a href="http://python_module_path">here</a>.</p><p>If you already have <a href="https://github.com/bruin-data/bruin">Bruin CLI</a>, you can use the command below in the terminal to get a fresh start and it will automatically create a starter template for you. You can update this pipeline according to your needs and use it in the production.</p><pre><code>brew tap bruin-data/tap
bruin init firebase</code></pre><p>As a result of this command, you will have a fully-prepared production-ready data pipeline based on our articles, applying the best practices of managing Firebase data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yQiy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yQiy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 424w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 848w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yQiy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png" width="614" height="1218" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:1218,&quot;width&quot;:614,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:149820,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yQiy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 424w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 848w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 1272w, https://substackcdn.com/image/fetch/$s_!yQiy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e2c49-79d1-4880-af41-de5c409a4bf2_614x1218.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If you have questions about this article or running Bruin pipelines, <a href="https://join.slack.com/t/bruindatacommunity/shared_invite/zt-2cx3hk7ck-INfKbeFjCVrEDxiJ~S~hww">join our Slack community</a>. </p><p>In the next article, I'll explain how to create a daily summary table and we will create our first dashboard on Looker Studio. You can subscribe to this newsletter to get updated about the next article.</p>]]></content:encoded></item><item><title><![CDATA[The Pains of Data Ingestion]]></title><description><![CDATA[Why is it so hard? Could we do something about it?]]></description><link>https://blog.getbruin.com/p/the-pains-of-data-ingestion</link><guid isPermaLink="false">https://blog.getbruin.com/p/the-pains-of-data-ingestion</guid><dc:creator><![CDATA[Burak Karakan]]></dc:creator><pubDate>Tue, 27 Feb 2024 09:38:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!rKKj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rKKj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rKKj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 424w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 848w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rKKj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1063239,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rKKj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 424w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 848w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!rKKj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff2e56f0a-0a29-4c27-ad9f-68baee5729a2_1792x1024.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One of the first issues companies run into when it comes to analyzing their data is having to move the data off of their production databases:</p><ul><li><p>The production instances have different abilities that are not suitable for analytical workloads, such as row-oriented vs column-oriented databases.</p></li><li><p>Analytical use-cases have very different SLAs and requirements than production applications, which means their reliability needs are very different. An analytical query may take 1.2s instead of 400ms and that would be fine, whereas that latency could be a huge disruption to the user experience if it happened on the production database.</p></li><li><p>Online Transaction Processing (OLTP) databases are focused on transactional use-cases, which means they lack quite a few features around data analysis.</p></li></ul><p>Due to these contributing factors, companies usually move their data off to an analytical database such as <a href="https://cloud.google.com/bigquery?hl=en">Google BigQuery</a> or <a href="https://www.snowflake.com/en/">Snowflake</a> after a certain size and scale for analytical purposes.&nbsp;</p><p>While moving the data to a database that is fit for purpose sounds good, it has its own challenges:</p><ul><li><p>The data needs to be copied over at a regular cadence via some tool/custom code. This means extra effort and cost to build and maintain.</p></li><li><p>The data is now duplicated across multiple databases, meaning that changes in the source need to be accurately reflected in the analytical database.</p></li><li><p>The assumptions around the atomicity/reliability of the data change since there are multiple places where the data resides now.</p></li><li><p>After a certain data size, transferring the data becomes expensive and slow, requiring further engineering investment to make the process more efficient.</p></li></ul><p>All of these reasons build up the problems around data ingestion, and there are already a bunch of tools in the market that aim to solve this.</p><h3>Building everything from&nbsp;scratch&nbsp;</h3><p>The moment the data ingestion/copy problem is acknowledged, the first reaction across many teams is to build a tool that does the ingestion for them, and then schedule it via cronjobs or more advanced solutions. The problem sounds simple on the surface:</p><ul><li><p>Download a copy of the original data</p></li><li><p>Upload it to the destination database either via SQL <code>insert</code> statements, or some other platform-specific way to load the data into the database</p></li></ul><p>However, this on-the-surface analysis forgets quite a few crucial questions:</p><ul><li><p>How do you ensure the data is copied over accurately?</p></li><li><p>What happens when there&#8217;s a bug that requires copying the data again?</p></li><li><p>What if the data does not fit into the memory at once? How do you paginate?</p></li><li><p>What happens as the data grows and copying/overwriting everything becomes too slow/expensive?</p></li><li><p>What happens when the schema of the data changes?</p></li><li><p>How does the team know about failures?</p></li><li><p>Where do you deploy the logic?</p></li><li><p>and quite a few more&#8230;</p></li></ul><p>As you can see, there are many open points and they all require a solid understanding of the problem at hand, along with the investment to make the overall initiative success. Otherwise, the engineering team builds quick hacks to get them up and running, and these &#8220;hacks&#8221; start to become the backbone of the analytical use-cases, making it very hard, if not impossible, to evolve the architecture as the business evolves.</p><p>Some smart people saw the problem at hand and came up with various solutions to make this process easier.</p><h2>No-code solutions</h2><p>Over the years some teams have decided that data ingestion can be performed simply via UI-driven solutions that have pre-built connectors across various platforms, which means non-technical people can also ingest data. Two major players that come to mind are <a href="https://www.fivetran.com/">Fivetran</a> and <a href="https://airbyte.com/">Airbyte</a>, both giant companies trying to tackle the long-tail of the data ingestion problem.</p><p>Even though there are a few differences between these no-code platforms, their primary approach is that you use their UI to set up connectors, and you forget about the problem without needing any technical person, e.g. a marketing person can set up a data ingestion task from Postgres to BigQuery.</p><p>While these tools do have a great deal of convenience, they still pose some challenges:</p><ul><li><p>The movement of the data is a fairly technical work that has quite a few questions about the ways of copying the data, and the data work rarely ends after just copying the data, therefore technical people such as data analysts, scientists, or engineers still need to be involved in the process, which means that the actual audience is the data people rather than non-technical folks.</p></li><li><p>The UI-driven workflow causes lock-in, which means that the company is not going to be able to move away from these platforms until they build a replacement, which usually means further investment later on without disrupting the current ways of working + migrating the existing usecases.</p></li><li><p>For the open-source solutions such as Airbyte, they still need to be hosted and maintained internally, which means engineering time and effort &amp; infrastructure costs.</p></li></ul><p>All in all, while the UI-driven data ingestion tools like Fivteran or Airbyte allow teams to get going from zero, there are still some issues that causes teams to stay away from them and resort to writing code due to the flexibility it provides.</p><h2>Yes-code solutions: <a href="https://github.com/dlt-hub/dlt">dlt</a></h2><p>There has been an emerging open-source Python library from the company <a href="https://dlthub.com/">dltHub</a> called <a href="https://github.com/dlt-hub/dlt">dlt</a>, which focuses more on the use cases where there&#8217;ll still be code written to ingest the data, but the code could actually be a lot smaller and maintainable. dlt has built-in open-source connectors, but it also allows custom sources &amp; destinations to be built by teams for their specific needs. It is flexible but allows quick iteration when it comes to ingestion.</p><p>There are a couple of things dlt takes care of very nicely:</p><ul><li><p>dlt supports schema evolution, meaning that when the schema of an upstream dataset changes, dbt will make sure the destination tables are updated accordingly based on the changes.</p></li><li><p>dlt supports custom sources and destinations, meaning that their prebuilt sources &amp; destinations can be combined with custom ones.</p></li><li><p>dlt has support for incremental updates and deduplication, which means that the data can be incrementally updated with only the changed data while ensuring it still matches the source data.</p></li></ul><p>dlt is quite a powerful library and has a very vibrant, growing community. It might be the perfect companion when it comes to engineers wanting to write code for certain custom requirements.</p><p>However, we felt that there might be a middle ground for simpler use-cases that doesn&#8217;t require coding, but also doesn&#8217;t lock us into a UI-driven workflow.</p><p>While we like dlt a lot at <a href="https://getbruin.com">Bruin</a>, we felt that there were quite a few simpler scenarios that we couldn&#8217;t justify writing, maintaining, and deploying code for:</p><ul><li><p>Some of our customers wanted to be able to simply copy a source table to a destination, and override the data in the destination because the data was small enough.</p></li><li><p>Some others required fixed incremental strategies, such as &#8220;just get the latest data based on the `updated_at` column.</p></li><li><p>Some others needed to be able to merge the new records with the old ones incrementally.</p></li></ul><p>While all of these are possible with dlt, it requires these people to write code and figure out a way to deploy them and monitor them. It is not incredibly hard, but it is also not trivial. Seeing all these patterns, we have decided to take a stab at the problem in an open-source fashion.</p><h1>Introducing: <a href="https://github.com/bruin-data/ingestr">ingestr</a></h1><p><a href="https://github.com/bruin-data/ingestr">ingestr</a> is a command-line application that allows you to ingest data from any source into any destination using simple command-line flags, without having to write any code and still having it as part of your tech stack.</p><ul><li><p>&#10024; copy data from your Postgres / MySQL / SQL Server or any other source into any destination, such as BigQuery or Snowflake</p></li><li><p>&#10133; incremental loading</p></li><li><p>&#128013; single-command installation: <code>pip install ingestr</code></p></li></ul><p>ingestr takes away the complexity of managing any backend or writing any code for ingesting data, simply run the command and watch the magic</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CYZf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CYZf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 424w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 848w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CYZf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif" width="1250" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1250,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:101450,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CYZf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 424w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 848w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 1272w, https://substackcdn.com/image/fetch/$s_!CYZf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F49632483-f3d8-4f11-a7dd-345af599e102_1250x600.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>.</p><p>ingestr makes a couple of opinionated decisions about how the ingestion should work:</p><ul><li><p>it is built as an <a href="https://github.com/bruin-data/ingestr">open-source</a> solution, and anyone can use it for any purpose based on its permissive license</p></li><li><p>ingestr treats everything as a URI: every source and every destination has its own URI based on <a href="https://www.sqlalchemy.org/">SQLAlchemy</a> connection URIs.</p></li><li><p>ingestr has a few built-in incremental loading strategies: <code>replace</code>, <code>append</code>, <code>merge</code> and <code>delete+insert</code></p></li></ul><p>While there will be quite a few scenarios where the teams would benefit from the flexibility dlt provides, we believe that 80% of the real-life scenarios out there would fall into these presets, and for those <a href="https://github.com/bruin-data/ingestr">ingestr</a> could simplify things quite a bit.</p><p>&#127775; Give it a look and give us <a href="https://github.com/bruin-data/ingestr">a star on GitHub!</a> We&#8217;d love to hear your feedback and feel free to join our Slack community <a href="https://join.slack.com/t/bruindatacommunity/shared_invite/zt-2dl2i8foy-bVsuMUauHeN9M2laVm3ZVg">here</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.getbruin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Firebase Events Table]]></title><description><![CDATA[How to query Firebase events table and some tricks to make it easier]]></description><link>https://blog.getbruin.com/p/firebase-events-table</link><guid isPermaLink="false">https://blog.getbruin.com/p/firebase-events-table</guid><dc:creator><![CDATA[Sabri Karagonen]]></dc:creator><pubDate>Fri, 23 Feb 2024 09:41:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1a3de396-a685-4700-9eae-cb996c23956d_1792x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In our <a href="https://blog.getbruin.com/p/exporting-firebase-data-to-bigquery">previous post</a>, we explored the process of exporting data to BigQuery. Now, it's time to delve into the wealth of insights stored in this extensive table containing all your user events and detailed user information.</p><p>While a comprehensive explanation of each column is available <a href="https://support.google.com/analytics/answer/7029846?hl=en">here</a>, this post will focus on making the table more accessible.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.getbruin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Bruin - Unified Analytics Platform! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Accessing Firebase Demo Project</h1><p>Let's kick things off with the Firebase demo project. If you already have a project, you don&#8217;t need to follow this step, you can just jump to the next topic below.</p><p>The demo dataset resides in the <em><strong>firebase-public-project</strong></em>, and you can add it to your workspace with a simple click on the <strong>+ ADD</strong> button near above the data catalog.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4sKm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4sKm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 424w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 848w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 1272w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4sKm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png" width="450" height="206.25" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/278be893-07f7-48ce-9259-38680d341bd6_768x352.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:352,&quot;width&quot;:768,&quot;resizeWidth&quot;:450,&quot;bytes&quot;:46091,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4sKm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 424w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 848w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 1272w, https://substackcdn.com/image/fetch/$s_!4sKm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F278be893-07f7-48ce-9259-38680d341bd6_768x352.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Select the <strong>Star a project by name</strong> option, and type <strong>firebase-public project</strong> in the window that appears.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CyJH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CyJH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 424w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 848w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 1272w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CyJH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png" width="336" height="303.625" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:694,&quot;width&quot;:768,&quot;resizeWidth&quot;:336,&quot;bytes&quot;:88560,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CyJH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 424w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 848w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 1272w, https://substackcdn.com/image/fetch/$s_!CyJH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd55b8e-b5f8-40ca-bec7-2c942c1b83e1_768x694.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6rRk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6rRk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 424w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 848w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 1272w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6rRk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png" width="306" height="278.85483870967744" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:452,&quot;width&quot;:496,&quot;resizeWidth&quot;:306,&quot;bytes&quot;:30437,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6rRk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 424w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 848w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 1272w, https://substackcdn.com/image/fetch/$s_!6rRk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F224e5be8-c9e1-4705-9d19-315f5f9e3066_496x452.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Upon clicking 'Star,' you'll find this dataset conveniently located in the left pane.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T3Br!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T3Br!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 424w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 848w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 1272w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T3Br!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png" width="382" height="393.7374301675978" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:738,&quot;width&quot;:716,&quot;resizeWidth&quot;:382,&quot;bytes&quot;:79520,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T3Br!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 424w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 848w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 1272w, https://substackcdn.com/image/fetch/$s_!T3Br!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddd44bca-b281-4fae-9dd7-899dfa65e177_716x738.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Understanding Events Table</h1><p>Once you start exporting your data to BigQuery, you'll encounter a very wide table in BigQuery which is hard to understand and contains too much information.</p><p>Depending on your export settings, Firebase exports events in 2 names:</p><ul><li><p><strong>events_</strong></p></li><li><p><strong>events_intraday_</strong></p></li></ul><p>These tables are <a href="https://cloud.google.com/bigquery/docs/partitioned-tables#dt_partition_shard">sharded</a> tables, and generates a table for each day. For example, for 30 September 2023, the table name will be <strong>events_20230930</strong>.</p><p>Let's write our first query to see the event counts on a specific day, "<strong>2018-10-03</strong>".</p><pre><code>SELECT
&#9;event_name,
&#9;count(*) as event_cnt,
&#9;count(distinct user_pseudo_id) as user_cnt,
&#9;count(*) / count(distinct user_pseudo_id) as event_per_user
FROM `firebase-public-project.analytics_153293282.events_20181003`
GROUP BY 1
ORDER BY 2 desc</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mkUT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mkUT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 424w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 848w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 1272w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mkUT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png" width="1112" height="1246" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1246,&quot;width&quot;:1112,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:215661,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mkUT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 424w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 848w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 1272w, https://substackcdn.com/image/fetch/$s_!mkUT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2465d503-d74b-4e15-8458-51368a9f578d_1112x1246.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Firebase triggers some events like <strong>screen_view</strong>, <strong>user_engagement</strong> automatically, so if you haven't triggered any of them, you don't need to get worried.</p><h1>Working with Event Timestamp Column</h1><p>If you preview the events table, the first thing you&#8217;ll see is, <strong>event_timestamp</strong> is an integer, and not easy to understand.</p><p>To convert it to a timestamp, you can use the <strong>TIMESTAMP_MICROS</strong> function. </p><p>Let's find hourly level starts in our game. To understand how <strong>timestamp_trunc</strong> function works, you can check the <a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#timestamp_trunc">documentation</a>.</p><pre><code><code>SELECT 
    timestamp_trunc(timestamp_micros(event_timestamp), hour) as hour, 
    count(*) as events
FROM `firebase-public-project.analytics_153293282.events_20181003`
GROUP BY 1
ORDER BY 1</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Bz7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Bz7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 424w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 848w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 1272w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Bz7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png" width="386" height="318.9861111111111" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:714,&quot;width&quot;:864,&quot;resizeWidth&quot;:386,&quot;bytes&quot;:107670,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-Bz7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 424w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 848w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 1272w, https://substackcdn.com/image/fetch/$s_!-Bz7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43382ece-ed3b-4ef4-bf64-785faa0e8982_864x714.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5uBF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5uBF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 424w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 848w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 1272w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5uBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png" width="380" height="293.7962962962963" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:668,&quot;width&quot;:864,&quot;resizeWidth&quot;:380,&quot;bytes&quot;:102176,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5uBF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 424w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 848w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 1272w, https://substackcdn.com/image/fetch/$s_!5uBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124752ea-728f-45b1-8b15-fec823ac87dc_864x668.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As you can see here, even though we queried the data for <strong>2018-10-03</strong>, we got data from 7:00 AM to the next day until 7:00 AM. It happens due to the reporting time zone in Google Analytics settings. There always will be a difference between event_date and event_timestamp, but to minimize it you can choose UTC as time zone.</p><h1>Querying Events, Event Params and User Properties</h1><p>Let's focus on <strong>level_start_quickplay</strong> event and see some of the events and parameters.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5y5I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5y5I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 424w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 848w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 1272w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5y5I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png" width="1456" height="651" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/59180415-4283-4fce-be1f-1b8486c73124_1802x806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:651,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:172535,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5y5I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 424w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 848w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 1272w, https://substackcdn.com/image/fetch/$s_!5y5I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F59180415-4283-4fce-be1f-1b8486c73124_1802x806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There is a `board` parameter in event_params, and the value is `S`. It keeps the board size value for the played level.</p><p>Let's count level starts per board, but event_params is an array. How do we access it?</p><p>For both event_params and user_properties, we can use this code to access the parameters:</p><pre><code>(select value.{PARAMETER_TYPE}_value from unnest(event_params) where key = "{PARAMETER_NAME}")</code></pre><p>So to access the parameter, let's use it in the query and count it:</p><pre><code>SELECT
&#9;(select value.string_value from unnest(event_params) where key = "board") as board,
&#9;count(*) as cnt
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "level_start_quickplay"
GROUP BY 1</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6u4y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6u4y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 424w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 848w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 1272w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6u4y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png" width="1324" height="658" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:658,&quot;width&quot;:1324,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:108958,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6u4y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 424w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 848w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 1272w, https://substackcdn.com/image/fetch/$s_!6u4y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7592b91b-e71b-4b77-bd1a-2f250f740e9a_1324x658.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Get Param Functions</h1><p>As you want to include more and more parameters, writing this query will be very annoying.</p><p>For that purpose, I created some functions for you. First, I recommend you to create a dataset called <strong>fn</strong> and store all the functions in that dataset. Don't forget to choose the same region as the events tables region for this dataset.</p><pre><code>CREATE OR REPLACE FUNCTION fn.get_param_str(event_params ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64&gt;&gt;&gt;, param_key STRING) AS 
((
&#9;SELECT
&#9;&#9;COALESCE(
&#9;&#9;&#9;value.string_value,
&#9;&#9;&#9;CAST(value.int_value as string),
&#9;&#9;&#9;CAST(value.float_value as string),
&#9;&#9;&#9;CAST(value.double_value as string)
&#9;&#9;)
&#9;FROM UNNEST(event_params) WHERE key = param_key&#9;
));

CREATE OR REPLACE FUNCTION fn.get_param_int(event_params ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64&gt;&gt;&gt;, param_key STRING) AS 
((
&#9;SELECT
&#9;&#9;COALESCE(
&#9;&#9;&#9;value.int_value,
&#9;&#9;&#9;SAFE_CAST(value.float_value as int64),
&#9;&#9;&#9;SAFE_CAST(value.double_value as int64),
&#9;&#9;&#9;SAFE_CAST(value.string_value as int64)
&#9;&#9;)
&#9;FROM UNNEST(event_params) WHERE key = param_key
));

CREATE OR REPLACE FUNCTION fn.get_param_float(event_params ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64&gt;&gt;&gt;, param_key STRING) AS 
((
&#9;SELECT
&#9;&#9;COALESCE(
&#9;&#9;&#9;value.float_value,
&#9;&#9;&#9;value.double_value,
&#9;&#9;&#9;CAST(value.int_value as FLOAT64),
&#9;&#9;&#9;SAFE_CAST(value.string_value as FLOAT64)
&#9;&#9;)
&#9;FROM UNNEST(event_params) WHERE key = param_key&#9;
));

CREATE OR REPLACE FUNCTION `fn.get_param_bool`(event_params ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64&gt;&gt;&gt;, param_key STRING) AS (
&#9;SAFE_CAST(fn.get_param_int(event_params, param_key) as bool)
);</code></pre><p>After creating these functions, you can rewrite your query as:</p><pre><code>SELECT
&#9;fn.get_param_str(event_params, "board") as board,
&#9;count(*) as cnt
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "level_start_quickplay"
GROUP BY 1</code></pre><p>Let&#8217;s query <strong>post_score</strong> event with parameters:</p><p>First, to find the parameters, let&#8217;s check the table without manipulation:</p><pre><code>SELECT 
    user_pseudo_id,
    timestamp_micros(event_timestamp) as ts,
    event_params
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "post_score"</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5wHY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5wHY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 424w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 848w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 1272w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5wHY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png" width="1456" height="441" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:441,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:181181,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5wHY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 424w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 848w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 1272w, https://substackcdn.com/image/fetch/$s_!5wHY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62d0a8b6-85ff-4085-9c86-c2200877706b_2492x754.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here, we can see that there are 4 parameters relevant to the event. </p><ul><li><p>level_name (string)</p></li><li><p>level (double)</p></li><li><p>time (double)</p></li><li><p>score (double)</p></li></ul><p>If we use our functions to unnest the parameters, the query looks like that. Since BigQuery doesn&#8217;t have a <strong>double</strong> datatype, doubles are queried as <strong>float</strong>s:</p><pre><code><code>SELECT 
    user_pseudo_id,
    timestamp_micros(event_timestamp) as ts,
    fn.get_param_str(event_params, "level_name") as level_name,
    fn.get_param_float(event_params, "level") as level,
    fn.get_param_float(event_params, "time") as time,
    fn.get_param_float(event_params, "score") as score,
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "post_score"</code></code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lRuN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lRuN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 424w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 848w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 1272w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lRuN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png" width="1456" height="608" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:608,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:213025,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lRuN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 424w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 848w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 1272w, https://substackcdn.com/image/fetch/$s_!lRuN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6b69f77d-68a5-4f19-a904-76b7d8443ae3_1792x748.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Even though parameters are sent as double/float,  it looks like they indeed are integers. Let&#8217;s verify it by checking all the values:</p><pre><code>SELECT 
    fn.get_param_float(event_params, "score") as score,
    count(*)    
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "post_score"
group by 1
order by 1</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lzc_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lzc_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 424w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 848w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 1272w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lzc_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png" width="298" height="347.0258064516129" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:722,&quot;width&quot;:620,&quot;resizeWidth&quot;:298,&quot;bytes&quot;:57872,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!lzc_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 424w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 848w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 1272w, https://substackcdn.com/image/fetch/$s_!lzc_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30f4c50f-effb-45d2-8123-43efed2d25bb_620x722.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As suspected, all the rows are actually integers. If we do the same check for level and time, we see that they are also integers.</p><p>So let&#8217;s rewrite our query:</p><pre><code>SELECT 
    user_pseudo_id,
    timestamp_micros(event_timestamp) as ts,
    fn.get_param_str(event_params, "level_name") as level_name,
    fn.get_param_int(event_params, "level") as level,
    fn.get_param_int(event_params, "time") as time,
    fn.get_param_int(event_params, "score") as score,
FROM `firebase-public-project.analytics_153293282.events_20181003`
WHERE event_name = "post_score"</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VSnu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VSnu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 424w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 848w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 1272w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VSnu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png" width="1456" height="634" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:634,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:209184,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VSnu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 424w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 848w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 1272w, https://substackcdn.com/image/fetch/$s_!VSnu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d3e16c1-3fdd-4646-a734-01674c12186e_1694x738.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We get the same table, but with correct datatypes this time.</p><p><strong>get_param_*</strong> and <strong>get_prop_*</strong> functions are automatically casting the data to the right data types, so you don&#8217;t have to cast them again.</p><p>Here is the code for get_prop functions:</p><pre><code>CREATE OR REPLACE FUNCTION `fn.get_prop_str`(user_properties ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64, set_timestamp_micros INT64&gt;&gt;&gt;, param_key STRING) AS (
(
    SELECT 
        COALESCE(
            value.string_value,
            CAST(value.int_value as string),
            CAST(value.float_value as string),
            CAST(value.double_value as string)
        )
    FROM UNNEST(user_properties) WHERE key = param_key
)
);

CREATE OR REPLACE FUNCTION `fn.get_prop_int`(user_properties ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64, set_timestamp_micros INT64&gt;&gt;&gt;, param_key STRING) AS (
(
    SELECT 
        COALESCE(
            value.int_value,
            SAFE_CAST(value.float_value as int64),
            SAFE_CAST(value.double_value as int64),
            SAFE_CAST(value.string_value as int64)
        )
    FROM UNNEST(user_properties) WHERE key = param_key
)
);

CREATE OR REPLACE FUNCTION `fn.get_prop_bool`(user_properties ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64, set_timestamp_micros INT64&gt;&gt;&gt;, param_key STRING) AS 
(
    COALESCE(
        SAFE_CAST(fn.get_prop_int(user_properties, param_key) as bool),
        SAFE_CAST(fn.get_prop_str(user_properties, param_key) as bool)
    )
);

CREATE OR REPLACE FUNCTION `fn.get_prop_double`(user_properties ARRAY&lt;STRUCT&lt;key STRING, value STRUCT&lt;string_value STRING, int_value INT64, float_value FLOAT64, double_value FLOAT64, set_timestamp_micros INT64&gt;&gt;&gt;, param_key STRING) AS (
(
    SELECT 
        COALESCE(
            value.double_value,
            value.float_value,
            CAST(value.int_value as FLOAT64),
            SAFE_CAST(value.string_value as FLOAT64)
        )
    FROM UNNEST(user_properties) WHERE key = param_key
)
);</code></pre><h1>Querying multiple days</h1><p>Until here, we only queried 1 day of data, specifically <strong>2018-10-03</strong>.</p><p>What if we want to query multiple days?</p><p>BigQuery gives you a flexible way of querying sharded tables. You can just use `<strong>*</strong>` instead of the date in the table name, and you will be able to query all the dates:</p><pre><code>SELECT
    event_date,
    count(*) as cnt,
    avg(fn.get_param_int(event_params, "score")) as avg_score,
    avg(fn.get_param_int(event_params, "level")) as avg_level
FROM `firebase-public-project.analytics_153293282.events_*`
WHERE event_name = "post_score"
GROUP BY 1
ORDER BY 1</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fwkl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fwkl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 424w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 848w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 1272w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fwkl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png" width="1268" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:1268,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84318,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fwkl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 424w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 848w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 1272w, https://substackcdn.com/image/fetch/$s_!fwkl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8484c5e-4d09-4f11-b82a-fd06bd15d1a3_1268x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8mUm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8mUm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 424w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 848w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 1272w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8mUm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png" width="1268" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:1268,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:86361,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8mUm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 424w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 848w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 1272w, https://substackcdn.com/image/fetch/$s_!8mUm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50b35bdb-3cbf-4fa6-89cd-6bc3f66165b0_1268x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This query returns 114 rows, for days between 12 June and 3 October.</p><p>However, you might need only the days between instead of full data. It will be both cheaper since we scan less data, and also might be more useful for our analysis. In that case, we&#8217;re using <strong>_TABLE_SUFFIX</strong> to filter the dates:</p><pre><code>SELECT 
    PARSE_DATE('%Y%m%d', event_date) as dt,
    count(*) as cnt,
    avg(fn.get_param_int(event_params, "score")) as avg_score,
    avg(fn.get_param_int(event_params, "level")) as avg_level
FROM `firebase-public-project.analytics_153293282.events_*`
WHERE event_name = "post_score"
    AND _TABLE_SUFFIX between '20180701' and '20180731'
GROUP BY 1
ORDER BY 1</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!I80n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!I80n!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 424w, https://substackcdn.com/image/fetch/$s_!I80n!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 848w, https://substackcdn.com/image/fetch/$s_!I80n!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 1272w, https://substackcdn.com/image/fetch/$s_!I80n!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!I80n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png" width="998" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:998,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77134,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!I80n!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 424w, https://substackcdn.com/image/fetch/$s_!I80n!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 848w, https://substackcdn.com/image/fetch/$s_!I80n!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 1272w, https://substackcdn.com/image/fetch/$s_!I80n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4dafc378-bacb-4b7d-9fda-694818ea95d9_998x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JxIT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JxIT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 424w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 848w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 1272w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JxIT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png" width="998" height="406" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:406,&quot;width&quot;:998,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82389,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JxIT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 424w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 848w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 1272w, https://substackcdn.com/image/fetch/$s_!JxIT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F66713ff4-0c1c-4d4e-913c-1591e253cfd9_998x406.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This query returns only July&#8217;s data which I need, also it costs much less compared to querying all data.</p><p>I made another change in that query as well, instead of using event_date, I used the <strong>PARSE_DATE</strong> function because event_date is stored as a string, and it&#8217;s both hard to read and also impossible to apply date operations. So by using parse_date, we converted it to date datatype.</p><p>Even though it&#8217;s much easier to query now, we still need to know of the parameters name, datatype, etc. In the next article we&#8217;ll transform this table to make it easier and cheaper to query.</p><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.getbruin.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Bruin - Unified Analytics Platform! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Mythical Data Team]]></title><description><![CDATA[The first thing every company that wants to move towards a data-driven culture did was to hire the engineers of the thing they wished they did well, without thinking why.]]></description><link>https://blog.getbruin.com/p/the-mythical-data-team</link><guid isPermaLink="false">https://blog.getbruin.com/p/the-mythical-data-team</guid><dc:creator><![CDATA[Burak Karakan]]></dc:creator><pubDate>Tue, 06 Feb 2024 18:03:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Rw1d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Rw1d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Rw1d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Rw1d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Mythical Data Team&quot;,&quot;title&quot;:&quot;The Mythical Data Team&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Mythical Data Team" title="The Mythical Data Team" srcset="https://substackcdn.com/image/fetch/$s_!Rw1d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!Rw1d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8c189439-a9ed-4006-866a-bfc0be0beef8_1792x1024.webp 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The mythical "data teams" have been living their prime time over the past few years. The first thing every company that is moving towards a <em>data-driven culture</em> does is to hire engineers for the things they wished they did well, without thinking why.</p><p>It's like the "DevOps" of 2010s: everyone claims they <em>do it</em>, but everyone understands the role &#8211;or the philosophy, for that matter&#8211; differently.</p><p>The whole story revolves around this idea that the lifecycle of data is too complex &#8211;<em>it is!</em>&#8211; for analysts/scientists to manage &#8211;<em>not just for them, all of us!</em>&#8211;, therefore we drop these engineers from outside into a highly complex business environment, expecting them to deliver value using data right away.</p><p>Of course, this never works: engineering teams spend months building infrastructure, restructuring the data, and building tooling for things that might not even be used by the rest of the business. In the end, the company is out millions of dollars, and likely worse than where they were before.</p><h2><strong>Delivering without impact</strong></h2><p>The idea that data would be dealt with outside the rest of the business by throwing more engineers on it is a very old idea. It often plays out as follows:</p><ul><li><p>The company builds software and becomes successful in some way.</p></li><li><p>They generate a lot of data; although, not as a first-class citizen, always as an afterthought.</p></li><li><p>There'll be a Jane in marketing, and a Joe in sales who knows how to pull some data to Excel and get some numbers out. The data and the story it tells are still an afterthought.</p></li><li><p>The company grows further, but the "Jane"s and "Joe"s are not enough to serve the rest of the business. They decide to hire an analyst or two.</p><ul><li><p>Guess what? Data is still an afterthought.</p></li></ul></li><li><p>The analysts are trying to help the rest of the business, but are unable to keep up with all the demand and feel abandoned while trying to navigate the hot mess.</p></li><li><p>At some point, some exec will get mad at not being able to get some numbers and call the shots to build a data team.</p></li></ul><p>This is where things get nasty because an issue that is primarily a cultural matter is being tackled by the means of throwing people on it. The budgets are secured, the openings are posted, and the applications start flowing in, with no change in how to think about data.</p><p>The engineers that are hired jump straight into throwing solutions on problems that are not real problems, simply because that's what they can <em>influence</em> rather than what should be done. The ability to deliver results is euphoric, regardless of their impact. A complex infrastructure is built to move a CSV from Google Drive to S3, and the leaders feel accomplished: "<em>look at all this cloud bill we have! we are definitely data-driven.</em>"</p><p>Data, my friends, is <em>still</em> an afterthought.</p><h2><strong>Data as a core value</strong></h2><p>The reason that companies struggle with shifting away from the data being an afterthought mindset is the top-down approach towards getting value out of data: data is not like cash that a leader can decide how to use the best at the moment; on the contrary, <strong>data is like oil</strong>. Not in the sense of "<strong><a href="https://www.forbes.com/sites/nishatalagala/2022/03/02/data-as-the-new-oil-is-not-enough-four-principles-for-avoiding-data-fires/?sh=25cd5977c208">data is the new oil yay</a></strong>", but in the sense that it needs a lengthy and expensive process to bring out its value, and that requires deep investment. You know people, they don't love deep investments.</p><p>The first step in this process is to treat the data as an asset, just as any other asset the company has, not something nice to have. The good use of data can propel the business way further than any accounting process could, or any lawyer that can protect the company, therefore it needs to be treated with the same importance. Do you leave your bookkeeping unattended? Then you should not leave your data as well. This needs to propagate the ranks: the data is incredibly valuable, no data should be wasted, and it should be treated with utmost care.</p><p>Once the importance of the data is clear to the rest of the business, then comes the first tangible action to take: data is not a separate entity from the software organization, make them own it.</p><h2><strong>Own the damn data</strong></h2><p>I have seen it repeated countless times that data is being treated as if it is a separate thing from the rest of the software &#8211;and the team that builds it&#8211;, which means that there's a data analyst on one side trying to duct-tape a bunch of tables together in some weird drag-and-drop tool, while the software team just drops a full table from production the next day.</p><p>The organizations that have the healthiest data landscape are those that have a very clear understanding of data ownership: every bit of data that is produced/ingested/transformed/used must have an owner, no discussion. Do you own the service that writes to this database? You own the data. Do you own the internal events being generated on Kafka? You own the data. Do you join these billion different tables into a new table? You own the data.</p><p>The most important point here is that the software teams are aware that the data they produce is owned by them. This means that they will be responsible for a few core questions to be answered properly:</p><ul><li><p>How will this data be made available to the rest of the organization?</p></li><li><p>How will the quality of this data be ensured?</p></li><li><p>How would anyone notice if the data went corrupt? How quickly?</p></li><li><p>What is the change management process around this data?</p></li></ul><p>This means that the software teams will start treating their data just as they are treating their services. Not sure about your experience, but the quality of software services has been treated way higher than the quality of the data they produced in my experience, which means this is a win in my book.</p><h2><strong>Data as a product</strong></h2><p>There has been a large shift in the software world with the spread of concepts such as <strong><a href="https://martinfowler.com/bliki/DomainDrivenDesign.html">Domain-Driven Design</a></strong>, and the result ended up being domain-oriented services, owned by domain-focused teams, managing individual "products" of the larger product the company produces. This enabled ownership, independence, reliability, and more importantly the ability to deliver high-quality software quickly to become a competitive advantage. The data world is in for a similar transition.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IDfs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IDfs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IDfs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp" width="1456" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;An illustration that compares two different types of data teams: centralized and distributed&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="An illustration that compares two different types of data teams: centralized and distributed" title="An illustration that compares two different types of data teams: centralized and distributed" srcset="https://substackcdn.com/image/fetch/$s_!IDfs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 424w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 848w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 1272w, https://substackcdn.com/image/fetch/$s_!IDfs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F891a4ba6-194e-489c-816b-7989752fac64_1792x1024.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The data teams are in for a similar transition: the days of having a team called "data teams" are over. Any sufficiently large software team has noticed the drawbacks of having isolated functional teams, and instead transitioning towards having cross-functional, agile teams, and the same principle applies to data teams. Instead of having a siloed team that takes in the data everyone else in the company produces and tries to make sense of it, the data team should be distributed among the business teams.</p><p>The mindset of the business teams started shifting towards treating data as an end-to-end product, and the associated rise in quality that comes with that. The organization treats data as part of its core product, and applies the appropriate measures to building, changing, governing, and protecting it.</p><p>This requires a rethinking of the structure of the data team:</p><ul><li><p>The team is transparent and spread across the whole organization.</p></li><li><p>The data people within the organization work very closely with the business and product teams, <strong>no more siloes</strong>.</p></li><li><p>The data team needs fewer engineers, more analysts &amp; scientists who understand the business context.</p></li></ul><p>In the end, you do not have a central data team, you have an organization that speaks data on all levels, across all teams.</p><h2><strong>This will take time, and it's fine</strong></h2><p>Shifting the whole data-as-an-afterthought mindset to making it a central beat of the company's heart is kind of like finally deciding to clean up that one junk drawer in your kitchen. You know it&#8217;s going to be a mess, and it&#8217;s way easier to just keep shoving stuff in there, but once you get it sorted, finding batteries or that one specific takeout menu becomes a breeze. It&#8217;s all about making data not just something you do, but a part of who you are as a company.</p><p>The real shift in terms of value generated from the data will come once the organizations internalize this change in the mindset.</p>]]></content:encoded></item><item><title><![CDATA[Exporting Firebase Data to BigQuery]]></title><description><![CDATA[Moving the Firebase data to BigQuery is a great way to get more out of your data, and here's how to do it.]]></description><link>https://blog.getbruin.com/p/exporting-firebase-data-to-bigquery</link><guid isPermaLink="false">https://blog.getbruin.com/p/exporting-firebase-data-to-bigquery</guid><dc:creator><![CDATA[Sabri Karagonen]]></dc:creator><pubDate>Mon, 22 Jan 2024 17:53:00 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!vBXN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Lately, I've been in touch with several startup folks, especially those in mobile gaming and app development. One common headache? Understanding what users are up to. It's a challenge many face, but there's a solution in town&#8212;Firebase Analytics, courtesy of Google.</p><ol><li><p><strong>Backed by Google:</strong> Firebase Analytics isn't your average analytics tool. It's built on the foundation of Google's internal solutions for app challenges, refined and available for everyone.</p></li><li><p><strong>Seamless Google Analytics Integration:</strong> Firebase and Google Analytics are buddies. Whatever you track in Firebase, you can seamlessly analyze in Google Analytics. The best part? It's user-friendly, no need for a tech whiz; your product manager can handle it.</p></li><li><p><strong>Comprehensive Toolbox:</strong> Firebase is more than just an analytics tool. It handles errors, secures user data, allows for remote config adjustments, and even offers A/B testing. It's a holistic solution for refining and perfecting your app's operation.</p></li><li><p><strong>Industry Standard with Community Support:</strong> Many other apps, similar to yours, use it. That means a supportive community and ample resources to tap into when challenges arise.</p></li><li><p><strong>Cost-Effective:</strong> In a landscape where similar tools come with a hefty price tag, Firebase stands out. Oh, and did I mention it's free? Google's offering it without a bill attached, making it an attractive choice for budget-conscious startups.</p></li></ol><p>Now, let's dive a bit deeper. As a bonus, we'll explore how to export your Firebase Analytics data to BigQuery, taking your insights to the next level. Ready to get hands-on? Let's jump into the how-to.</p><h2><strong><a href="https://getbruin.com/blog/exporting-firebase-data-to-bigquery#exporting-firebase-analytics-data-to-bigquery-recommended-settings">Exporting Firebase Analytics Data to BigQuery: Recommended Settings</a></strong></h2><p>Moving forward, I'll walk you through the recommended settings for exporting your Firebase Analytics data to BigQuery. To avoid redundancy, we won't replicate the instructions available in the official documentation <strong><a href="https://firebase.google.com/docs/projects/bigquery-export">here</a></strong>, which covers the initial setup:</p><blockquote><ul><li><p>Go to the <a href="https://console.firebase.google.com/project/_/settings/integrations">Integrations</a> page in the Firebase console.</p></li><li><p>In the BigQuery card, click Link.</p></li><li><p>Follow the on-screen instructions to enable BigQuery.</p></li></ul></blockquote><p>With those initial steps covered, let's now explore additional settings to optimize your data export process:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vBXN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vBXN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 424w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 848w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 1272w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vBXN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png" width="845" height="424" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:424,&quot;width&quot;:845,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;BigQuery Export Settings&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="BigQuery Export Settings" title="BigQuery Export Settings" srcset="https://substackcdn.com/image/fetch/$s_!vBXN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 424w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 848w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 1272w, https://substackcdn.com/image/fetch/$s_!vBXN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98977e44-9c87-43ab-8efd-14ad4dc67cd6_845x424.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ol><li><p><strong>Region:</strong> Consider regulations like GDPR in Europe, CCPA in the US, or KVKK in Turkey when choosing a region to store your data.</p></li><li><p><strong>Export Frequency:</strong> Firebase has its quirks with batch processing, like a daily limit of 1 million events. Instead, I recommend the more real-time Streaming option. Yes, it's a bit pricier, but the pros outweigh the cons, especially if you're aiming for almost real-time data.</p></li><li><p><strong>Advertising Identifiers:</strong> Device tracking can be tricky, making it smart to have IDFA/IDFV and GPS-Adid for debug purposes. Enabling advertising IDs also empowers you for future data integration, particularly when dealing with various data sources such as marketing (MMPs like Adjust/Appsflyer, ad networks like Facebook/Google/TikTok), or revenue data.</p></li></ol><p>With data in BigQuery, our journey progresses. In the forthcoming article, we'll shift our focus to understanding Firebase data in BigQuery. Get ready for a detailed exploration of how data looks in BigQuery and practical strategies for leveraging its power for a deeper understanding of your app's performance.</p>]]></content:encoded></item></channel></rss>