<?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[Cauchy's stories]]></title><description><![CDATA[Lessons from building data and AI systems with AI.]]></description><link>https://blog.cauchy.io</link><image><url>https://substackcdn.com/image/fetch/$s_!BWPo!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0da85095-5863-4a4d-af11-e7b2cd7bed8e_422x422.png</url><title>Cauchy&apos;s stories</title><link>https://blog.cauchy.io</link></image><generator>Substack</generator><lastBuildDate>Thu, 16 Apr 2026 03:42:46 GMT</lastBuildDate><atom:link href="https://blog.cauchy.io/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Cauchy.io]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[info@cauchy.io]]></webMaster><itunes:owner><itunes:email><![CDATA[info@cauchy.io]]></itunes:email><itunes:name><![CDATA[Cauchy]]></itunes:name></itunes:owner><itunes:author><![CDATA[Cauchy]]></itunes:author><googleplay:owner><![CDATA[info@cauchy.io]]></googleplay:owner><googleplay:email><![CDATA[info@cauchy.io]]></googleplay:email><googleplay:author><![CDATA[Cauchy]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Can I trust what I have not traced? ]]></title><description><![CDATA[The interface that builds my trust (Dashboards) isn&#8217;t the interface preferred by my users (Genie).]]></description><link>https://blog.cauchy.io/p/can-i-trust-what-i-have-not-traced</link><guid isPermaLink="false">https://blog.cauchy.io/p/can-i-trust-what-i-have-not-traced</guid><dc:creator><![CDATA[Eirini Papakosta]]></dc:creator><pubDate>Wed, 01 Apr 2026 19:01:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!MuuL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.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_!MuuL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MuuL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 424w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 848w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 1272w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MuuL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png" width="540" height="364.6351931330472" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:944,&quot;width&quot;:1398,&quot;resizeWidth&quot;:540,&quot;bytes&quot;:2234468,&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;:&quot;https://blog.cauchy.io/i/191016256?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MuuL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 424w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 848w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.png 1272w, https://substackcdn.com/image/fetch/$s_!MuuL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fb835a7-ae75-401c-a552-7bc773f44f63_1398x944.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>In my previous blog, I investigated how easy it is to migrate a Power BI report (with the semantic model) to AI/BI dashboards. One comment stood out:</p><blockquote><p><em>&#8220;Very cool. I&#8217;m curious how Genie can then be used to answer questions directly based on the semantic model or the visuals? Also, is there any &#8216;Narrative&#8217; feature like Power BI has now to generate an executive summary? This would be super useful as to be honest nobody wants to interpret visuals anymore, we only care about getting our BI questions answered straight to the point.&#8221;</em></p></blockquote><p>That comment resonated not because it&#8217;s universally true, but because it reflects a real frustration. Research shows that 41% of business leaders don&#8217;t understand their data because it&#8217;s too complex, and 70% of BI users stick to less than 10% of available features out of confusion. So then, is natural language the answer? Can Databricks Genie do it better? Can it get to the point faster? As someone who has worked as a data analyst, this raised a question I couldn&#8217;t shake.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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><strong>Can I trust insights I didn&#8217;t earn?</strong></p><h3><strong><br></strong>The Analyst&#8217;s Dilemma</h3><p>I earn my insights. I build the dashboard choosing the measures, setting the filters, validating the numbers against what I know to be true. By the time I present a visualization, I&#8217;ve traced every number back to its source. The insight isn&#8217;t just shown; it&#8217;s verified through the act of creation.</p><p>But Genie changes this. It generates the visualization. It writes the SQL. It gives me the answer in seconds. And I&#8217;m left wondering: is this right? Not because Genie is wrong but because I didn&#8217;t build it. I didn&#8217;t earn it.</p><p>Of course, research tells me I might be fooling myself. Studies show that manual work can breed overconfidence that the labor of building doesn&#8217;t guarantee accuracy, just the feeling of it. And users of automated systems fall into the opposite trap: trusting outputs without scrutiny. Both can be wrong. Both can be right.</p><p>Business users don&#8217;t share my hesitation. For them, natural language is liberation no more filters, no more dropdowns, no more waiting for the analyst. They ask, they understand, they act.</p><p>So here&#8217;s my conflict: the interface that builds my trust isn&#8217;t the interface that serves my users.</p><h3>What Research Says About Trust</h3><p>Research on human-AI collaboration offers a reframe. Studies on &#8220;complementary expertise&#8221; show that users calibrate their trust in AI for unfamiliar tasks based on how accurately it performs on tasks they <em>can</em> verify (Pareek et al., 2024).</p><p>This is exactly my situation. I know the dashboard. I built the measures, validated the logic, tested the edge cases. If I ask Genie the same questions and it gives me the same answers, I can extend that trust to questions I haven&#8217;t personally verified. My expertise becomes the calibration mechanism.</p><p>There are also two distinct types of trust at play. Verification trust the kind I build through dashboards comes from seeing the data, tracing the lineage, checking the math. Delegation trust the kind business users need comes from understanding the explanation and believing the reasoning (Datameer, 2022). One is earned through labor; the other through transparency.</p><p>Here&#8217;s the connection: I can&#8217;t personally verify every answer Genie gives to every user. But I <em>can</em> verify the foundation Genie draws from the semantic layer. When metric definitions are centralized, governed, and versioned, I verify the logic once. Genie inherits it every time. The dashboard and Genie draw from the same source of truth. My verification trust becomes the infrastructure for their delegation trust.</p><p>And the research supports this approach: semantic layers, centralized, governed definitions of business metrics, reduce LLM hallucinations by over 50% and push text-to-SQL accuracy toward 99.8% (Atlan, 2026). Which means, the foundation matters more than the interface.</p><h2>The Hypothesis</h2><p>So here&#8217;s my hypothesis: the dashboard doesn&#8217;t compete with Genie, it enables it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img processing" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZiQ_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 424w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 848w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 1272w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif" width="1456" height="811" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:811,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:12256088,&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;:&quot;https://blog.cauchy.io/i/191016256?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif&quot;,&quot;isProcessing&quot;:true,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 424w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 848w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.gif 1272w, https://substackcdn.com/image/fetch/$s_!ZiQ_!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cffe79c-70bf-49db-8db3-39517caf4254_1920x1069.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>If I validate the semantic model through dashboard interaction, I create the trust infrastructure that allows business users to safely delegate to Genie. The dashboard becomes the audit trail where I verify definitions, test edge cases, and build my confidence. Genie becomes the interface where users ask questions in natural language and receive answers I&#8217;ve already validated.</p><p style="text-align: center;">The analyst earns the trust. The user inherits it.</p><h2>What&#8217;s Next</h2><p>In the next posts, I&#8217;ll test this hypothesis. </p><ol><li><p>Migrating the interpretation from Power BI semantic model to Databricks Genie: Using Claude and the Power BI Semantic Model MCP, I&#8217;ll extract insights from a dashboard and migrate them to a Databricks Genie space deploying with BrickKit (library from Cauchy),</p></li><li><p>Lets get technical:  Metric views is the key, translating DAX to Metric Views, and converting RLS to Unity Catalog row filters.</p></li></ol><p>Testing: Same data. Same questions. Different interface. Does the trust transfer?</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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 FinOps Guide to Databricks: From System Tables to Chargeback]]></title><description><![CDATA[Your monthly Databricks invoice is a single number. With this guide you can break it down.]]></description><link>https://blog.cauchy.io/p/the-complete-guide-to-databricks</link><guid isPermaLink="false">https://blog.cauchy.io/p/the-complete-guide-to-databricks</guid><dc:creator><![CDATA[Casper Lubbers]]></dc:creator><pubDate>Thu, 26 Mar 2026 06:28:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e2985875-c717-4aa3-93ed-70adea1f156a_800x751.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Your monthly Databricks invoice is a single number. Behind it are dozens of services, each with different billing mechanics, different tagging surfaces, and different levels of visibility in system tables. A SQL warehouse bills in DBUs per hour, which is straightforward enough, but a Vector Search index is a different story: the endpoint that serves queries bills through the inference SKU while the background process that keeps the index in sync with your Delta table bills as serverless jobs, and these show up as entirely separate line items on your bill. Then there are services like Genie workspaces that have no billing SKU of their own and quietly bill through whatever SQL warehouse sits underneath them. The further you look, the more you find that Databricks billing is less a flat list of services and more a web of dependencies where one resource&#8217;s cost shows up under another resource&#8217;s meter.</p><p>This guide is a reference for untangling that web. It covers how Databricks billing works, how to tag every service for cost attribution, how to query system tables for cost breakdowns, and how to bridge the visibility gap when your account spans multiple regions or metastores.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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><strong>Who this is for:</strong></p><ul><li><p><strong>Developers</strong> &#8212; Sections 1-3: understand what you&#8217;re being billed for and how to tag your resources</p></li><li><p><strong>Platform engineers</strong> &#8212; Sections 3-7: enforce tagging, query system tables, bridge multi-metastore gaps, dashboards</p></li><li><p><strong>Finance / FinOps teams</strong> &#8212; Sections 2, 7, and 8: cost allocation models, dashboards, reporting, chargeback</p></li><li><p><strong>Management</strong> &#8212; Sections 2 and 9: cost landscape, key observations, action items</p></li></ul><p>One caveat before we start. System tables have no SLA. Data typically arrives hours after actual usage. If you need real-time operational cost insight, system tables are not the mechanism. They are for retrospective analysis and reporting.</p><div><hr></div><h2>1. How Databricks billing works</h2><p>Databricks costs consist of two components: what Databricks charges you, and what your cloud provider charges you. The cloud provider bill covers the infrastructure that Databricks runs on, things like VMs, storage accounts, and networking. The Databricks bill covers the software layer on top of that. When you spin up a cluster, Databricks provisions VMs in your cloud account and runs its software on them. Your monthly bill will show both the Databricks charge and the cloud provider charge for those VMs. This guide focuses on the Databricks side, which is where the complexity in cost attribution lives.</p><h3>The DBU</h3><p>Databricks uses the Databricks Unit (DBU) as its internal billing currency. A DBU represents a unit of processing capacity per hour, and the price of a single DBU varies depending on the service, the workspace tier (Standard vs Premium), and the cloud region. This means that a DBU consumed by a job cluster costs less than a DBU consumed by an all-purpose cluster, even though both are measured in the same unit. The DBU is not a fixed-price token. It is a billing meter whose rate changes based on context.</p><p>Most Databricks services bill in DBUs, but not all. Databricks uses six distinct billing units across its product surface:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yfDB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yfDB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yfDB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png" width="1371" height="299" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:299,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41839,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yfDB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!yfDB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20e9e90c-8da4-4da3-9737-5fb0ded61bf1_1371x299.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>For most organisations, DBUs will dominate the bill. But storage and networking costs are easy to overlook, especially in architectures that use cross-region replication or Delta Sharing. These show up as DSU and GB charges respectively, and they can become meaningful at scale.</p><h3>List prices and what you actually pay</h3><p>Every SKU has a list price, visible in <code>system.billing.list_prices</code>. This is the baseline. Your actual price may differ because of negotiated discounts, promotional pricing, or credits. The system table shows both a <code>default</code> price and an <code>effective_list</code> price. The effective list price reflects promotions. Neither reflects your negotiated rate.</p><p>This distinction matters for every dashboard and report you build downstream. Be explicit about which price basis you use. Joining usage to list prices without this context will produce numbers that don&#8217;t match your invoice.</p><h3>What generated the cost vs how it&#8217;s priced</h3><p>There is a second distinction that is equally important and far less obvious. Every record in <code>system.billing.usage</code> has two fields that look like they should tell you the same thing but don&#8217;t: <code>billing_origin_product</code> and <code>sku_name</code>.</p><p><code>billing_origin_product</code> tells you <strong>what generated the cost</strong>. Vector Search, Predictive Optimization, AI Functions, Lakehouse Apps. It is the service that consumed the resource.</p><p><code>sku_name</code> tells you <strong>how that consumption is priced</strong>. It maps to a row in <code>system.billing.list_prices</code>. It is the billing meter.</p><p>These are different dimensions. Many services do not have their own SKU. They bill through an existing one:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xr9A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xr9A!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 424w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 848w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 1272w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xr9A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png" width="1371" height="378" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:378,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56862,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xr9A!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 424w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 848w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.png 1272w, https://substackcdn.com/image/fetch/$s_!xr9A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ba0d3a4-f7ad-4fa5-bd15-fe11ada15bf1_1371x378.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 has three practical consequences:</p><ol><li><p><strong>You will not find these services in </strong><code>list_prices</code><strong>.</strong> If you query <code>list_prices</code> for a &#8220;Vector Search&#8221; SKU, you get nothing. The price is the regional <code>SERVERLESS_REAL_TIME_INFERENCE</code> rate.</p></li><li><p><strong>Grouping by </strong><code>sku_name</code><strong> alone hides what&#8217;s driving cost.</strong> Your &#8220;serverless jobs&#8221; spend might actually be Vector Search index maintenance, Predictive Optimization, or Data Classification running in the background. Always include <code>billing_origin_product</code> in your cost reports.</p></li><li><p><strong>A single service can bill through multiple SKUs.</strong> Vector Search uses <code>SERVERLESS_REAL_TIME_INFERENCE</code> for endpoint serving and <code>JOBS_SERVERLESS_COMPUTE</code> for index sync. Lakebase uses <code>DATABASE_SERVERLESS_COMPUTE</code> for queries, <code>DATABRICKS_STORAGE</code> for persistence, and <code>JOBS_SERVERLESS_COMPUTE</code> for maintenance. One service, three billing lines.</p></li></ol><p>The cost landscape table in the next section is organised by <code>billing_origin_product</code>. The price column shows which <code>sku_name</code> applies.</p><div><hr></div><h2>2. The cost landscape: every service and what it costs</h2><blockquote><p><strong>For: Everyone</strong></p></blockquote><p>The table below maps every Databricks service to its SKU, billing unit, and current list price. Prices are from <code>system_union.billing.list_prices</code> as of March 2026, USD. Regional variants are collapsed to ranges.</p><h3>Compute</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L96c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L96c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!L96c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!L96c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!L96c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L96c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png" width="1371" height="339" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:339,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:61329,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L96c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!L96c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!L96c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!L96c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F06478bf2-da11-4899-b937-de52b77ba92a_1371x339.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Job compute at $0.30/DBU vs all-purpose at $0.55/DBU is the single largest cost optimisation available to most teams. If a workload can run as a job, it should.</p><p>Serverless compute appears more expensive ($0.45-$0.65 vs $0.30 for classic jobs), but the comparison is misleading. Serverless pricing includes the VM cost. Classic compute pricing does not. Your cloud provider bills you separately for the underlying VMs. The true cost comparison depends on your VM sizing and utilisation.</p><h3>SQL Warehouses</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iXsV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iXsV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iXsV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png" width="1371" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:26240,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iXsV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!iXsV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdcf1b3e2-8d42-49b7-8718-5905044975e2_1371x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Classic SQL at $0.22 is flat across regions. Pro and serverless are regional. The jump from classic to Pro ($0.22 &#8594; $0.55+) is significant. Know which tier your warehouses are running.</p><h3>DLT / Lakeflow Pipelines</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6oI3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6oI3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6oI3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png" width="1371" height="181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:181,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:19832,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6oI3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!6oI3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c4f05a7-82ad-43f8-a52d-7ab7fa07ab32_1371x181.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>DLT pricing is tier-based, not region-based. Core ($0.30) is the same as job compute. Pro ($0.38) adds CDC and expectations. Advanced ($0.54) adds flow-level lineage. Photon variants exist at the same price points. Standard tier is identical to Premium for DLT.</p><h3>AI/ML Serving</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z5Y4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png" width="1371" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29344,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!Z5Y4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F43c138d8-52a9-45fe-91e6-030c8cbdd53d_1371x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Foundation model APIs bill in DBUs, not per token, in the list prices table. The per-token cost is derived from how many DBUs a given model consumes per request.</p><h3>Vector Search</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UJ_d!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UJ_d!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UJ_d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png" width="1371" height="181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:181,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:41913,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UJ_d!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!UJ_d!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fced02cb8-092f-4f81-aba9-906e789b0693_1371x181.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Vector Search has three billing components. The endpoint that serves queries bills through the inference SKU. The background process that syncs the index from the source Delta table bills as serverless jobs. And the index itself incurs storage costs as DSU, with a minimum of 4GB per endpoint regardless of actual index size. All three lines carry <code>billing_origin_product = 'VECTOR_SEARCH'</code> but at different prices because the <code>sku_name</code> differs.</p><p>The index sync cost deserves particular attention because it depends on the trigger configuration. If Delta Sync is set to <strong>continuous</strong>, the sync process runs permanently and bills continuously at the serverless jobs rate ($0.45-$0.65/DBU). If set to <strong>triggered</strong> (on-demand), it runs only when explicitly invoked or on a schedule. For tables with infrequent updates, triggered sync is significantly cheaper. For tables with high write frequency where freshness matters, continuous sync is appropriate but the cost scales with both table size and write volume. This is one of the most common sources of unexpectedly high Vector Search bills.</p><h3>AI Services</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vxrx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vxrx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vxrx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png" width="1371" height="181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:181,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:38387,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Vxrx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!Vxrx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb005051-48e9-4fab-88ac-1da824d54b70_1371x181.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>AI Functions deserve specific attention. Every <code>ai_query()</code> call in a SQL query or notebook bills through the inference SKU. On a shared SQL warehouse running dashboards that use <code>ai_query()</code>, this can be a significant and unexpected cost driver because it&#8217;s not visible in the warehouse&#8217;s DBU consumption &#8212; it appears as a separate billing line with <code>billing_origin_product = 'AI_FUNCTIONS'</code>.</p><h3>Model Training</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!suOf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!suOf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!suOf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!suOf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!suOf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!suOf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png" width="1371" height="181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:181,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24432,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!suOf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 424w, https://substackcdn.com/image/fetch/$s_!suOf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 848w, https://substackcdn.com/image/fetch/$s_!suOf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 1272w, https://substackcdn.com/image/fetch/$s_!suOf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc1bb2ad6-1187-4fce-8700-637441d688fc_1371x181.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>Lakebase</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CPd4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CPd4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 424w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 848w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 1272w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CPd4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png" width="1371" height="102" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:102,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:16460,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CPd4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 424w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 848w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 1272w, https://substackcdn.com/image/fetch/$s_!CPd4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c92cc-2852-4467-b214-ff743e660ff2_1371x102.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Lakebase is Databricks&#8217; managed PostgreSQL-compatible database, now GA. The effective list price is roughly 50% of the default price. This is a promotional rate that has carried through from preview into GA, so it is the actual price you should use for cost estimation.</p><p>Lakebase billing is purely serverless. There is no provisioned capacity option. Costs scale with query volume and complexity. In addition to the compute DBU charge, Lakebase also incurs <code>DATABRICKS_STORAGE</code> (DSU) for data persistence and <code>JOBS_SERVERLESS_COMPUTE</code> for background maintenance tasks. These show up as separate billing lines with <code>billing_origin_product = 'LAKEBASE'</code>, so you can filter and track the full cost of the service.</p><h3>Storage, Networking, Other</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qG8u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qG8u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qG8u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png" width="1371" height="299" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:299,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:39117,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qG8u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!qG8u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8547afec-dd32-4b41-b626-4e5511d85f0c_1371x299.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Networking costs add up with Delta Sharing and cross-region replication. Inter-region egress at $0.02-$0.16/GB is worth monitoring if your architecture spans regions.</p><h3>Platform &amp; Background Services</h3><p>These services run automatically or in the background. They have no dedicated SKU &#8212; they bill through existing serverless SKUs. Because they lack dedicated pricing, they are easy to overlook. But collectively, they can account for meaningful spend.Predictive Optimization is the one to watch. It runs continuously in the background once enabled, compacting and optimising tables. In an account with many tables, this becomes a visible line item. You can track it by filtering <code>billing_origin_product = 'PREDICTIVE_OPTIMIZATION'</code> and decide whether the optimisation benefit justifies the cost per catalog.</p><p>Data Classification is similar &#8212; automatic scanning that bills as serverless jobs. If you&#8217;ve enabled it on large catalogs, check the spend.</p><div><hr></div><h2>3. Tagging: what you can tag and how</h2><blockquote><p><strong>For: Developers, Platform Engineers</strong></p></blockquote><p>Cost attribution in Databricks comes down to one thing: getting the right tags onto the right resources so they appear in <code>system.billing.usage.custom_tags</code>. This section covers what you can tag, how to tag it, and where tags end up.</p><p>An entire overview (to be published soon as interactive HTML) of the various component and how they appear and where:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nnkr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nnkr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 424w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 848w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 1272w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nnkr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png" width="1456" height="910" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:910,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:867003,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Nnkr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 424w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 848w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.png 1272w, https://substackcdn.com/image/fetch/$s_!Nnkr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe3b19c2d-11f2-4bf1-9204-0d85686f0b42_5120x3200.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><h3>Classic compute resources</h3><p><strong>All-purpose clusters</strong> are the most straightforward. Set <code>custom_tags</code> as a key-value map when creating or editing the cluster. Available in the UI (Compute &#8594; Advanced &#8594; Tags), via the Clusters API, Terraform (<code>databricks_cluster.custom_tags</code>), and DABs (<code>clusters[].custom_tags</code>). Tags take effect at cluster start and require a restart to update.</p><p><strong>Job clusters</strong> accept tags at two levels. The job definition has a <code>tags</code> map (max 25) that propagates to any job clusters created during runs. The <code>new_cluster</code> spec within a job also accepts <code>custom_tags</code>. Both flow into billing records. Databricks auto-applies <code>RunName</code> and <code>JobId</code> as default tags on every job cluster.</p><pre><code><code># DABs example: job with tags
resources:
  jobs:
    etl_daily:
      tags:
        team: data-engineering
        cost_center: "9531"
        environment: production
      tasks:
        - task_key: ingest
          new_cluster:
            custom_tags:
              workload: ingestion
</code></code></pre><p><strong>DLT pipelines</strong> accept tags at the pipeline level (max 25, Public Preview) and at the cluster level within the pipeline spec. Pipeline tags are forwarded to the underlying clusters. DLT has three pricing tiers: Core ($0.30/DBU), Pro ($0.38), and Advanced ($0.54). The SKU in your billing records tells you which tier is running.</p><pre><code><code># Terraform example: DLT pipeline with tags
resource "databricks_pipeline" "etl" {
  name = "etl-pipeline"

  tags = {
    team        = "data-engineering"
    cost_center = "9531"
  }

  cluster {
    custom_tags = {
      environment = "production"
    }
  }
}
</code></code></pre><p><strong>Instance pools</strong> use the same <code>custom_tags</code> map (max 43 on AWS). This matters more than it might seem. On AWS and Azure, when a cluster launches from a pool, only pool and workspace tags propagate to cloud resources. Cluster tags do not. If your finance team uses AWS Cost Explorer or Azure Cost Analysis, cost attribution tags must be on the pool, not the cluster.</p><h3>SQL warehouses</h3><p>SQL warehouses use a different tag structure from clusters. The API expects a <code>tags</code> object containing a <code>custom_tags</code> array of <code>{key, value}</code> objects. In Terraform, this becomes a nested block syntax:</p><pre><code><code># Terraform: SQL warehouse tags (note the nested syntax)
resource "databricks_sql_endpoint" "analytics" {
  name             = "analytics-warehouse"
  cluster_size     = "Small"
  warehouse_type   = "PRO"

  tags {
    custom_tags {
      key   = "team"
      value = "analytics"
    }
    custom_tags {
      key   = "cost_center"
      value = "9921"
    }
  }
}
</code></code></pre><p>This structural difference from clusters is a common source of configuration errors when teams write Terraform modules that try to handle both.</p><p>For query-level attribution on shared warehouses, use query tags: <code>SET QUERY_TAGS['team'] = 'marketing'</code>. These appear in <code>system.query.history.query_tags</code> (Public Preview) and enable proportional cost allocation across teams sharing a warehouse.</p><h3>Serverless resources</h3><p>Serverless compute runs on Databricks-managed infrastructure. There are no cloud resources in your account to tag. The tagging mechanism is the <strong>serverless budget policy</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!343N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!343N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 424w, https://substackcdn.com/image/fetch/$s_!343N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 848w, https://substackcdn.com/image/fetch/$s_!343N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 1272w, https://substackcdn.com/image/fetch/$s_!343N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!343N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png" width="1456" height="930" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:930,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:153813,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!343N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 424w, https://substackcdn.com/image/fetch/$s_!343N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 848w, https://substackcdn.com/image/fetch/$s_!343N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.png 1272w, https://substackcdn.com/image/fetch/$s_!343N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61d43a4e-3330-43ff-b085-dd13bb76cf29_1804x1152.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>A budget policy defines custom tag key-value pairs (max 20). You assign the policy to users, groups, or service principals. When an assigned user runs a serverless workload, the policy&#8217;s tags appear in <code>system.billing.usage.custom_tags</code> and the policy ID is stored in <code>usage_metadata.budget_policy_id</code>.</p><p>Budget policies apply to: serverless notebooks, serverless jobs, serverless pipelines, model serving endpoints, and Vector Search endpoints.</p><pre><code><code># Terraform: serverless budget policy
resource "databricks_budget_policy" "data_engineering" {
  custom_tags = [
    { key = "team", value = "data-engineering" },
    { key = "cost_center", value = "9531" },
    { key = "environment", value = "production" }
  ]
}
</code></code></pre><p>In DABs, serverless jobs can reference a budget policy directly:</p><pre><code><code>resources:
  jobs:
    serverless_etl:
      budget_policy_id: ${var.budget_policy_id}
      tags:
        team: data-engineering
</code></code></pre><p>Key rules to know: </p><p>- If a user has only one policy assigned, it auto-applies to new serverless resources. </p><p>- If multiple policies are assigned, the user must choose. Default is alphabetical first. </p><p>- If a notebook runs inside a job, the job&#8217;s budget policy applies. The notebook&#8217;s policy is ignored. </p><p>- Pipeline tag updates in Development mode take 24 hours to propagate.</p><h3>AI/ML services</h3><p><strong>Model serving endpoints</strong> accept both <code>tags</code> (array of <code>{key, value}</code>) and a <code>budget_policy_id</code>. Tags auto-propagate to billing logs. Available in the UI, API, Terraform, and DABs.</p><p><strong>Vector Search endpoints</strong> support only <code>budget_policy_id</code>. No direct custom tags. Both the serving component (<code>SERVERLESS_REAL_TIME_INFERENCE</code> SKU) and the index sync component (<code>JOBS_SERVERLESS_COMPUTE</code> SKU) carry <code>billing_origin_product = 'VECTOR_SEARCH'</code>, so you can filter for all Vector Search costs. The endpoint&#8217;s <code>budget_policy_id</code> propagates to the serving lines. The index sync lines also carry the <code>budget_policy_id</code>.</p><p><strong>Foundation model APIs</strong> (Anthropic, OpenAI, Gemini) bill through the serving endpoint. Tag the endpoint.</p><p><strong>AI Functions, AI Gateway, Agent Evaluation</strong> &#8212; These services bill through <code>SERVERLESS_REAL_TIME_INFERENCE</code> and are not directly taggable. AI Functions (<code>ai_query()</code> calls) inherit context from the SQL warehouse or notebook that invoked them. To attribute these costs, filter by <code>billing_origin_product</code> and correlate with the workspace and time window.</p><h3>Platform services that are not taggable</h3><p>Several background services generate cost but have no tagging surface:</p><ul><li><p><strong>Predictive Optimization</strong> &#8212; bills as <code>JOBS_SERVERLESS_COMPUTE</code>. Not taggable. Attribute by <code>billing_origin_product</code>.</p></li><li><p><strong>Data Classification</strong> &#8212; bills as <code>JOBS_SERVERLESS_COMPUTE</code>. Not taggable. Attribute by <code>billing_origin_product</code>.</p></li><li><p><strong>Lakehouse Monitoring</strong> &#8212; bills as <code>JOBS_SERVERLESS_COMPUTE</code>. Auto-tagged with <code>LakehouseMonitoringTableId</code> and related keys.</p></li><li><p><strong>Lakehouse Apps</strong> &#8212; bills as <code>ALL_PURPOSE_SERVERLESS_COMPUTE</code>. Supports <code>budget_policy_id</code>. Identified via <code>usage_metadata.app_name</code>.</p></li><li><p><strong>Fine-Grained Access Control</strong> &#8212; bills as <code>JOBS_SERVERLESS_COMPUTE</code>. Not taggable. Attribute by <code>billing_origin_product</code>.</p></li></ul><p>For these services, <code>billing_origin_product</code> is the only reliable cost attribution mechanism. Include it in every cost report.</p><h3>Workspace-level tags</h3><p>Workspace tags propagate to all compute within the workspace. Set via the Account API or Azure ARM resource group tags. Useful for account-wide defaults like <code>org</code> or <code>account_id</code>. Propagation takes up to one hour, and existing resources need a restart.</p><div><hr></div><h2>4. Tag enforcement: from optional to mandatory</h2><blockquote><p><strong>For: Platform Engineers</strong></p></blockquote><p>Tags only work for cost attribution if they&#8217;re consistently applied. Left to individual developers, tagging is inconsistent. Platform teams need enforcement mechanisms.</p><h3>Compute policies</h3><p>Compute policies are the strongest enforcement lever for classic compute. They control what developers can and cannot configure when creating clusters. For tags, three policy types matter:</p><pre><code><code>{
  "custom_tags.cost_center": {
    "type": "allowlist",
    "values": ["9999", "9921", "9531"]
  },
  "custom_tags.team": {
    "type": "fixed",
    "value": "data-engineering"
  },
  "custom_tags.environment": {
    "type": "unlimited"
  }
}
</code></code></pre><ul><li><p><code>"type": "fixed"</code> &#8212; sets an immutable value. Users cannot change it. Use for tags that should always be the same within a policy (e.g. team name).</p></li><li><p><code>"type": "unlimited"</code> &#8212; requires the tag but allows any value. Use for tags where users need to provide input (e.g. project name).</p></li><li><p><code>"type": "allowlist"</code> &#8212; restricts to a predefined set. Use for cost centers or environments where values must match your finance taxonomy.</p></li></ul><p>If a user tries to create a cluster without a required tag, creation fails. This is the enforcement. No tag, no cluster.</p><p>One limitation: there is no equivalent enforcement for job-level tags. Compute policies apply to clusters, not jobs. Job tags cannot be made mandatory through policy controls.</p><h3>Serverless budget policies</h3><p>For serverless compute, budget policies are the enforcement mechanism. Create policies with the required tags, assign them to users or groups, and serverless usage gets tagged automatically. The platform team&#8217;s job is to ensure every user has an appropriate policy assigned.</p><h3>Enforcement maturity</h3><p>A practical progression:</p><ol><li><p><strong>Crawl</strong> &#8212; Recommend tags. Report on untagged percentage. No enforcement.</p></li><li><p><strong>Walk</strong> &#8212; Enforce via compute policies. Create budget policies for serverless. Monitor compliance.</p></li><li><p><strong>Run</strong> &#8212; Deny untagged compute via IAM-level controls (AWS). Achieve &gt;90% allocation coverage.</p></li></ol><p>Track &#8220;allocated %&#8221; as a governance KPI. It tells you what fraction of your spend can be attributed to an owner. Start measuring it early.</p><div><hr></div><h2>5. Reading the bill: system tables for cost attribution</h2><blockquote><p><strong>For: Developers, Platform Engineers</strong></p></blockquote><h3>The core join</h3><p>Everything starts with <code>system.billing.usage</code> joined to <code>system.billing.list_prices</code>. Get this join wrong and every downstream number is wrong.</p><pre><code><code>SELECT
  u.billing_origin_product,
  u.sku_name,
  u.usage_date,
  u.custom_tags,
  u.usage_quantity AS dbus,
  u.usage_quantity * lp.pricing.effective_list.default AS estimated_cost
FROM system.billing.usage u
JOIN system.billing.list_prices lp
  ON lp.sku_name = u.sku_name
  AND u.usage_end_time &gt;= lp.price_start_time
  AND (lp.price_end_time IS NULL OR u.usage_end_time &lt; lp.price_end_time)
WHERE u.usage_date &gt;= DATE_TRUNC('month', CURRENT_DATE)
</code></code></pre><p>Two things to get right here:</p><ol><li><p>The time-window logic (<code>price_start_time</code> / <code>price_end_time</code>) is essential. Without it, you join to multiple price records for the same SKU and inflate your costs. This is the most common cost calculation mistake in Databricks.</p></li><li><p>Always include <code>billing_origin_product</code> alongside <code>sku_name</code>. As covered in Section 1, these are different dimensions. Joining on <code>sku_name</code> gives you the price, but <code>billing_origin_product</code> tells you what actually consumed it. Without both, your Vector Search costs disappear into your &#8220;serverless inference&#8221; line and your Predictive Optimization costs hide inside &#8220;serverless jobs&#8221;.</p></li></ol><h3>Tag-based cost aggregation</h3><p>With tags in place, aggregation is straightforward:</p><pre><code><code>SELECT
  custom_tags['team'] AS team,
  custom_tags['cost_center'] AS cost_center,
  sku_name,
  SUM(usage_quantity) AS total_dbus,
  SUM(usage_quantity * lp.pricing.effective_list.default) AS estimated_cost
FROM system.billing.usage u
JOIN system.billing.list_prices lp
  ON lp.sku_name = u.sku_name
  AND u.usage_end_time &gt;= lp.price_start_time
  AND (lp.price_end_time IS NULL OR u.usage_end_time &lt; lp.price_end_time)
WHERE usage_date &gt;= DATE_TRUNC('month', CURRENT_DATE)
  AND custom_tags['team'] IS NOT NULL
GROUP BY 1, 2, 3
ORDER BY estimated_cost DESC
</code></code></pre><h3>Other tag-bearing system tables</h3><p>Beyond billing, four system tables carry tag information:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h1VT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h1VT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h1VT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png" width="1371" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:42968,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!h1VT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!h1VT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F827acfaf-48fb-4e8d-9ed5-a1877bbf4611_1371x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>These enable auditing: &#8220;what were the tags at the time?&#8221; vs &#8220;what are the tags now?&#8221;</p><h3>The attribution gap</h3><p>Jobs running on all-purpose clusters have no <code>job_id</code> in billing records. The cost attributes to the cluster, not the job. There is no way to distinguish which job consumed what on a shared all-purpose cluster. Which you shouldn&#8217;t anyway. Even when running the job from Azure Data Factory.</p><p>The recommendation: use dedicated job compute or serverless compute for workloads that need per-job cost attribution. </p><h3>Global vs regional system tables</h3><p><code>system.billing.usage</code> is global.Same data regardless of which metastore you query.</p><p><code>system.access.audit</code> is regional for workspace level events, and global for account level events. It&#8217;s scoped to the metastore. If you have multiple metastores (one per region), each region&#8217;s usage table only shows that region&#8217;s data.</p><p>This creates a problem for any organisation with multiple regions or cloud providers. Your dashboard in <code>eu-west-1</code> cannot easily see <code>us-east-1</code> activity. There is no built-in single pane of glass.</p><div><hr></div><h2>6. Multi-metastore: bridging the visibility gap</h2><blockquote><p><strong>For: Platform Engineers</strong></p><h3>The problem</h3><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xZ-G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xZ-G!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 424w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 848w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 1272w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xZ-G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png" width="1040" height="645" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:645,&quot;width&quot;:1040,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:169893,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xZ-G!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 424w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 848w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.png 1272w, https://substackcdn.com/image/fetch/$s_!xZ-G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb25d3c1e-c45d-4106-b32b-f543f2b0abbd_1040x645.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>One metastore per region. Some system tables are scoped to the region, and you can only have one metastore per region. A dashboard in one region cannot query another region&#8217;s audit table. For organisations operating across multiple regions, or across AWS and Azure, cost visibility is fragmented and it is insightful to combine the system tables for a complete overview.</p><h3>Why a copy job, not Delta Sharing directly</h3><p>The natural instinct is to use Delta Sharing to share system tables across metastores. But system tables are managed by Databricks and cannot be shared via Delta Sharing directly. Trying to circumvent it with a VIEW will technically allow you to create the share, only to result in an error when you want to consume it.</p><p>The workaround we found is a scheduled job that reads from the system tables in each metastore and writes the data into a regular Delta table in a central catalog, which is than shared. This shared catalog is then combined in a UNION VIEW in acentral catalog, we call <code>system_union</code>, follows the same schema structure as the native system tables (<code>system_union.billing.usage</code>, <code>system_union.billing.list_prices</code>, etc.). The job runs every few hours and does a simple merge based on the changes in the last window. Because the data is now in a regular Delta table that you own, it can be shared via Delta Sharing to other metastores, or queried directly if the central catalog is accessible. Benefit of only changing the catalog name is that the dashboards allow easy parametrisation of the catalog name and as such you have to change little.</p><p>The system table schema changes occasionally as Databricks adds columns or modifies types. The sync job needs to handle schema evolution, which is a known maintenance cost. In practice this means catching schema mismatches on the merge and evolving the target table accordingly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Fhn9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Fhn9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 424w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 848w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 1272w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Fhn9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png" width="1326" height="734" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af754366-1902-42c0-ad3d-32c973b4480d_1326x734.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:734,&quot;width&quot;:1326,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131064,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Fhn9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 424w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 848w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.png 1272w, https://substackcdn.com/image/fetch/$s_!Fhn9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf754366-1902-42c0-ad3d-32c973b4480d_1326x734.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><a href="https://github.com/CauchyIO/system_tables_os/tree/main/consolidate">[The </a><strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/consolidate">consolidate</a></strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/consolidate"> notebooks live in /consolidate &#8212; one to copy system tables for delta sharing, and one to create union views across accounts. Clone the repo and configure via YAML]</a></p><h3>Team-scoped system table views</h3><p>The unified catalog serves a second purpose beyond cross-metastore visibility. By creating filtered views on top of it, you can produce team-specific catalogs that contain only the system table entries relevant to that team&#8217;s workspaces. Team &#8220;SDI&#8221; gets <code>sdi_system_tables.billing.usage</code> showing only their workspaces. They see their costs without access to the full account view.</p><p>This serves three purposes: access control (teams see only their own data), simplicity (a developer doesn&#8217;t need to understand the full account structure to see their costs), and dashboard personalisation (the same dashboard template, pointed at a team-scoped catalog, becomes a tailored cost view for that team without any modification to the dashboard itself).</p><p><a href="https://github.com/CauchyIO/system_tables_os/tree/main/distribute">[The </a><strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/distribute">distribute</a></strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/distribute"> notebook in /distribute creates filtered views scoped to specific workspaces or business units. Clone the repo, set your workspace filter in YAML, and deploy with DABs.]</a></p><h3>Workspace enrichment</h3><p>The <code>system.billing.workspaces</code> table contains workspace names and IDs, but no environment label, team, region, or cost center. The workspace is one of the most natural aggregation dimensions for cost reporting, yet the raw table lacks the metadata to make those aggregations useful.</p><p>Enrichment adds those missing columns so that every billing record can be joined to structured metadata about which team, environment, and business unit a workspace belongs to. Once enriched, workspaces become a first-class dimension in your cost model.</p><p><a href="https://github.com/CauchyIO/system_tables_os/tree/main/enrich">[The </a><strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/enrich">enrichment</a></strong><a href="https://github.com/CauchyIO/system_tables_os/tree/main/enrich"> notebook in /enrich adds business context to the workspaces table &#8212; parse naming conventions, pull Azure tags, or join a manual mapping table. Clone the repo and pick your strategy.] </a></p><p><strong>Three approaches to enrichment:</strong></p><ol><li><p><strong>Parse naming conventions.</strong> If your workspaces follow a consistent pattern like <code>team-environment-region</code> (e.g. <code>sdi-production-westeurope</code>), you can split the name into separate columns using string functions. This is the cheapest approach but depends on naming discipline. In practice, most organisations have partial consistency at best, and edge cases (renamed workspaces, legacy naming) require manual overrides.</p></li><li><p><strong>Pull cloud provider tags.</strong> On Azure, workspace-level tags set through ARM resource groups contain metadata that Databricks doesn&#8217;t expose in its system tables. You can query the Azure Resource Graph API to retrieve these tags and join them to the workspaces table. This works well if your cloud team already maintains tagging standards on Azure resources. On AWS, similar metadata can be retrieved via the AWS Resource Groups Tagging API.</p></li><li><p><strong>Maintain a mapping table.</strong> A manually curated Delta table that maps workspace IDs to team, environment, cost center, and any other business dimensions. This is the most reliable approach because it doesn&#8217;t depend on naming conventions or cloud provider tags being correct, but it requires ongoing maintenance. The mapping table should be treated as a governed asset with clear ownership.</p></li></ol><p><strong>What enrichment unlocks per team:</strong></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7LJ5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7LJ5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 424w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 848w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 1272w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7LJ5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png" width="1371" height="288" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:288,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:53287,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7LJ5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 424w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 848w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 1272w, https://substackcdn.com/image/fetch/$s_!7LJ5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe70e043f-3b1d-4a48-9e10-8b2fb783f648_1371x288.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The enriched workspace table becomes a dimension table that you join to <code>system.billing.usage</code> via <code>workspace_id</code>. Combined with custom tags on resources, it gives you two independent attribution paths: tags for workload-level attribution (which job, which team tagged the cluster) and workspace enrichment for organisational-level attribution (which business unit owns this workspace, what environment is it).</p><p>A practical pattern is to create the enriched table as a view in your <code>system_union</code> catalog:</p><pre><code><code>CREATE OR REPLACE VIEW system_union.billing.workspaces_enriched AS
SELECT
  w.*,
  CASE
    WHEN w.workspace_name LIKE '%-production-%' THEN 'production'
    WHEN w.workspace_name LIKE '%-dev-%' THEN 'development'
    WHEN w.workspace_name LIKE '%-staging-%' THEN 'staging'
    ELSE COALESCE(m.environment, 'unknown')
  END AS environment,
  COALESCE(m.team, split(w.workspace_name, '-')[0]) AS team,
  COALESCE(m.cost_center, 'unassigned') AS cost_center
FROM system_union.billing.workspaces w
LEFT JOIN workspace_metadata.default.workspace_mapping m
  ON w.workspace_id = m.workspace_id
</code></code></pre><p>This combines naming convention parsing with a manual mapping fallback. The <code>COALESCE</code> pattern ensures you get a value even when the mapping table has gaps, while the mapping table takes precedence where it exists. The enriched view then works as a drop-in replacement in any dashboard or report that currently joins to the raw workspaces table.</p><p>This enrichment is highly custom per organisation. The right approach depends on your naming conventions, cloud provider, and how much maintenance effort your team can sustain. But without it, you are limited to aggregating at the workspace level, which is rarely the dimension that finance teams need for cross-charging.</p><div><hr></div><h2>7. Dashboards: from system tables to actionable views</h2><blockquote><p><strong>For: Platform Engineers, Finance / FinOps, Developers</strong></p></blockquote><p>System tables and tags are the foundation. Dashboards are what people actually look at. The goal is a set of views where each persona can answer their questions without needing to write SQL. Below is an aggregation of the most frequently shared dashboards.</p><p><a href="https://github.com/CauchyIO/system_tables_os/tree/main/dashboards">[The dashboards live in /dashboards and deploy as a standalone DAB bundle. Override dataset_catalog and warehouse_id to point at your own environment. Clone the repo and deploy. https://github.com/CauchyIO/system_tables_os]</a></p><h3>Dashboard per persona</h3><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i24_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i24_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!i24_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!i24_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!i24_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i24_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png" width="1371" height="339" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:339,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84539,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i24_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!i24_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!i24_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!i24_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F402d0a3f-ce42-42e0-bb7a-694222848c8d_1371x339.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>What these dashboards query</h3><p>All dashboards share the same <code>billing.usage</code> + <code>list_prices</code> join as their cost calculation core. Each adds domain-specific system tables:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-EHF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-EHF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-EHF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png" width="1371" height="299" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:299,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:65119,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-EHF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 424w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 848w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 1272w, https://substackcdn.com/image/fetch/$s_!-EHF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46820270-732b-44aa-b6b9-73a6067c19dd_1371x299.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><h3>Tag matching analysis</h3><p>The Account Usage Dashboard v3 includes a dedicated Tag Matching Analysis page. It identifies:</p><ul><li><p>Usage records with no custom tags (completely unattributable)</p></li><li><p>Records with tags that don&#8217;t match expected values (e.g. a <code>cost_center</code> value that doesn&#8217;t exist in your taxonomy)</p></li><li><p>The &#8220;allocated %&#8221; metric: what fraction of total spend has a valid owner tag</p></li></ul><p>This is the operational view for the &#8220;enforcement maturity&#8221; discussed in section 4. As you roll out tagging policies, this dashboard shows whether they&#8217;re working.</p><h3>Failed run costs: a hidden cost driver</h3><p>The Jobs dashboard tracks something most cost reports miss: the cost of failed runs. A job that fails after 45 minutes of compute still incurs the full DBU cost for that time. If it retries automatically, the repair run adds more.</p><p>The dashboard surfaces: - Cost per job broken down by result state (succeeded, failed, timed out) - Most-repaired jobs in the last 30 days and their cumulative repair cost - Outlier runs that exceeded the P90 baseline cost for that job</p><p>This is operational insight that finance teams rarely see but should. A job with a 15% failure rate and automatic retries can silently inflate costs by 20%+.</p><h3>Model serving cost by model family</h3><p>The Model Serving dashboard breaks down serving costs by provider. Foundation model APIs each have their own SKU:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!M5lP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M5lP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M5lP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png" width="1371" height="220" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:220,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29948,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!M5lP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 424w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 848w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 1272w, https://substackcdn.com/image/fetch/$s_!M5lP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d5b09d3-b014-468e-acb3-b3ed2dc44eae_1371x220.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The dashboard also tracks batch inference costs across executing compute types (DBSQL, DLT, jobs, all-purpose clusters), showing where AI workloads actually run and what they cost. For organisations using AI functions in SQL (<code>ai_query</code>, <code>ai_classify</code>), the dashboard pulls these from <code>query.history</code> to attribute AI costs incurred through SQL warehouses.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QQLI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QQLI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 424w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 848w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 1272w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QQLI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png" width="1456" height="1169" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1169,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:387608,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QQLI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 424w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 848w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.png 1272w, https://substackcdn.com/image/fetch/$s_!QQLI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff0831ccb-1a4d-445a-b884-42aea88621a9_2250x1806.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><h3>Catalog convention</h3><p>All dashboards are adjusted now to work with a configurable default catalog. If you use the <code>system_union</code> catalog convention from section 6, swap the default catalog name and the dashboards show account-wide data across metastores. If you use team-scoped catalogs, each team gets their own dashboard view automatically.</p><div><hr></div><h2>8. Cost allocation and reporting: the finance perspective</h2><blockquote><p><strong>For: Finance / FinOps, Management</strong></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XZss!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XZss!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 424w, https://substackcdn.com/image/fetch/$s_!XZss!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 848w, https://substackcdn.com/image/fetch/$s_!XZss!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 1272w, https://substackcdn.com/image/fetch/$s_!XZss!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XZss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png" width="1090" height="480" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:1090,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131475,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XZss!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 424w, https://substackcdn.com/image/fetch/$s_!XZss!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 848w, https://substackcdn.com/image/fetch/$s_!XZss!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.png 1272w, https://substackcdn.com/image/fetch/$s_!XZss!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6a3c8318-3a72-46ef-b60a-102498c5967d_1090x480.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><h3>Showback vs chargeback</h3><p>Two terms finance teams will recognise:</p><p><strong>Showback</strong> reports costs by team, product, or department for visibility and behavioural change. No general ledger movement. The spend stays in a centralised budget. The goal is accountability through transparency.</p><p><strong>Chargeback</strong> sends costs to business unit budgets or product P&amp;Ls with formal reconciliation and month-end processes. It requires agreed allocation policy, high tag coverage, and a repeatable close process.</p><p>Showback is always required. Chargeback depends on organisational accounting policy. Neither is inherently more mature. Start with showback. Graduate to chargeback when finance and engineering agree on allocation rules.</p><h3>Allocation models</h3><p><strong>Direct allocation</strong> is the best case. Each billing record maps to one owner via custom tags. Define an allocation key:</p><pre><code><code>COALESCE(
  custom_tags['cost_center'],
  custom_tags['team'],
  'unallocated'
) AS allocation_key
</code></code></pre><p>Track &#8220;unallocated %&#8221; as a governance KPI. It tells you what fraction of spend has no owner. Reduce it over time.</p><p><strong>Proportional allocation</strong> is necessary for shared resources. A SQL warehouse serving multiple teams can&#8217;t be directly allocated. Split the warehouse cost using query execution time from <code>system.query.history</code>:</p><pre><code><code>-- Proportional allocation for shared SQL warehouse
WITH warehouse_cost AS (
  SELECT
    usage_metadata.warehouse_id,
    SUM(usage_quantity * lp.pricing.effective_list.default) AS total_cost
  FROM system.billing.usage u
  JOIN system.billing.list_prices lp
    ON lp.sku_name = u.sku_name
    AND u.usage_end_time &gt;= lp.price_start_time
    AND (lp.price_end_time IS NULL OR u.usage_end_time &lt; lp.price_end_time)
  WHERE sku_name LIKE '%SQL%'
  GROUP BY 1
),
query_weights AS (
  SELECT
    compute.warehouse_id,
    query_tags['team'] AS team,
    SUM(execution_duration_ms) AS team_duration
  FROM system.query.history
  WHERE query_tags['team'] IS NOT NULL
  GROUP BY 1, 2
)
SELECT
  qw.team,
  wc.total_cost * (qw.team_duration / SUM(qw.team_duration) OVER (PARTITION BY qw.warehouse_id)) AS allocated_cost
FROM query_weights qw
JOIN warehouse_cost wc ON qw.warehouse_id = wc.warehouse_id
</code></code></pre><p><strong>Hybrid allocation</strong> is the most common mature pattern. Direct allocate everything with a valid tag. Proportionally allocate shared resources. Attribute the remainder to a platform cost center and optionally spread it as overhead.</p><h3>What a monthly cost report should contain</h3><ul><li><p>Spend summary by cost center or team, with allocated vs unallocated percentage</p></li><li><p>Spend by workload type (compute, SQL, DLT, serving) to show where growth is</p></li><li><p>Top cost drivers: workspaces, clusters, jobs, warehouses ranked by spend</p></li><li><p>Pricing basis disclosure: explicitly state whether numbers use list prices or negotiated rates</p></li><li><p>Anomaly notes: spikes with driver explanations and remediation actions</p></li></ul><h3>Budget governance</h3><p>Databricks budgets track spending against a monthly threshold and send email alerts. They do not stop usage or charges. The final bill can exceed the budget amount. Emails can lag up to 24 hours. Budgets use list prices, not negotiated rates.</p><p>For faster, more flexible alerting, use SQL alerts on <code>system.billing.usage</code> queries delivered via Slack or webhook notification destinations. A burn-rate alert that fires when daily spend exceeds a threshold is more useful than a monthly budget email that arrives after the fact.</p><p>Hard spending limits do not exist natively. The enforcement lever is compute policies: restrict what can be created, by whom, and at what size. Capacity control, not spending caps.</p><div><hr></div><h2>9. Putting it together</h2><blockquote><p><strong>For: Everyone</strong></p></blockquote><h3>Common mistakes</h3><p><strong>Treating budgets as hard stops.</strong> They are alerts, not controls. If your governance model assumes budgets prevent overspend, it will fail.</p><p><strong>Starting tagging late.</strong> Tags cannot be applied retroactively to historical billing records. Every day without tags is a day of unattributable spend.</p><p><strong>Assuming tags propagate uniformly.</strong> Pool-backed clusters on AWS/Azure don&#8217;t pass cluster tags to cloud resources. Serverless resources need budget policies, not cluster tags. Different resources have different tag structures.</p><p><strong>Incorrect list_prices joins.</strong> Without the time-window logic on <code>price_start_time</code> and <code>price_end_time</code>, you join to multiple price records per usage line and inflate your numbers.</p><p><strong>Ignoring cloud infrastructure costs.</strong> DBU costs are only part of the bill. The VMs, storage, and networking underneath are billed separately by your cloud provider. Serverless pricing includes the VM cost. Classic compute pricing does not.</p><h3>Do this first</h3><ol><li><p><strong>Define a tag taxonomy.</strong> Four tags cover most needs: <code>cost_center</code>, <code>team</code>, <code>environment</code>, <code>product</code>. Standardise the allowed values.</p></li><li><p><strong>Enforce tags.</strong> Compute policies for classic compute. Budget policies for serverless. No tag, no cluster.</p></li><li><p><strong>Build the allocation dataset.</strong> <code>system.billing.usage</code> joined to <code>system.billing.list_prices</code> with correct time-window logic. State the pricing basis.</p></li><li><p><strong>Set up alerting.</strong> SQL alerts on daily spend anomalies, delivered to Slack. Don&#8217;t rely on budget emails.</p></li><li><p><strong>Report monthly.</strong> Spend by owner, by workload type, with allocated percentage and anomaly explanations.</p></li><li><p><strong>Iterate.</strong> Graduate from showback to chargeback when allocation coverage is high enough and finance agrees on the rules.</p></li></ol><h3>Companion notebook</h3><p>This guide is accompanied by a Databricks notebook that demonstrates how to tag every resource type programmatically. It uses the Databricks SDK for compute-layer tagging (clusters, jobs, warehouses, pipelines, budget policies, compute policies) and Brickkit for Unity Catalog and AI/ML asset tagging (catalogs, schemas, tables, Vector Search, Genie spaces, model serving). The notebook is structured to be run cell-by-cell as a tagging workshop.</p><h3>Features in Public Preview (March 2026)</h3><p>Several capabilities referenced in this guide are in Public Preview and may change:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jloI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jloI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!jloI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!jloI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!jloI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jloI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png" width="1371" height="339" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:339,&quot;width&quot;:1371,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40004,&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;:&quot;https://blog.cauchy.io/i/191034272?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!jloI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 424w, https://substackcdn.com/image/fetch/$s_!jloI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 848w, https://substackcdn.com/image/fetch/$s_!jloI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 1272w, https://substackcdn.com/image/fetch/$s_!jloI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcfc66c1d-63da-417a-a734-da80cd06bfad_1371x339.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p></blockquote></blockquote><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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[How hard is it to migrate a Power BI dashboards to Databricks AI/Dashboard? ]]></title><description><![CDATA[Automating Power BI to Databricks AI/Dashboard with a Claude reusable skills file]]></description><link>https://blog.cauchy.io/p/how-hard-is-it-to-migrate-a-power</link><guid isPermaLink="false">https://blog.cauchy.io/p/how-hard-is-it-to-migrate-a-power</guid><dc:creator><![CDATA[Eirini Papakosta]]></dc:creator><pubDate>Thu, 12 Feb 2026 14:28:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!M6k1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif" 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_!M6k1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!M6k1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 424w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 848w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 1272w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!M6k1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif" width="720" height="450" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:450,&quot;width&quot;:720,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2032199,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!M6k1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 424w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 848w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 1272w, https://substackcdn.com/image/fetch/$s_!M6k1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f50e6b-5ea7-45a7-b2d6-d96bf0b97c13_720x450.gif 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>In this blog I explore how to automate the migration of Power BI dashboards to Databricks AI/BI Dashboards using Claude Code and a reusable skills file. The aim is to convert Power BI semantic models, visuals, and interactions into working Databricks dashboards and to build a skills file that anyone can pick up and use.</p><p><a href="https://github.com/CauchyIO/PowerBI_to_AIBIDashboard_migrations">The full repo for the migration, the reusable skill files and the 3 examples can be found here</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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><h2>Why Even Go There?</h2><p>For a while I have been struggling to facilitate some standard way of working with Databricks and BI tools. Even though there are direct connections, to actually fully and consistently operationalise the adoption, governance is a difficult task in an enterprise setting. When teams are migrating their workflows to Databricks, they want to keep using the BI tools they are used to and connect them with Databricks. Databricks has the capabilities that a lot of these tools provide in terms of ETL, but because Business as Usual (BAU) should not be hindered in projects like migrations, the decision is usually not to replace these tools with Databricks just yet. So what is my problem? Let me explain.</p><h4>Governance</h4><p>With Databricks, the governance story is straightforward: Unity Catalog provides unified access control across all data assets. For native AI/BI Dashboards, that&#8217;s where it ends. The moment you introduce an external BI tool, that clean story breaks down.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h6kP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h6kP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 424w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 848w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 1272w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h6kP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png" width="936" height="691" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:691,&quot;width&quot;:936,&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;: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_!h6kP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 424w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 848w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.png 1272w, https://substackcdn.com/image/fetch/$s_!h6kP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecd7ee49-3f8a-468b-a8db-5ff8d5d532af_936x691.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><p>The core problem is the gap between development and production. During development, everything looks fine analysts connect with their own identity, and Unity Catalog enforces permissions as expected. But the moment a dashboard is published, scheduled for refresh, or embedded, the authentication model changes. BI tools switch to service accounts or service principals, not end-user identities. With import mode the most common pattern  data is extracted and cached inside the BI tool, where Unity Catalog has no visibility at all. The result: governance splits in two. One layer controls what the service principal can access in Unity Catalog, and a separate permission model inside the BI tool controls who sees what. Two systems, doing the same job, never fully in sync.</p><ul><li><p><strong>Access latency:</strong> Every new BI connection requires securely configuring non-personal authentication, routing data owner approvals, and provisioning access  adding days of delay before users can actually see their data in the tool.</p></li><li><p><strong>Drift and inconsistency:</strong> When a team&#8217;s access in Unity Catalog changes new sources added, permissions refined those changes don&#8217;t automatically flow through to the BI tool&#8217;s non-personal authentication. Someone has to manually replicate the changes, and until they do, what users see in the BI tool diverges from what they&#8217;d see in Databricks.</p></li><li><p><strong>Duplicated governance:</strong> In practice, organisations end up maintaining access policies in two (or more) places: Unity Catalog for the platform and a separate permission model inside the BI tool. Keeping these in sync is a constant, error-prone operational burden.</p></li><li><p><strong>Unhappy everyone:</strong> End users are frustrated by slow access. Platform and ops teams are burdened with manual, repetitive provisioning work across multiple systems. Nobody asked for this, nobody enjoys it, and it scales poorly.</p></li></ul><p>With Databricks AI/BI Dashboards, the story is quite different. Users authenticate with their own identity, Unity Catalog enforces governance in real time, and there is no secondary permission layer to build, sync, or maintain. One platform, one identity, one governance model.</p><h4>Costs</h4><p>I have been seeing this discussion come back more and more around BI licensing and additional costs. Databricks collapses the BI layer into the data platform itself no extra licences, no data copies, no separate infrastructure. Dashboards are just another workload on the platform you already run, while most BI tools continue to add cost and complexity as you scale.</p><p>The cost model of AI/BI Dashboards in Databricks is simple. You only pay for the SQL warehouse compute behind them every click, refresh, or Genie question triggers queries, and that&#8217;s where the cost sits. The same applies to Databricks Genie, which can be embedded in your dashboard: every question it answers runs queries on the underlying SQL warehouse at your expense.</p><h4>Time to Insight</h4><p>Anyone who has worked with BI tools and non-technical users knows that dashboard requirements rarely stay fixed business questions evolve, priorities shift, and the feedback cycle between &#8220;this isn&#8217;t quite what I meant&#8221; and a corrected visual can span days across separate tools. Having data, logic, and dashboards on one platform compresses that loop considerably.</p><p>With traditional BI tools, a new dashboard doesn&#8217;t start with building visuals; it starts with infrastructure. Configuring gateways, setting up service accounts, and registering data sources all happen before anyone sees a chart. Databricks AI/BI Dashboards remove most of that setup by querying Unity Catalog directly no data extraction, no gateway, no connection strings to maintain.</p><p>The data preparation work itself doesn&#8217;t disappear aggregations, joins, and transformations still need to be built regardless of the tool. The difference is the engine: Spark distributes computation across a cluster and Photon accelerates it natively, which matters as data volumes grow beyond single-machine limits. Materialized views can pre-compute expensive aggregations and refresh incrementally, keeping dashboards fast without recomputing on every load.</p><h2>The Migration Approach</h2><p>I used Claude Code to set up a project containing Power BI reports, to create the Databricks AI/BI Dashboards according to the skills file, and to deploy them with Databricks Asset Bundles (DAB). The aim is to figure out the proper instructions and construct a Claude skills file that can adapt Power BI dashboards to AI/BI dashboards directly. In addition, the effort is not limited to a one-to-one matching of the visualisations but also to mimic the interactions and to construct a dataset that can produce the expected results. For this reason, the project is looking into an overall migration from Power BI to Databricks AI/BI Dashboards. </p><p>To get a head start I used the skills file from Cauchy blog from Steven Kempers: <em><a href="https://blog.cauchy.io/p/claude-meets-json-automating-databricks">Claude meets JSON: Automating Databricks Dashboards</a></em>. Another available skills file is <a href="https://github.com/databricks-solutions/ai-dev-kit/blob/main/databricks-skills/aibi-dashboards/SKILL.md">aibi_dashboard from Databricks</a>. I used the same skills file and the deployment method to create and deploy the Databricks dashboard.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9Avk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9Avk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 424w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 848w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 1272w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9Avk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png" width="936" height="300" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:300,&quot;width&quot;:936,&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_!9Avk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 424w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 848w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.png 1272w, https://substackcdn.com/image/fetch/$s_!9Avk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8bcf1af-c32d-4dd1-af88-c070609a950c_936x300.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>I used three different Power BI reports to investigate multiple components. On the first dashboard (Bakehouse Sales) I wanted to investigate what happens when a table has DAX measures, transformations, and Power Query code. On the second dashboard (Adventure Works) the aim was cross-filtering  a characteristic that is very important for Power BI reports and expected behaviour. On the third report (Sample Superstore) the aim was to test the skills file.</p><h3>Dashboard 1: Bakehouse Sales</h3><p>I started by creating my own Power BI dashboard including the semantic model with data from the Bakehouse sample in Databricks. The idea is to export it as a <code>.pbip</code> file, which is a readable version of a Power BI file containing a collection of the Semantic Model, Report Visuals, and the Theme and it looks like this.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SNDS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SNDS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 424w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 848w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 1272w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SNDS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png" width="936" height="243" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:243,&quot;width&quot;:936,&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_!SNDS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 424w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 848w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.png 1272w, https://substackcdn.com/image/fetch/$s_!SNDS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e8e83e5-672f-4d8f-8f65-f613c38722ff_936x243.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 information would be read by Claude and migrated into a Databricks dashboard, which is a single <code>.lvdash.json</code> file containing SQL queries and widget definitions. I tried to split the process into three tasks.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hyw-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hyw-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 424w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 848w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 1272w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hyw-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png" width="490" height="275.28846153846155" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:818,&quot;width&quot;:1456,&quot;resizeWidth&quot;:490,&quot;bytes&quot;:346447,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Hyw-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 424w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 848w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.png 1272w, https://substackcdn.com/image/fetch/$s_!Hyw-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a365e6e-69ec-477a-84c4-152fd26658a8_2338x1314.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">Power BI Dashboard</figcaption></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_!Rs5U!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Rs5U!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 424w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 848w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Rs5U!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png" width="492" height="272.69505494505495" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:807,&quot;width&quot;:1456,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:341459,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Rs5U!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 424w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 848w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!Rs5U!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecdc7de7-2838-4770-8394-414c29aac36f_2526x1400.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">Databricks AI/BI Dashboard</figcaption></figure></div><p>The BakehouseSales dashboard was intentionally simple but not trivial. It tested:</p><ul><li><p>Can the migration handle Power Query transformations (column renaming, text trimming, calculated columns)?</p></li><li><p>Can the migration convert DAX measures to SQL aggregations?</p></li><li><p>Can the migration reproduce a calculated DAX table (<code>CALENDAR</code> + <code>ADDCOLUMNS</code>) as a SQL view?</p></li><li><p>Can the migration produce working visuals (cards, line charts, tables)?</p></li></ul><p>Because of DAX and Power Query, my direction to Claude was to create SQL views for each table that has transformations, keep the same column names to match exactly with Power BI, and to only migrate what is exactly used. After a couple of back and forths, the results surprisingly matched relatively fast. These are the lessons learned that are included in the skills file:</p><h4>Lessons Learned from BakehouseSales</h4><ol><li><p><strong>When something&#8217;s wrong, it&#8217;s always about dates: </strong>A DAX date dimension built with <code>CALENDAR</code> + <code>ADDCOLUMNS</code> has no direct SQL equivalent &#8212; and this was the first thing that broke. The solution is <code>explode(sequence())</code> combined with <code>DATE_FORMAT</code>, which the skills file now captures as a reusable template:<br>Not obvious, but now any future migration gets this for free.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1N67!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1N67!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 424w, https://substackcdn.com/image/fetch/$s_!1N67!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 848w, https://substackcdn.com/image/fetch/$s_!1N67!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 1272w, https://substackcdn.com/image/fetch/$s_!1N67!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1N67!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png" width="630" height="119.7" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:171,&quot;width&quot;:900,&quot;resizeWidth&quot;:630,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!1N67!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 424w, https://substackcdn.com/image/fetch/$s_!1N67!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 848w, https://substackcdn.com/image/fetch/$s_!1N67!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 1272w, https://substackcdn.com/image/fetch/$s_!1N67!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec963cd-6c08-495f-ad90-51b62bda4d6f_900x171.png 1456w" sizes="100vw" loading="lazy"></picture><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_!RHcP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!RHcP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 424w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 848w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 1272w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!RHcP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png" width="626" height="388.12" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:558,&quot;width&quot;:900,&quot;resizeWidth&quot;:626,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&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="" title="" srcset="https://substackcdn.com/image/fetch/$s_!RHcP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 424w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 848w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.png 1272w, https://substackcdn.com/image/fetch/$s_!RHcP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcf8c8c86-a2b2-4bbb-a772-590e7ff434f1_900x558.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></li><li><p><strong>Table widgets are verbose and strict:</strong> each column needs ~20 lines of boilerplate, and the widget breaks silently if you miss <code>disaggregated: true</code>, <code>spec.version: 1</code>, or <code>invisibleColumns: []</code>.</p></li><li><p><strong>Only migrate what&#8217;s used:</strong> the semantic model is a reusable data layer that often contains more than what the report displays. A migration only needs to reproduce what the visuals actually reference.</p></li><li><p><strong>The colours are not matching</strong>: but I am willing to let it go.</p></li></ol><p>The full mapping between Power BI and Databricks can be seen in the skills files of the repo.</p><h3>Dashboard 2: Adventure Works</h3><p>The AdventureWorks dashboard was an existing Power BI report with more complexity: multiple tables joined together, a filled map, and most importantly  slicers. The aim was to test cross-filtering, the behaviour that Power BI users rely on most and take for granted.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-s47!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-s47!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 424w, https://substackcdn.com/image/fetch/$s_!-s47!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 848w, https://substackcdn.com/image/fetch/$s_!-s47!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 1272w, https://substackcdn.com/image/fetch/$s_!-s47!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-s47!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png" width="492" height="297.3626373626374" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:880,&quot;width&quot;:1456,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:276476,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-s47!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 424w, https://substackcdn.com/image/fetch/$s_!-s47!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 848w, https://substackcdn.com/image/fetch/$s_!-s47!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.png 1272w, https://substackcdn.com/image/fetch/$s_!-s47!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6ffec28d-fe5d-4a5b-9ad4-0f60b4b3b524_1950x1178.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">Power BI Dashboard (map is not working)</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UED1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UED1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 424w, https://substackcdn.com/image/fetch/$s_!UED1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 848w, https://substackcdn.com/image/fetch/$s_!UED1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 1272w, https://substackcdn.com/image/fetch/$s_!UED1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UED1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png" width="492" height="217.6153846153846" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:644,&quot;width&quot;:1456,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:346642,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!UED1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 424w, https://substackcdn.com/image/fetch/$s_!UED1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 848w, https://substackcdn.com/image/fetch/$s_!UED1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 1272w, https://substackcdn.com/image/fetch/$s_!UED1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa96f9d97-8ec9-4521-92bf-3ff5988cf03e_2526x1118.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Databricks AI/BI Dashboard</figcaption></figure></div><h4>The Filter Problem - The Biggest Surprise</h4><p><strong>Challenge:</strong> In Power BI, you drop a slicer on the page, connect it to a field, and it automatically shows a dropdown list and filters all visuals through the semantic model. It is effortless. My first attempt used parameter-based filtering defining parameters in the dataset with <code>WHERE col = :param_name</code>. I deployed it, opened the dashboard, and instead of a dropdown list I got a text input box. Users would have to type the exact value. No list, no autocomplete.</p><p><strong>Solution:</strong> The fix was field-based filtering: the filter widget queries a field from the dataset, populates a dropdown from the distinct values, and handles filtering client-side. No parameters, no <code>WHERE</code> clause. The difference in the JSON is subtle, but the behaviour is completely different. This distinction cost several deployment cycles to figure out and was not clearly documented.</p><h4>Cross-Filtering &#8212; Replicating Click-to-Filter</h4><p><strong>Challenge:</strong> In Power BI, clicking on a bar or pie slice automatically filters every other visual on the page. In Databricks, this only works between widgets on the same dataset.</p><p>The AdventureWorks line chart needed a <code>UNION ALL</code> of two queries (Sales by Order Date and Sales by Due Date). But putting the choropleth map and table on the same <code>UNION ALL</code> dataset caused double-counting &#8212; every row appeared twice. We tested a single dataset; the numbers were wrong.</p><p><strong>Solution:</strong> The solution was two datasets connected by filter widgets that reference both. A single filter widget can query the same field from multiple datasets. When the user selects a value, both datasets filter simultaneously. This required adding JOINs to the <code>UNION ALL</code> dataset so that categorical fields (Category, Country) existed in both datasets. The rule that emerged:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cnCF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cnCF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 424w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 848w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 1272w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cnCF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png" width="936" height="568" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:568,&quot;width&quot;:936,&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_!cnCF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 424w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 848w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.png 1272w, https://substackcdn.com/image/fetch/$s_!cnCF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17a45295-560d-4dd9-b306-ba1b9bfd67ba_936x568.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><blockquote><p>Every categorical dimension visible or clickable on the report must have a filter widget that references all datasets containing that column.</p></blockquote><p>In Power BI, this happens automatically. In Databricks, you build it explicitly.</p><h4>The Choropleth Discovery &#8212; Reverse-Engineering Widget Specs</h4><p><strong>Challenge:</strong> One visual was a filled map showing order quantity by country. Claude guessed the JSON encoding structure <code>widgetType: "choropleth"</code>, <code>version: 3</code>, a flat geo encoding. I deployed it. The widget rendered with &#8220;Visualization has no fields selected.&#8221;</p><p><strong>Solution:</strong> Rather than continuing to guess, I asked Claude to query the Databricks Lakeview API (<code>GET /api/2.0/lakeview/dashboards/&lt;id&gt;</code>) to export a working choropleth created manually in the UI. Three things were wrong: the widget type is <code>"choropleth-map"</code> (not <code>"choropleth"</code>), the version is <code>1</code> (not <code>3</code>), and the region encoding uses a nested <code>admin0</code> object with <code>geographicRole</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pJOb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pJOb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 424w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 848w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 1272w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pJOb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png" width="936" height="492" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:936,&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_!pJOb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 424w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 848w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.png 1272w, https://substackcdn.com/image/fetch/$s_!pJOb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb961acf5-adcf-43e3-8c96-e9375ab3c2fa_936x492.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 pattern create a working example in the UI, export via API, use the result as a template became a reliable fallback whenever documentation is incomplete.</p><h4>Lessons Learned from AdventureWorks</h4><ol><li><p><strong>Field-based, not parameter-based:</strong> parameters create text inputs; field-based filtering creates dropdown lists. For Power BI slicer behaviour, always use field-based.</p></li><li><p><strong>UNION ALL breaks cross-filtering:</strong> when one chart needs <code>UNION ALL</code>, use separate datasets and connect them with multi-dataset filter widgets.</p></li><li><p><strong>When documentation is sparse, use the API:</strong> export a working dashboard via the Lakeview API to reverse-engineer the correct JSON structure.</p></li></ol><h2>Dashboard 3: Sample Superstore</h2><p>The Sample Superstore was an existing Power BI report with a single table (Orders), no DAX measures (just direct SUM aggregations), and no Power Query transformations. The data was already in Unity Catalog. The aim of this dashboard was to test the skills file could Claude generate a correct dashboard using the patterns documented from the first two migrations?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E09b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E09b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 424w, https://substackcdn.com/image/fetch/$s_!E09b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 848w, https://substackcdn.com/image/fetch/$s_!E09b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 1272w, https://substackcdn.com/image/fetch/$s_!E09b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E09b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png" width="492" height="275.45631067961165" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/032e6739-866a-4a32-8eab-6efec589d875_1236x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1236,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:154597,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!E09b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 424w, https://substackcdn.com/image/fetch/$s_!E09b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 848w, https://substackcdn.com/image/fetch/$s_!E09b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.png 1272w, https://substackcdn.com/image/fetch/$s_!E09b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F032e6739-866a-4a32-8eab-6efec589d875_1236x692.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">Power BI dashboard</figcaption></figure></div><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mYgO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mYgO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 424w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 848w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 1272w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mYgO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png" width="492" height="172.33516483516485" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:510,&quot;width&quot;:1456,&quot;resizeWidth&quot;:492,&quot;bytes&quot;:213273,&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;:&quot;https://blog.cauchy.io/i/187675692?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mYgO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 424w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 848w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 1272w, https://substackcdn.com/image/fetch/$s_!mYgO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa670f40a-c872-48c9-b111-044b62ddd11d_2530x886.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Databricks AI/BI Dashboard</figcaption></figure></div><h3>What the Skills File Got Right</h3><p>Claude read the Power BI source files and generated the dashboard on the first attempt with:</p><ul><li><p><strong>Gauges &#8594; Counters:</strong> correctly mapped (the skills file documented that Databricks has no gauge &#8212; use counter instead)</p></li><li><p><strong>Single dataset:</strong> recognised that all charts use the same table with no <code>UNION ALL</code> needed, so one dataset was sufficient</p></li><li><p><strong>Correct widget specs:</strong> version 2 for counters, version 3 for charts, all field expressions correct</p></li><li><p><strong>City filter:</strong> generated as field-based from the start (the skills file had &#8220;Do NOT use parameters&#8221; clearly documented)</p></li></ul><h3>Lessons Learned from Sample Superstore</h3><ol><li><p><strong>Skills files work:</strong> the patterns from BakehouseSales and AdventureWorks enabled a near-correct first attempt, proving the knowledge base approach pays off.</p></li><li><p><strong>Gauge &#8594; Counter is a visual downgrade:</strong> the number is correct, but losing the dial/arc visual is noticeable. Counter sparklines help but are not a full replacement.</p></li><li><p><strong>Rules need to be explicit:</strong> the categorical filter rule was obvious in hindsight, but Claude did not infer it until it was written down. If a pattern matters, document it.</p></li></ol><p><strong>Simple dashboards migrate fastest:</strong> no SQL views, no <code>UNION ALL</code>, no multi-dataset filters. A single table with direct aggregations is the ideal case.</p><h2>Conclusion</h2><p>Considering the headaches I have seen companies face with the adoption of BI tools, this could be a natural next step. What surprised me most was how straightforward the migration turned out to be. For organisations already running on Databricks, the transformations and aggregations typically already live on the platform BI tools increasingly serve as a visual layer on top. And if the data, the logic, and the governance are all in Databricks already, why not keep the dashboards there too?</p><p>The migration itself is not a one-click operation, but it is more feasible than I expected. Across three dashboards of increasing complexity, the core patterns became clear: DAX translates to SQL, Power Query transforms become views, and most standard visual types have a Databricks equivalent. The skills file approach proved its value &#8212; what took several iterations on Bakehouse was nearly right on the first attempt by Sample Superstore. And because the skills file captures these patterns as reusable instructions, any user can pick it up and apply it to their own Power BI dashboards without starting from scratch.</p><p>There are gaps. Cross-filtering requires explicit wiring that Power BI handles automatically. Table widgets are verbose and break silently. Advanced analytics visuals like decomposition trees and key influencers have no equivalent but these typically belong in dedicated analysis tools rather than operational dashboards. Colour matching and theme alignment are achievable but were not prioritised in this iteration a natural next step for the skills file.</p><p>If you have a Power BI dashboard that you think would be a good challenge complex filters, unusual visuals, heavy DAX I&#8217;d love to see how it holds up. Try the skills file on your own report and let&#8217;s collaborate to improve it. Every edge case we solve makes the next migration easier.</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 Cauchy's stories! 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[Why Your Data Project Needs A Companion App]]></title><description><![CDATA[Interacting with your data through "vibe-coded" webapps]]></description><link>https://blog.cauchy.io/p/why-your-data-project-needs-a-companion</link><guid isPermaLink="false">https://blog.cauchy.io/p/why-your-data-project-needs-a-companion</guid><dc:creator><![CDATA[Steven Kempers]]></dc:creator><pubDate>Fri, 23 Jan 2026 10:44:56 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!QPs_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic" 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_!QPs_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QPs_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 424w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 848w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 1272w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QPs_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic" width="1408" height="736" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:736,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:97159,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.cauchy.io/i/183220470?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QPs_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 424w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 848w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 1272w, https://substackcdn.com/image/fetch/$s_!QPs_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F067180a6-5dc8-44b9-8dd2-f8286016f43a_1408x736.heic 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><h3>Introduction</h3><p>This blog post is the fourth in a series focused on end-to-end data ingestion and transformation with Databricks, based on the principles of the Medallion architecture. The project will feature the vehicle datasets published by the Dutch RDW (national vehicle authority) and is aimed to exemplify a basic data processing workflow using core Databricks functionalities. Here we explore the creation of companion apps using LLMs such as Claude Code, which offer exciting new possibilities for interacting with your project data.</p><p>The entire blog series consists of:</p><ul><li><p>Blog 1: Data Ingestion Framework &amp; Medallion Architecture - The secrets of bronze, silver, and gold</p></li><li><p>Blog 2: Data Quality Checks with DQX - DQX: We do not trust the data we have not validated</p></li><li><p>Blog 3: Dashboard Automation with Claude Code - Claude meets JSON: automating Databricks dashboards</p></li><li><p><strong>Blog 4: Companion App for Data Exploration - You need a companion to explore your data</strong></p></li><li><p>Blog 5: Asset Bundle Deployment - Deploy your project like a pro with Databricks Asset Bundles</p></li><li><p>Blog 6: Cost Optimization &amp; Analysis - It&#8217;s all great, but how much does it cost?</p></li></ul><h3><strong>Why Build a Companion App</strong></h3><p>Typical data pipelines include ingestion, transforming, cleaning, and validating. Once finished, and having obtained a trusted dataset, its data is usually monitored with a dashboard or through ad-hoc SQL queries and is then exposed to downstream systems. This leaves a lot to be desired in terms of intuitive interaction with your datasets. </p><p>Building a companion app offers something different: a lightweight and interactive way to <em>use</em> your data in a real setting, instead of just focusing on reporting statistics and analytics. Our RDW companion app made it possible to explore what types of vehicles are live on the Dutch roads, and see their details. It is also possible to look up an existing license plate to see more specific information. </p><p>There are a few reasons why this is valuable:</p><ul><li><p><strong>Validating your pipelines</strong>: Manual inspection of your data through a visual UI is perhaps the most effective way to reveal potential issues with your data quality. You can quickly navigate through specific data and spot details that are abstracted away in dashboards or aggregation queries. In addition, it helps to develop a deeper understanding of your data and show what issues (e.g., edge cases) may arise in real world implementations.</p></li><li><p><strong>Making data accessible</strong>: A front-end application makes it very intuitive to interact with your data, and moreover, allows others to do this as well. Other users such as colleagues or stakeholders without specific SQL or programming skills are now enabled to work with the data, making the project more accessible. For example, you could use it to create an app where non-technical stakeholders that have in-depth knowledge of the data can validate it.</p></li><li><p><strong>Useful</strong>: Depending on the type and sensitivity of your data, the companion app may actually become a handy tool on its own and provide additional value to your pipelines!</p></li></ul><p>Previously, these reasons may not have warranted the overhead for data engineers, but with the advent of LLM-assisted coding (&#8220;<em>Vibe coding</em>&#8221;), it has become incredibly easy and quick to build Python web apps, even with ample knowledge of front-end development. </p><p>With novel tools such as Claude Code, you can describe what you are looking for and iterate towards a working application quickly. This allows users to realise a working prototype or PoC within minutes. The barrier has been lowered so much that a companion app can become a natural extension of your project instead of a whole separate endeavour. </p><h3><strong>Core Features of Our App</strong></h3><p>The companion app for our RDW vehicles project is mainly focussed on looking up technical vehicle data. It features two main pages: <em>Overview</em> and <em>License plate</em>. </p><h5>Vehicle overview</h5><p>The main page features a vehicle overview which reads data from the <code>registered_vehicles_dedup</code> table, containing all unique vehicles in the RDW dataset. This page allows the user to view the vehicles belonging to the current selection, which is dictated by the filter options on the left-hand side. Filters include vehicle brands, models, and sliders for production year, engine displacement, weight, and number of seats.</p><p>As the table only contains unique vehicles, it is only intended for a general overview on the distinct cars existing in the dataset. </p><h5>License plate lookup</h5><p>The second page is geared towards finding information about specific registered vehicles. The user can enter a license plate first, and is then shown detailed information:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G4Hv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G4Hv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 424w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 848w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 1272w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G4Hv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png" width="1456" height="809" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:331499,&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;:&quot;https://blog.cauchy.io/i/183220470?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!G4Hv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 424w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 848w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.png 1272w, https://substackcdn.com/image/fetch/$s_!G4Hv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff099fbae-af13-43f3-b24c-a298511283cb_3024x1680.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><h5>AI-assistant</h5><p>Both the overview and lookup pages are equipped with an AI-assistant chatbot. In the overview page, it is possible to chat with the assistant in natural language and have the assistant change the filters accordingly. For example, you can prompt the assistant to display lightweight vehicles with large engine displacements:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NNzD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NNzD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 424w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 848w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 1272w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NNzD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png" width="1456" height="809" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1751525,&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;:&quot;https://blog.cauchy.io/i/183220470?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NNzD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 424w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 848w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.png 1272w, https://substackcdn.com/image/fetch/$s_!NNzD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa49d3f91-faba-4b93-b54a-5fdda375727f_3024x1680.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 is also possible to chat with the assistant in the license plate lookup. Once a plate has been given and the subsequent detail page is loaded, users can chat with the assistant and ask questions about the currently viewed vehicle. This makes it possible to ask about general background or more specific vehicle-related information:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9tEG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9tEG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 424w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 848w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 1272w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9tEG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png" width="1456" height="808" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:808,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:771514,&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;:&quot;https://blog.cauchy.io/i/183220470?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9tEG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 424w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 848w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.png 1272w, https://substackcdn.com/image/fetch/$s_!9tEG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b4cb315-244c-44f8-9c63-888fbbb62461_3024x1678.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><h3><strong>Technical Architecture</strong></h3><p>There are some things to consider for the technical backend of such an app. We used Python Dash to run our web app in. For all debugging purposes it was hosted locally. Once happy with the result, it was packaged as a Databricks app and added to the Databricks Asset Bundle (DAB) to deploy with the package itself. In your <code>databricks.yml</code>, you can include the app as follows:</p><pre><code>apps:
  rdw_webapp:
    name: "rdw-webapp-${bundle.target}"
    description: "RDW Vehicle Data Dashboard"
    source_code_path: ./webapp
    permissions:
      - user_name: your@email.com
        level: CAN_MANAGE</code></pre><h5>Authentication</h5><p>The Databricks SDK&#8217;s WorkspaceClient handles authentication for REST API calls, while DatabricksSession from Databricks Connect handles Spark data access. One of the nice properties here is that both use Databricks&#8217; unified authentication, they natively work with your Databricks credentials once deployed as a Databricks App,  and in local development they use your CLI configured profile(s) or environment variables. </p><pre><code>from databricks.sdk import WorkspaceClient

# Automatically authenticated
workspace_client = WorkspaceClient()

# For API calls, get auth headers from the SDK
auth_headers = workspace_client.config.authenticate()
# Returns: {"Authorization": "Bearer &lt;token&gt;"}</code></pre><h5>Permissions</h5><p>When you deploy a Databricks App, it automatically creates a service principal for your application. However, this service principal has no permissions by default and you will need to explicitly grant access to the resources your app needs.</p><p>For our dashboard, we had to grant the app&#8217;s service principal access to the required table. You can find your app&#8217;s service principal in the Databricks App settings, then grant permissions via the Catalog Explorer UI or using SQL. </p><p>Currently, it is not able to define your service principal or permissions upfront with the deployment of the bundle, meaning that manual setup of permissions (depending on your use case) will be required. </p><h5>Retrieving Data</h5><p>We use Databricks Connect with serverless compute for table access. The main benefit for this application is no cluster startup required, allowing for instant querying and table retrieval. </p><pre><code>from databricks.connect import DatabricksSession

def _get_spark_session():
    return DatabricksSession.builder.serverless(True).getOrCreate()

# Query Unity Catalog directly
spark = _get_spark_session()
df = spark.table("gold_catalog.rdw_etl.registered_vehicles_dedup")</code></pre><p>The overview page uses the deduplicated table. During load, it selects only columns deemed necessary for our purposes to reduce size. The table is then loaded in memory as a local DF, requiring only around 500MB of RAM. Note that this may not work for you depending on the size of your table. The main benefit of maintaining the table in this way is that it makes filter and selection operations instant, without the need to run queries to the table stored in a catalog. </p><p>For the license plate lookup, the amount of potentially requested data is too large to store as a local DF. Here, the registered vehicles table is queried using SQL, looking up the requested row by its primary key (license plate). As a result, looking up a license plate requires a few seconds processing time. </p><h5>Providing AI chat through LLM endpoint</h5><p>The last component is the AI chat, which uses Databricks model serving endpoints under the hood. In our case, we used the <code>databricks-meta-llama-3-1-70b-instruct </code>endpoint, wrapped in a class.</p><pre><code>import requests
from databricks.sdk import WorkspaceClient

class AIChat:
    def __init__(self, endpoint: str = "databricks-meta-llama-3-1-70b-instruct"):
        self.endpoint = endpoint
        self.workspace_client = WorkspaceClient()
        self.api_url = f"{workspace_host}/serving-endpoints/{endpoint}/invocations"

    def _get_structured_ai_response(
        self, user_message: str, current_filters: Dict[str, Any]
    ) -&gt; str:
        """
        Get structured AI response for car filtering using Databricks LLM.

        Args:
            user_message (str): User's message/question
            current_filters (Dict): Current filter state

        Returns:
            str: AI response in JSON format
        """
        # Create a structured prompt that requests JSON output
        system_prompt = """You are a car search assistant. Analyze the user's request and respond with a JSON object containing:
            1. "message": A helpful response to the user
            2. "filters": Suggested filter changes based on their request

            Available filter categories:
            - "brands": List of car brands (e.g., ["BMW", "Mercedes", "Audi"])
            - "models": List of model names (e.g., ["320i", "520d"])
            - "vehicle_types": List of vehicle types (e.g., ["Personenauto"])
            - "engine_range": [min_cc, max_cc] (e.g., [1000, 3000])
            - "weight_range": [min_kg, max_kg] (e.g., [1000, 2000])
            - "seats": [min_seats, max_seats] (e.g., [4, 7] where 7 means 7+)
            - "year_range": [min_year, max_year] (e.g., [2010, 2020])

            Only include filter categories that should change based on the user's request. Use null for filters that shouldn't change.

            Example response:
            {
            "message": "I'll help you find cars",
            "filters": {
                "brands": ["BMW"],
                "models": null,
                "year_range": [2015, 2020],
                "vehicle_types": null,
                "engine_range": null,
                "weight_range": null,
                "seats": null
            }
            }

            In addition, you should also be able to converse with the user to discuss cars in general, to find any car.
            Once the user agrees with the car selection, adjust the filters to find this car."""

        user_prompt = f"""Current filters: {json.dumps(current_filters)}
            User request: {user_message}

            Please respond with a JSON object as specified."""

        headers = {
            "Content-Type": "application/json"
        }

        (...)

        payload = {
            "messages": [
                {
                    "role": "system",
                    "content": system_prompt
                },
                {
                    "role": "user",
                    "content": user_prompt
                }
            ],
            "max_tokens": 1000,
            "temperature": 0.3
        }

        response = requests.post(self.api_url, headers=headers, json=payload, timeout=60)
        return response.json()["choices"][0]["message"]["content"]</code></pre><p>Specifically on the overview page the LLM is equipped to change the filters. This is performed by requesting a response structured in specific JSON syntax, making it easy to convert the LLM response into an actual filter on the page.</p><p>For the car lookup assistant, a different system prompt is used, that simply requires the assistant to answer questions, and is given as input the full information of the current vehicle such that it can incorporate that in the response. The LLM endpoint calling is the same. </p><h3>Considerations</h3><p>Whilst building a &#8220;vibe-coded&#8221; web app for your project can be very useful and is a fun exercise, there are obvious limitations.</p><ul><li><p><strong>Treat it as a personal or small-scale tool</strong>: Building apps this way (entirely vibe-coded) should be considered as a tool for personal- or small scale usage. Unless you are experienced in (frontend) application development, it is not recommended to publish on a large scale. Do not blindly give people access to your hosted app. </p></li><li><p><strong>Vibe coding is no substitute for proper engineering</strong>: Similarly, vibe-coding gets you to a working prototype fast, but it often skips the fundamentals: testing, logging, authentication best practices, dependency management. If the app becomes critical to your workflow or others start relying on it, you will need to revisit these gaps. The more importance your app bears, the more you should invest time to understand what is under the hood, and not rely on LLM-generated code.</p></li><li><p><strong>AI chats can be abused</strong>:<strong> </strong>Likewise, the AI chat can be abused. Not only are people using the app using <strong>your</strong> LLM endpoint (you are paying for it), there are no guardrails implemented making it very easy to bypass security in a variety of ways and (ab)use the LLM for other purposes than intended. If you want to use AI chat assistants in production, you must educate yourself on vulnerabilities such as prompt injection, jailbreaking, obfuscation, and so forth. The same goes for any other endpoint that your app is using, or exposes.</p></li></ul><h3>Conclusion</h3><p>Building a companion app for your data project has become remarkably accessible with LLM-assisted coding. What used to require significant frontend expertise and development overhead can now be prototyped in a matter of hours. In our case, we built a simple web app to explore the RDW vehicle dataset, allowing for license plate lookups, browsing filtered results, and even natural language queries through a Databricks model serving endpoint. This approach turns your gold layer from a well-modelled table into something tangible and interactive. </p><p>There is a lot of potential in enabling non-technical stakeholders to interact with the data beyond statistics and dashboards, through webapps, which has become a manageable endeavour with LLM-assisted coding. </p><p>That said, vibe-coded apps come with clear limitations. They&#8217;re best suited for personal use or small-scale internal tooling, not production deployments. Be mindful of security considerations, especially when exposing AI endpoints.</p><p>In the upcoming blog posts we will dive deeper into various aspects of the project, such as deploying with Databricks Asset Bundles (DABs) and cost analysis.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 the Cauchy.io blog! Subscribe for free to receive new posts and upcoming 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[Claude meets JSON: Automating Databricks Dashboards]]></title><description><![CDATA[Dashboard Automation with Claude Code]]></description><link>https://blog.cauchy.io/p/claude-meets-json-automating-databricks</link><guid isPermaLink="false">https://blog.cauchy.io/p/claude-meets-json-automating-databricks</guid><dc:creator><![CDATA[Steven Kempers]]></dc:creator><pubDate>Mon, 05 Jan 2026 12:43:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!iE9w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.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_!iE9w!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iE9w!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iE9w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&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;: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_!iE9w!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!iE9w!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F993a680c-2958-4360-b1a0-a51be3c73d2e_1024x1024.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><h3>Introduction</h3><p>This blog post is the third in a series focused on end-to-end data ingestion and transformation with Databricks, based on the principles of the Medallion architecture. The project will feature the vehicle datasets published by the Dutch RDW (national vehicle authority) and is aimed to exemplify a basic data processing workflow using core Databricks functionalities. This blog will focus on <strong>Dashboard creation using Claude code</strong><em>, </em>similarly you can use any LLM of your choice. </p><p>The entire blog series consists of:</p><ul><li><p>Blog 1: Data Ingestion Framework &amp; Medallion Architecture - The secrets of bronze, silver, and gold</p></li><li><p>Blog 2: Data Quality Checks with DQX - DQX: We do not trust the data we have not validated</p></li><li><p><strong>Blog 3: Dashboard Automation with Claude Code - Claude meets JSON: automating Databricks dashboards</strong></p></li><li><p>Blog 4: Companion App for Data Exploration - You need a companion to explore your data</p></li><li><p>Blog 5: Asset Bundle Deployment - Deploy your project like a pro with Databricks Asset Bundles</p></li><li><p>Blog 6: Cost Optimization &amp; Analysis - It&#8217;s all great, but how much does it cost?</p></li></ul><h3><strong>Databricks JSON dashboards</strong></h3><p>Databricks dashboards provide a native way to visualize data directly from Unity Catalog tables. They support a range of chart types, filters, and parameters which can be configured through a visual editor within the workspace.</p><p>Databricks dashboards consist of a few key components:</p><ul><li><p>Datasets: SQL queries that pull data from your tables. Each dataset is referenced by widgets.</p></li><li><p>Widgets: The individual visualizations (counters, bar charts, line charts, tables) plus text and filter elements.</p></li><li><p>Layout: A grid-based positioning system where you specify x, y, width, and height for each widget.</p></li></ul><p>Each dashboard is structured as a JSON file on the backend. The JSON follows a predictable pattern: you define your datasets first, then create widgets that reference them and specify visualization options. The basic structure looks like:</p><pre><code>json
{
  &#8220;datasets&#8221;: [
    {
      &#8220;name&#8221;: &#8220;vehicle_count&#8221;,
      &#8220;query&#8221;: &#8220;SELECT COUNT(*) as total FROM gold_layer.rdw_etl.registered_vehicles&#8221;
    }
  ],
  &#8220;widgets&#8221;: [
    {
      &#8220;name&#8221;: &#8220;Total Vehicles&#8221;,
      &#8220;type&#8221;: &#8220;counter&#8221;,
      &#8220;dataset&#8221;: &#8220;vehicle_count&#8221;,
      &#8220;column&#8221;: &#8220;total&#8221;,
      &#8220;position&#8221;: {&#8221;x&#8221;: 0, &#8220;y&#8221;: 0, &#8220;width&#8221;: 3, &#8220;height&#8221;: 2}
    }
  ]
}</code></pre><p>Existing dashboards can be exported to retrieve their JSON files. Databricks has also added support for Git version control in dashboards (have to live in Git folders), where the underlying JSON changes get tracked. That said, the JSON is designed as a storage medium rather than a file intended for direct editing.</p><p>That is not to say that it is impossible to alter your dashboard by directly modifying the JSON, but it definitely is very impractical and tedious to do so, hence it is not really recommended. The Databricks UI editor remains far more usable for actually building and modifying dashboards. Adjusting layouts, adding pages and configuring is much more intuitive through a visual interface, compared to scrolling through nested JSON properties.</p><p>This project was in part inspired by the realisation that the AI assistant provided by Databricks does not yet offer extensive capabilities in this regard. It can help generate individual widgets, but it can&#8217;t handle broader operations like creating new pages, rearranging the layout, or even automatically defining datasets from your tables (at least, not directly from the UI). As such, building dashboards with LLM assistance is still somewhat limited.</p><h3><strong>Using Claude Code</strong></h3><p>Given these current limitations on using the assistant with dashboards, we turned to Claude Code for dashboard development. The approach was simple; the exported JSON of the existing dashboard was placed in the project structure (<code>dashboard/src/rdw_dashboard.lvdash.json</code>). To sync it easily with our deployed asset bundle, it was also defined in <code>databricks.yml</code>:</p><pre><code>yaml
 dashboards:
   rdw_dashboard:
     display_name: &#8220;RDW Dashboard&#8221;
     file_path: dashboard/src/rdw_dashboard.lvdash.json
     warehouse_id: ${resources.sql_warehouses.serverless_warehouse.id}</code></pre><p>Note that you need to attach a warehouse in the dashboard definition.</p><p>It was then possible to examine our dashboard using Claude by reading the JSON. From here you can prompt Claude Code to modify the JSON in any way. For example, you can add new widgets, adjust queries or reorganize the layout.</p><p>Especially in the beginning the changes by Claude were not always correct. These issues were largely caused by Claude not being fully familiar with the syntax conventions used in Databricks dashboards. Field names, default values, and structural patterns would sometimes drift from what the platform expects. Rather than correcting these issues manually each time, we found it more effective to set up a Claude agent that had more knowledge about the syntax and conventions used by Databricks dashboard JSONs (you can probably use Claude skills as well here). This kept the output closer to what Databricks produces natively and reduced the back-and-forth during import.</p><p>What is also great about this approach is that both UI widgets and data sources can be updated in an instance. If the data or aggregations that your widget relies on is not (yet) available, Claude can define it at the same time in <code>datasets</code> using SQL queries.</p><p>Since we are adjusting the local clone of our dashboard&#8217;s JSON, it is not really possible to view the changes in real time. In our setup we used the dashboard attached in the DAB and deployed it to Databricks after changing, using <code>databricks bundle deploy &#8230;</code> command. This does mean that you have to refresh your browser where you are viewing the dashboard, making the process a bit more involved. Regardless, in our testing, this way of working was still miles faster than manually building the dashboard elements in the UI. Alternatively, it would probably also work to enable <code>databricks bundle sync</code> during this process to keep the dashboard in Databricks UI synced to your local changes.  </p><h3><strong>Walkthrough  </strong></h3><p>In our project we used Claude to build a job overview page. The overview page of our dashboard was built manually in the Databricks UI, and was given as a starting point for Claude. We recommend that you give Claude at least something (i.e., a few widgets) to start with, to help generate some context and syntax understanding. Whilst JSON rules are set, the dashboard syntax is not publicly available and hence we are essentially reverse-engineering it. This combined with a subagent in markdown (you could also use a skill) gave the best results for us. The subagent definition can be found <a href="https://github.com/CauchyIO/rdw_blog_repo/blob/main/dashboard/databricks-dashboard-json-agent.md">here</a>. The dashboard below was provided as context and created manually.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4qPY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4qPY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 424w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 848w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 1272w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4qPY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png" width="1456" height="883" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:883,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:404922,&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;:&quot;https://blog.cauchy.io/i/181971081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!4qPY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 424w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 848w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.png 1272w, https://substackcdn.com/image/fetch/$s_!4qPY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61b341c1-1d30-41a1-bdbb-841fda14f813_2606x1580.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>The first test we then conducted was for Claude to construct a &#8220;Top 20 Most Popular Brands&#8221; widget, which would involve both generating a widget and dataset. The first attempt yielded a correct widget with incorrect data, that showed all brands by popularity. We had to nudge Claude in the right direction and explicitly mention that it should generate a new dataset for this widget. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qi00!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qi00!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 424w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 848w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 1272w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qi00!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png" width="1456" height="823" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:823,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:300988,&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;:&quot;https://blog.cauchy.io/i/181971081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Qi00!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 424w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 848w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.png 1272w, https://substackcdn.com/image/fetch/$s_!Qi00!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae894f22-e2f3-42a3-9082-9aeed6adf922_2604x1472.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 was then time to let Claude loose on a new page for job overviews and statistics. We prompted to generate a job overview describing jobs in the current project (which can be read from <code>databricks.yml</code>), and use the system tables to automatically identify and construct datasets regarding metrics of these jobs. </p><p>The initial result was a decent overview page, though some widgets were still broken and could be positioned better. This was due to a line break syntax issue in the SQL queries. Having fixed that, the first results were genuinely impressive and very close to the end result. The tweaks thereafter were mainly focussed on layout, such as the color green/yellow/red colour scheme for visualisations, and improving the readability of scrolling widgets. We also found that the generated datasets could be simplified further. In the initial setup, Claude used one specific query per widget, and these could easily be refactored such that multiple widgets share queries/datasets.</p><p>In order to avoid too much back-and-forth work between the UI and local JSON, it is also helpful to ask Claude to describe the current contents:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L1SG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L1SG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 424w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 848w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 1272w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L1SG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png" width="1456" height="916" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:916,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:236722,&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;:&quot;https://blog.cauchy.io/i/181971081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!L1SG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 424w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 848w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.png 1272w, https://substackcdn.com/image/fetch/$s_!L1SG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c689830-c32c-42ff-9085-caf43329bae8_1596x1004.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><h3><strong>Results</strong></h3><p>The results below show what we were able to achieve in only around 30-60 minutes of dashboard work using Claude code in combinations with the raw JSON source file for the dashboard. The initial experiment for most popular brands widget is shown below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vQHR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vQHR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 424w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 848w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 1272w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vQHR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png" width="1456" height="413" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:413,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:159189,&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;:&quot;https://blog.cauchy.io/i/181971081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vQHR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 424w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 848w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.png 1272w, https://substackcdn.com/image/fetch/$s_!vQHR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2eb5a07e-5d55-470c-bd15-9e3331e6e49f_2566x728.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>The generated job overview page included job run results and statistics. It also gave metrics about pipeline health, such as SCD2 operations and quarantined tables. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!UQ_B!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!UQ_B!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 424w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 848w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 1272w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!UQ_B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png" width="1456" height="813" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:1456,&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_!UQ_B!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 424w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 848w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.png 1272w, https://substackcdn.com/image/fetch/$s_!UQ_B!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F85f1844c-d358-4d28-8e73-9f6809f0bcad_2048x1144.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_!fMx_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fMx_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 424w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 848w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 1272w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fMx_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png" width="1456" height="683" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e797888-5a62-4495-ad66-c3db59947941_2048x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:683,&quot;width&quot;:1456,&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_!fMx_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 424w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 848w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.png 1272w, https://substackcdn.com/image/fetch/$s_!fMx_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e797888-5a62-4495-ad66-c3db59947941_2048x960.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_!JrPT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JrPT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 424w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 848w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 1272w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JrPT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png" width="1456" height="412" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:412,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163636,&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;:&quot;https://blog.cauchy.io/i/181971081?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!JrPT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 424w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 848w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.png 1272w, https://substackcdn.com/image/fetch/$s_!JrPT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30a55790-add2-4f2e-9631-afad51aadf05_2574x728.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><a href="https://github.com/CauchyIO/rdw_blog_repo/tree/main/dashboard">The full dashboard JSON along with the subagent we used is now visible in the repository as well.</a> </p><h3><strong>Limitations</strong></h3><p>Obviously, there are some limitations to this approach:</p><p>One of the first that we stumbled upon was dashboard size. We tried to work on the <a href="https://github.com/CodyAustinDavis/dbsql_sme/tree/main/Observability%20Dashboards%20and%20DBA%20Resources/Account%20Usage%20Dashboard">Account Usage V2 dashboard</a> and modify it, but reading its JSON in Claude immediately flooded the context window with around 13.000 lines (and approximately 130.000 tokens) of reading required. This meant that it was not possible to work in the JSON file. There are probably ways to avoid this, such as splitting the pages in separate files, but it is still quite inconvenient and somewhat defeats the purpose of working with Claude, which is to be more efficient. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fXOi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fXOi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 424w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 848w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 1272w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fXOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png" width="926" height="328" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:328,&quot;width&quot;:926,&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_!fXOi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 424w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 848w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.png 1272w, https://substackcdn.com/image/fetch/$s_!fXOi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5ed8691c-6a32-4683-8ed9-668e3e376694_926x328.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 this approach can make dashboard work much more efficient, the way of working is still not perfect. Altering the local JSON clone of the dashboard and reviewing changes in the Databricks UI can feel like a bit of a back-and-forth process where you keep switching between both. If adopting this method in your workflow, it would be very beneficial to implement a live view, similar to the approach by <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;NextGenLakehouse&quot;,&quot;id&quot;:13028360,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1034df11-e0a1-40c6-9fa5-57c7862e5286_780x780.png&quot;,&quot;uuid&quot;:&quot;a0da575a-8c49-4168-ab4a-2b38feac7495&quot;}" data-component-name="MentionToDOM"></span> in their recent <a href="https://www.youtube.com/watch?v=LZa8IGx9Msg">video</a> on LLM-assisted AIBI dashboard generation.</p><p>We also noticed that even with a Claude subagent, errors were not uncommon, especially in more complex widgets. This can be attributed to the lack of formal documentation for the dashboard JSON schema; you essentially have to reverse engineer rules out of existing dashboards. This also means that there is no tooling or official method for validating your JSON schemas for dashboards.</p><h3><strong>Conclusion</strong></h3><p>Using Claude Code as an assistant for building dashboards has been very effective in our workflow. Using the JSON representation of Databricks dashboards allows for a more programmatically approach to dashboards and hence give Claude, or any LLM coding assistant of choice, access to it. In our case we used Claude (supplied with a specialized subagent) both to polish an existing page and build a new page for our RDW project dashboard. This way of working allowed for extremely quick prototyping without manually diving into SQL queries and fiddling with widgets in the UI. We did run in to some limitations:</p><ul><li><p>Large dashboards do not fit in LLM context window</p></li><li><p>Way of working is a bit of back-and-forth between local JSON and deployed Databricks dashboard to actually visualise it </p></li><li><p>Not perfect: Claude still makes errors with regard to the data and syntax sometimes</p></li></ul><p>In general, we can recommend the approach when you need to:</p><ul><li><p>Tweak or adjust existing dashboards - though dependent on its length. </p></li><li><p>Obtain quick visualisations and insights to answer questions from stakeholders in a matter of minutes. </p></li></ul><p>As of currently, we would not recommend it when:</p><ul><li><p>Building completely new dashboards with convoluted metrics from scratch - Claude performed significantly better in existing environments where it could deduce information from. If you want to try this it is beneficial to explore your plans and data first with Claude.</p></li><li><p>Working on very large dashboards (&gt;10K lines of JSON, depending on your model) where the LLM context window may not suffice. </p></li></ul><p>In the upcoming blog posts we will dive deeper into various aspects of the project, such as a data exploration webapp, Databricks Asset Bundles (DABs), and cost analysis.<br></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 the Cauchy.io blog! Subscribe for free to receive new posts and upcoming 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[We do not trust the data we have not validated]]></title><description><![CDATA[Data Quality Checks with DQX]]></description><link>https://blog.cauchy.io/p/we-do-not-trust-the-data-we-have</link><guid isPermaLink="false">https://blog.cauchy.io/p/we-do-not-trust-the-data-we-have</guid><dc:creator><![CDATA[Steven Kempers]]></dc:creator><pubDate>Wed, 17 Dec 2025 16:21:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ukQZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Introduction</h3><p>This blog post is the second in a series focused on end-to-end data ingestion and transformation with Databricks, based on the principles of the Medallion architecture. The project will feature the vehicle datasets published by the Dutch RDW (national vehicle authority) and is aimed to exemplify a basic data processing workflow using core Databricks functionalities. In this blog, we will focus on <strong>data validation using DQX by Databricks Labs</strong>. The entire blog series consists of:</p><ul><li><p>Blog 1: Data Ingestion Framework &amp; Medallion Architecture - The secrets of bronze, silver, and gold</p></li><li><p><strong>Blog 2: Data Quality Checks with DQX - DQX (YOU ARE HERE NOW!): We do not trust the data we have not validated</strong></p></li><li><p>Blog 3: Dashboard Automation with Claude Code - Claude meets JSON: automating Databricks dashboards</p></li><li><p>Blog 4: Companion App for Data Exploration - You need a companion to explore your data</p></li><li><p>Blog 5: Asset Bundle Deployment - Deploy your project like a pro with Databricks Asset Bundles</p></li><li><p>Blog 6: Cost Optimization &amp; Analysis - It&#8217;s all great, but how much does it cost?</p></li></ul><p>Check out the <a href="https://github.com/CauchyIO/rdw_blog_repo">project repo</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_!ukQZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ukQZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 424w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 848w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 1272w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ukQZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic" width="1456" height="1950" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1950,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:501748,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.cauchy.io/i/181333793?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ukQZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 424w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 848w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 1272w, https://substackcdn.com/image/fetch/$s_!ukQZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d73505-7dba-4d1b-9f84-6bcd760f215a_1792x2400.heic 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><figcaption class="image-caption">Inspired by Soda&#8217;s swag. Generated using Nano Banana</figcaption></figure></div><p></p><div><hr></div><h3>Data validation</h3><p>Data validation is a critical step in any data pipeline by enforcing data quality standards. It avoids silent propagation of bad data. In the medallion architecture we clean and validate the data in the silver layer, ensuring that it does not pass to the gold layer and ends up in business aggregations, dashboards or machine learning models. There are many different tools available for data validation. This blog will dive deeper into our data validation approach that uses DQX.</p><h3>About DQX</h3><p>DQX by Databricks Labs is a data quality framework for Apache Spark that allows for defining, monitoring, and addressing data quality issues in Python-based data pipelines. Specifically, DQX is native to Databricks and Spark Dataframes.</p><p>Data checks form the basis of DQX. These are rules that validate on a row-, column- or dataset-level. The outcomes of the rule checks are dictated by the user and can be set as errors, which will filter out that data, or warnings, which will only add a warning column to these entries. Error data can either be left out entirely, or saved to a quarantine table, which allows for inspection of the data that does not comply with the defined checks.</p><p>Broadly speaking, there are three different methods for defining DQX checks.</p><p>The first approach uses definition files in JSON or YAML format. One advantage is their automatic version control when placed in your Git project. Their formats are as shown below:</p><pre><code>yaml
- criticality: error
  check:
    function: is_not_null
    arguments:
      col_name: license_plate

- criticality: warn
  check:
    function: sql_expression
    arguments:
      expression: &#8220;LENGTH(license_plate) = 6&#8221;
      msg: &#8220;License plate must be 6 characters&#8221;</code></pre><pre><code>json
[
  {
    &#8220;criticality&#8221;: &#8220;error&#8221;,
    &#8220;check&#8221;: {
      &#8220;function&#8221;: &#8220;is_not_null&#8221;,
      &#8220;arguments&#8221;: { &#8220;col_name&#8221;: &#8220;license_plate&#8221; }
    }
  },
  {
    &#8220;criticality&#8221;: &#8220;warn&#8221;,
    &#8220;check&#8221;: {
      &#8220;function&#8221;: &#8220;sql_expression&#8221;,
      &#8220;arguments&#8221;: {
        &#8220;expression&#8221;: &#8220;LENGTH(license_plate) = 6&#8221;,
        &#8220;msg&#8221;: &#8220;License plate must be 6 characters&#8221;
      }
    }
  }
]</code></pre><p>The second approach is using Python code for defining rules. Its main advantage is the potential for dynamic and programmatic rule definition.</p><pre><code>python
from databricks.labs.dqx.row_checks import is_not_null, sql_expression
from databricks.labs.dqx.rule import DQColRule

checks = [
    DQColRule(
        criticality=&#8221;error&#8221;,
        check_func=is_not_null,
        col_name=&#8221;license_plate&#8221;
    ),
    DQColRule(
        criticality=&#8221;warn&#8221;,
        check_func=sql_expression,
        check_func_kwargs={
            &#8220;expression&#8221;: &#8220;LENGTH(license_plate) = 6&#8221;,
            &#8220;msg&#8221;: &#8220;License plate must be 6 characters&#8221;
        }
    )
]</code></pre><p>Lastly, it is also possible to store the rules in Delta Tables. This is especially useful if centralized management is required by the user(s). It does however add extra infrastructure to your project.</p><pre><code>python
# Save checks to Delta table
dq_engine.save_checks(
    checks,
    config=TableChecksStorageConfig(
        location=&#8221;catalog.schema.dqx_checks_table&#8221;,
        mode=&#8221;overwrite&#8221;
    )
)

# Load checks from Delta table
checks = dq_engine.load_checks(
    config=TableChecksStorageConfig(
        location=&#8221;catalog.schema.dqx_checks_table&#8221;
    )
)</code></pre><h3><strong>Alternatives and why we opted for DQX</strong></h3><p>The data quality tooling landscape for Spark workloads has several options, each with different trade-offs. Some of the most popular alternatives include Great Expectations, DLT Expectations, and Soda Core.</p><p><strong>Great Expectations</strong> is arguably the most mature open-source data quality framework. It offers 100+ built-in expectations, extensive integrations, and solid documentation. However, it has some overhead. There is a steep learning curve to using GE optimally, and its configurations can become very verbose. In addition, it was never designed for Spark in the first place, meaning it does not always leverage Spark&#8217;s parallelism optimally and can trigger unnecessary data movements or actions that harm performance. Depending on your purposes and resources, the complexity may outweigh the benefits, especially without dedicated data quality engineers.</p><p><strong>DLT Expectations</strong> are built directly into Delta Live Tables and work seamlessly within DLT pipelines. It has become the obvious choice for users fully committed to DLT, however, we decided against using it since our use-case does not require the use of DLTs. In addition, DLT workloads run on more expensive compute than standard Spark jobs.</p><p><strong>Soda Core</strong> takes a simpler approach with its YAML-based Soda Checks Language (SodaCL). It&#8217;s easier to get started with than Great Expectations and supports multiple data sources. The main downside to Soda Core is its SQL-focused core. And while Spark is supported through programmatic scans, it is not a native implementation. Advanced features also push you toward Soda Cloud, their commercial offering.</p><p>So why did we opt for DQX in our RDW pipeline?</p><ul><li><p><strong>PySpark/Databricks native</strong>: DQX operates directly on Spark DataFrames without translation layers or external dependencies. In addition it integrates cleanly with Unity Catalog and works on serverless compute.</p></li><li><p><strong>Built-in quarantine pattern</strong>: the built-in methods support separation of valid and invalid rows out of the box. This is an essential component of the medallion architecture where bad data should not propagate downstream</p></li><li><p><strong>Simplicity</strong>: Straight-forward setup for Databricks-focused projects. Defining checks in YAML is straightforward and requires only a few lines of code to apply them.</p></li><li><p><strong>Flexibility</strong>: DQX checks follow SQL syntax and are easy to store. It even supports generating rules for other libraries such as DLT or custom setups. </p></li></ul><p>Of course, DQX is not without limitations. Being a Databricks Labs project, it is not officially supported by Databricks (there are no SLA&#8217;s) - yet? The library is still relatively new, especially compared to its alternatives, meaning fewer available resources and less support. For our project where we demonstrate a pipeline with relatively simple validation requirements, these trade-offs are acceptable.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ok03!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ok03!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 424w, https://substackcdn.com/image/fetch/$s_!ok03!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 848w, https://substackcdn.com/image/fetch/$s_!ok03!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 1272w, https://substackcdn.com/image/fetch/$s_!ok03!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ok03!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic" width="1456" height="1161" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1161,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:203891,&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;:&quot;https://blog.cauchy.io/i/181333793?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ok03!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 424w, https://substackcdn.com/image/fetch/$s_!ok03!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 848w, https://substackcdn.com/image/fetch/$s_!ok03!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.heic 1272w, https://substackcdn.com/image/fetch/$s_!ok03!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F38fcc88e-a024-4f80-a15b-5296030651aa_2398x1912.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></p><h3>Workflow implementation</h3><p>In our implementation, we decided to store the validation rules in <code>src/rdw/dqx_checks</code>. Each of the 10 tables has an individual YAML definition where its data validation rules are stored. There are several types of rules applied in our tables:</p><ul><li><p>simple primary key <code>is_not_null</code> checks to verify integrity. for the main table we decided to also check the <code>make</code>, the <code>trade_name</code>, and the <code>vehicle_type</code> for nulls.</p></li><li><p>&#8220;is in&#8221; checks for categorical values, for example, `odometer_judgment_explanation_code <code>IN (&#8217;00&#8217;, &#8216;01&#8217;, &#8216;02&#8217;, &#8216;03&#8217;, &#8216;04&#8217;, &#8216;05&#8217;, &#8216;06&#8217;, &#8216;07&#8217;, &#8216;NG&#8217;)</code>. Can be applied when there is a limited range of applicable values for a column (and the values are known beforehand).</p></li><li><p>Format checking: all license plates should be 6 characters long. <code>LENGTH(license_plate) = 6</code></p></li><li><p>Date column integrity checking e.g., <code>registration_date IS NULL OR registration_date &gt;= &#8216;1890-01-01&#8217;</code></p></li></ul><p>The DQX validation checking is carried out in the silver layer processing script; for more information on our medallion architecture implementation read <a href="https://blog.cauchy.io/p/the-secrets-of-bronze-silver-and">blog 1 here</a>. There exists a helper function <code>apply_dqx_validation()</code> which initializes the <code>DQEngine</code> object. The engine uses a <code>databricks.sdk.WorkspaceClient</code> as a  parameter to initialize the Spark session. The WorkspaceClient automatically authenticates using your local Databricks configuration profile, or active Databricks instance when running on a cluster. Having initialized the <code>DQEngine</code> now allows us to load the stored checks using <code>FileChecksStorageConfig</code> and <code>load_checks</code> functions. In our case the paths are defined in the table configuration as <code>table.dqx_checks_path</code>.</p><p>It is then possible to validate the current DataFrame based on the configured checks:</p><pre><code>python
# Initialize DQX engine
dq_engine = DQEngine(WorkspaceClient())

# Load checks from YAML file using FileChecksStorageConfig
checks_config = FileChecksStorageConfig(location=table.dqx_checks_path)
checks = dq_engine.load_checks(checks_config)

# Apply checks and split into valid and quarantined DataFrames
# load_checks returns metadata (dicts), so use 
# apply_checks_by_metadata_and_split
valid_df, quarantined_df = dq_engine.apply_checks_by_metadata_and_split(df, checks)</code></pre><p>This returns both the validated- (cleaned) and quarantined DataFrames.</p><h3>Quarantine</h3><p>All data that does not comply with the validation checks ends up in the specified quarantine catalog. In our case we successfully caught a batch of data where improper formatting was found. Here, the license plate format check (<code>LENGTH(license_plate) = 6</code>) was triggered, and it seemed that all columns had shifted right. The `license_plate` column was substituted by what appears to be a row hash, hence all other columns had invalid, shifted data as well. The screenshot below shows the invalid data that was quarantined:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gq-3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gq-3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 424w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 848w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 1272w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gq-3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png" width="1456" height="692" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:692,&quot;width&quot;:1456,&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_!gq-3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 424w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 848w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.png 1272w, https://substackcdn.com/image/fetch/$s_!gq-3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0404396f-c21d-4bed-afa7-114cff48499e_2048x973.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 provides a perfect example of how data validation is effective in real-world data, that is more often than not messy upon receival. It is good to note that in the most recent data, these issues have been resolved and the RDW most likely caught wind of this issue, so your quarantine results with the data may vary.</p><h3><strong>Conclusion</strong></h3><p>We found DQX to be a valuable addition to the project. Its implementation was intuitive and simple, using YAML-based rule definitions. The built-in quarantine pattern proved its value immediately, filtering out 252 malformed records from the ingested RDW tables, before the data moved further downstream.</p><p>For teams working in Databricks with standard Spark jobs, DQX offers a low-overhead path to data quality enforcement and validation.</p><p>In the upcoming blog posts we will dive deeper into various aspects of the project, such as a data exploration webapp, Databricks Asset Bundles (DABs), and cost analysis.<br></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 the Cauchy.io blog! Subscribe for free to receive new posts and upcoming 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 secrets of bronze, silver, and gold]]></title><description><![CDATA[Data Ingestion Framework & Medallion Architecture]]></description><link>https://blog.cauchy.io/p/the-secrets-of-bronze-silver-and</link><guid isPermaLink="false">https://blog.cauchy.io/p/the-secrets-of-bronze-silver-and</guid><dc:creator><![CDATA[Steven Kempers]]></dc:creator><pubDate>Wed, 10 Dec 2025 13:53:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!IbBF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic" 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_!IbBF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IbBF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 424w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 848w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 1272w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IbBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic" width="728" height="683.8787878787879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:992,&quot;width&quot;:1056,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:196833,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/heic&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.cauchy.io/i/181222577?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!IbBF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 424w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 848w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 1272w, https://substackcdn.com/image/fetch/$s_!IbBF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd4c690b7-0c3f-4c08-b2c5-aba3f6da1f09_1056x992.heic 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><h3>Introduction</h3><p>This blog post is the first in a series focused on end-to-end data ingestion and transformation with Databricks, based on the principles of the Medallion architecture. The project will feature the vehicle datasets published by the Dutch RDW (national vehicle authority) and is aimed to exemplify a basic data processing workflow using core Databricks functionalities. In this first blog, we will focus on <strong>data ingestion </strong>and processing data using the <strong>medallion architecture</strong> in a bronze-silver-gold layer design. The blog series consists of:</p><p><strong>1.  The secrets of bronze, silver, and gold (YOU ARE HERE NOW!):</strong> Data Ingestion Framework &amp; Medallion Architecture.</p><p><strong>2. DQX: We do not trust the data we have not validated</strong>: Data Quality Checks with DQX</p><p><strong>3. Claude meets JSON: automating Databricks dashboards:</strong> Dashboard Automation with Claude Code.</p><p><strong>4. You need a companion to explore your data: </strong>Companion App for Data Exploration.</p><p><strong>5. Deploy your project like a pro with Databricks Asset Bundles.</strong></p><p><strong>6. It&#8217;s all great, but how much does it cost?: </strong>Cost Optimization &amp; Analysis.</p><div><hr></div><h3>The framework</h3><p>Data ingestion forms the foundation of any data engineering process. Broadly speaking, it involves collecting external data to an internal and centralized location, such as the Unity Catalog. Databricks offers various built-in connectors to link external sources to your workspace, but many use cases still warrant custom code implementations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Nr0Y!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 424w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 848w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 1272w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png" width="1456" height="538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:538,&quot;width&quot;:1456,&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_!Nr0Y!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 424w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 848w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.png 1272w, https://substackcdn.com/image/fetch/$s_!Nr0Y!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc18e9387-73e2-4a13-ae6e-47decf51fcfe_1600x591.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">Figure 1: Data flow from raw ingestion to gold layer in Unity Catalog</figcaption></figure></div><p>For most data, there is a lot of processing to be done before it is actually ready for production purposes. Raw data often arrives messy and suffers from problems such as inconsistent formats, duplicates, or missing values. A typical processing pipeline follows the three-layer Medallion architecture: bronze, silver and gold. Rather than attempting complex transformations in a single step, each layer adds incremental quality and structure, and breaks the work into manageable stages. In general the Medallion architecture dictates that bronze data is raw and unprocessed, silver data is cleaned and validated, and gold data is aggregated and curated to a business-ready form. Figure 1 displays the dataflow that we adhere to in this project. For more reading material on the Medallion architecture we highly recommend:</p><ul><li><p><a href="https://docs.databricks.com/aws/en/lakehouse/medallion">What is the medallion lakehouse architecture?</a> by Databricks</p></li><li><p><a href="https://www.oreilly.com/library/view/building-medallion-architectures/9781098178826/">Building Medallion Architectures: Designing with Delta Lake and Spark</a>, by Piethein Strengholt (2025)</p></li></ul><p>All code and examples are designed to work with the dataset provided by the RDW, as shown in the overview Figure 1. <a href="https://github.com/CauchyIO/rdw_blog_repo">The full code repository can be viewed here</a>. The repo is structured as shown below:</p><pre><code><code>rdw_repo/
  &#9500;&#9472;&#9472; dashboard
  &#9500;&#9472;&#9472; webapp
  &#9500;&#9472;&#9472; src/
  &#9474;   &#9492;&#9472;&#9472; rdw/
  &#9474;       &#9500;&#9472;&#9472; jobs/
  &#9474;       &#9500;&#9472;&#9472; dqx_checks/
  &#9474;       &#9500;&#9472;&#9472; views/
  &#9474;       &#9500;&#9472;&#9472; scd2/
  &#9474;       &#9492;&#9472;&#9472; utils/
  &#9474;
  &#9492;&#9472;&#9472; tests/
      &#9500;&#9472;&#9472; fixtures/
      &#9500;&#9472;&#9472; test_data/
      &#9500;&#9472;&#9472; unit_tests/
      &#9492;&#9472;&#9472; integration_tests/</code></code></pre><p>The ingestion scripts for the Medallion architecture reside in <code>src/rdw/jobs</code>.</p><h3>Ingestion</h3><p>Before actually ingesting any data, we modeled all 10 tables using Pydantic Basetables. This serves multiple purposes: it gives us an internal representation of what the data looks like (and should look like), but also provides a place to define computed properties (e.g., filepaths) that stay consistent across the codebase.</p><p>Although Python does offer built-in dataclasses, there are multiple reasons to choose for Pydantic. Pydantic enforces type validation at runtime, catching misconfigurations early rather than letting them emerge further down in the pipeline. It also makes serialization straightforward: table definitions can be exported to YAML or JSON, which becomes useful when you want to version control configurations separately from code or share them across tools. For a project like this, where table definitions drive everything from ingestion to validation to schema creation, having such flexibility is a big advantage. </p><p>The structure of the raw RDW tables is shown in Figure 2 below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uRjh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uRjh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 424w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 848w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uRjh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png" width="400" height="490.4214559386973" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1600,&quot;width&quot;:1305,&quot;resizeWidth&quot;:400,&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_!uRjh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 424w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 848w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.png 1272w, https://substackcdn.com/image/fetch/$s_!uRjh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45c5740b-08c8-4c28-a77d-824f47788214_1305x1600.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">Figure 2: Structure of RDW dataset tables</figcaption></figure></div><p>We define the structure of the tables in <code>models.py</code> :</p><pre><code>class BaseColumn(BaseModel):
   input_col: str # column names in raw input data
   output_col: str # processed column names
   original_type: Type
   output_data_type: DataType
   is_nullable: bool = True
   is_primary_key: bool = False
   is_foreign_key: bool = False
   foreign_key_reference_table: str = None
   foreign_key_reference_column: str = None


class BaseTable(BaseModel):
   name: str
   description: str
   columns: list[BaseColumn]


class RDWTable(BaseTable):
   url: str
   database: str = &#8220;rdw_etl&#8221;</code></pre><p>Then the actual tables are constructed in <code>definitions.py</code>. Here, <code>input_col</code> denotes the original column name, and <code>output_col</code> is the translated and cleaned column name used in our tables. This is based on the RDWs own documentation of the dataset <a href="https://www.rdw.nl/-/media/rdwnl/documenten/informatieverstrekking/3-e-1891c--beschrijving-dataset-gekentekende-voertuigen-v54.pdf?rev=edfd37c342c049a080825ff50cf02dd9&amp;hash=4C64759A5536E8CBD1CFD1AB731D786D$0">here (pdf)</a>. LLMs and Databricks <code>ai_parse_document()</code> are your friend here to automatically populate the tables!</p><pre><code>RDWTable(
 url=&#8221;https://opendata.rdw.nl/api/views/m9d7-ebf2/rows.csv?accessType=DOWNLOAD&#8221;,
   name=&#8221;gekentekende_voertuigen&#8221;,
   description=&#8221;Main dataset of registered vehicles in the Netherlands. Contains comprehensive vehicle information including registration details, technical specifications, ownership, and inspection data.&#8221;,
   columns=[
       BaseColumn(
           input_col=&#8221;Kenteken&#8221;,
           output_col=&#8221;license_plate&#8221;,
           original_type=str,
           output_data_type=StringType(),
           is_primary_key=True,
           is_nullable=False,
           description=&#8221;The license plate of a vehicle, consisting of a combination of numbers and letters. This makes the vehicle unique and identifiable.&#8221;,
       ),
       BaseColumn(
           input_col=&#8221;Merk&#8221;,
           output_col=&#8221;make&#8221;,
           original_type=str,
           output_data_type=StringType(),
           description=&#8221;The make of the vehicle as specified by the manufacturer.&#8221;,
       ),
       BaseColumn(
           input_col=&#8221;Handelsbenaming&#8221;,
           output_col=&#8221;trade_name&#8221;,
           original_type=str,
           output_data_type=StringType(),
           description=&#8221;Trade name of the vehicle as provided by the manufacturer. May differ from what appears on the vehicle.&#8221;,
       ),
       # more columns here ...
   ]
)
</code></pre><p>Having defined all tables, it is now possible to start the ingestion. In this case, we opted to download raw <code>.csv</code> tables from the RDW dataset. Each table is then sent to a Volume in the bronze layer catalog, using a timestamped folder. In the full implementation timestamps are passed from the job start time environment variable.</p><pre><code>def download_table_data(table_name: str, run_timestamp: Optional[str] = None):
   table = get_table_by_name(table_name)
   if not table:
       raise TableNotFoundException(
           f&#8221;Table &#8216;{table_name}&#8217; not found. Available tables: {[t.name for t in rdw_tables]}&#8221;
       )


   # Use provided timestamp or generate new one
   timestamp = run_timestamp or datetime.now().strftime(&#8221;%Y-%m-%dT%H-%M&#8221;)
   destination = table.get_timestamped_volume_path(timestamp)


   chunked_download(table.url, destination)</code></pre><h3><strong>Bronze</strong></h3><p>The bronze layer typically contains a copy of the raw source data, with as little as preprocessing as possible. Copying raw data into a table can, for example, be achieved using <code>SQL COPY INTO</code>. In our use case, minimal preprocessing had to be performed as the source tables used whitespaces in the column names, which is not accepted (by default) in Delta tables. This was resolved by using the <code>table.output_col</code> values to rename columns. Consequently, the data was stored into the bronze layer Delta tables.</p><pre><code>def transform_bronze(df, table):
   df = convert_columns_from_definition(df, table)
   return df


def process_bronze_layer(table_name: str, run_timestamp: Optional[str] = None):
   table = get_table_by_name(table_name)
   if not table:
       raise TableNotFoundException(
           f&#8221;Table &#8216;{table_name}&#8217; not found. Available tables: {[t.name for t in rdw_tables]}&#8221;
       )


   # 1. Read CSV from volume
   if run_timestamp:
       timestamp = run_timestamp # use provided timestamp
   else:
       timestamp = get_latest_timestamp_folder(table.volume_base_path) # auto-detect latest timestamp folder


   source_path = table.get_timestamped_volume_path(timestamp)
   df = read_volume_csv(source_path)


   # 2. Apply bronze transformations
   logger.info(&#8221;Applying transformations&#8221;)
   df = transform_bronze(df, table)


   # 3. Write to bronze layer
   save_delta_table(df, table.delta_bronze_path)</code></pre><h3>Silver</h3><p>Most of the actual data processing happens in the silver layer. In our case, data is cleaned, validated and all of the metadata is added, such as primary/foreign keys, and table/column descriptions. Our data is validated using the DQX - Data Quality Framework by Databricks Labs. Using the <code>create_table_statements</code> function, the PKs, FKs, column types and nullable property are enforced. Then, <code>alter_comments_statements</code> generates SQL statements to set the table and column descriptions.</p><h5>Table metadata</h5><p>In the <code>BaseTable</code> class the functions <code>create_table_statement</code> and <code>alter_comment_statements</code> are used to build SQL statements for the table creation and comment setting, respectively. Both are essentially string builders that use information from the table definitions. For example, the comment statements are built using:</p><pre><code>def alter_comment_statements(self, catalog: str = bronze_catalog, schema: str = rdw_schema) -&gt; str:
   # Use an array because Spark.SQL() can only process one ALTER statement at a time.
   alter_statements = []


   # Add table-level comment
   table_comment = self.description.replace(&#8221;&#8217;&#8221;, &#8220;&#8221;)
   alter_statements.append(f&#8217;ALTER TABLE {catalog}.{schema}.{self.name} SET TBLPROPERTIES (&#8221;comment&#8221; = &#8220;{table_comment}&#8221;);\n&#8217;)


   # add comments for each col
   for col in self.columns:
       alter_statements.append(f&#8217;ALTER TABLE {catalog}.{schema}.{self.name} ALTER COLUMN {col.output_col} COMMENT &#8220;{col.comment}&#8221;;\n&#8217;)


   return alter_statements</code></pre><h5>Preparation script</h5><p>Before running the actual silver processing script, a small preparation script is executed that generates and builds the silver tables with primary keys set. This ensures that all tables are ready to be populated before running the processing step. Foreign keys are set in the processing script itself, as they can only be set after all tables with their primary keys exist.</p><h5>Data validation</h5><p>Data validation is the next step in order to ensure the contents of the tables match our expectations and quality standards. Specifically, we validate primary- and foreign keys contents, datetime formats and logic, and null values. All rows that get rejected during validation are placed in a quarantine table such that they can be inspected later, and if necessary, fixed. Our validation rules used the DQX framework and stored the rules in YAML configuration files. More on this in blog post 2!</p><h5>SCD2</h5><p>In our project we decided to go with a custom SCD2 implementation. Slowly Changing Dimensions (SCD) provides a solution for handling source data changes over time. The simplest approach is SCD type 1, which simply overwrites old values and is easiest to implement. SCD type 2 preserves history, and instead of overwriting, marks existing record as current or not. In our use case, it allows us to see cars that have been exported or scrapped, and are no longer in the dataset. Whilst useful, SCD2 does pose a trade-off with added complexity.</p><p>Databricks offers a few paths for implementing SCD2. Delta Live Tables provides built-in support through the <code>APPLY CHANGES INTO API</code>, but you can also implement it yourself using <code>MERGE</code> statements on standard Delta tables. We opted for a custom implementation as it provides more flexibility in a custom pipeline.</p><h5>Job script</h5><p>In the final silver job, the following steps are taken:</p><ul><li><p>Create and prepare the table with metadata using SQL</p></li><li><p>Read from bronze layer</p></li><li><p>Apply data validation</p></li><li><p>Perform SCD2</p></li><li><p>Write to silver layer</p></li></ul><p>The code looks as follows:</p><pre><code>def process_silver_layer(table_name: str, full_refresh: bool = False):
   spark = get_spark_session()


   # specify which table is processed
   table = get_table_by_name(table_name)
   if not table:
       raise TableNotFoundException(
           f&#8221;Table &#8216;{table_name}&#8217; not found. Available tables: {[t.name for t in rdw_tables]}&#8221;
       )


   # Ensure silver table exists with proper schema
   create_silver_table_if_not_exists(table, spark, logger)


   # 1. Read bronze snapshot and existing silver history
   bronze_data = read_delta_table(table.delta_bronze_path, spark)


   # 2. Apply data quality checks (quarantine is saved internally)
   new_snapshot = apply_dqx_validation(bronze_data, table, logger)


   old_snapshot = None
   if spark.catalog.tableExists(table.delta_silver_path):
       old_snapshot = read_delta_table(table.delta_silver_path, spark)
   # else -&gt; No existing silver history found (first load)


   # 3. Apply SCD2 transformations
   history = transform_silver(new_snapshot, old_snapshot, spark)


   # 4. Write to silver layer
   save_delta_table_preserve_constraints(history, table.delta_silver_path, spark)</code></pre><h3>Gold</h3><p>The gold layer typically contains aggregated and joined data. In our case we created a processed table of all registered vehicles. This involved filtering on the following criteria</p><ul><li><p>Entry is current SCD2 record <code>(`F.col(&#8221;__is_current&#8221;) == True`)</code>.</p></li><li><p>Vehicle was not recently exported</p></li><li><p>Passenger cars only</p></li><li><p>Car is not a taxi</p></li><li><p>Is insured and allowed to drive on the road</p></li></ul><p>In addition, a deduplicated table is saved which only contains distinct vehicles (brand/model) and does not contain car-specific information such as MOT expiration. We also construct a metric view which provides an aggregation of the registered vehicle data. The metric view is built from a YAML definition in <code>vehicle_fleet_metrics.yml</code>.</p><pre><code>def process_gold_layer():
   spark = get_spark_session()

   # Load
   df = load_silver_registered_vehicles(spark)

   # Transform
   df_main, df_dedup = transform_licensed_vehicles(df)

   # Save tables
   save_delta_table(df_main, f&#8221;{gold_catalog}.{rdw_schema}.registered_vehicles&#8221;)

   save_delta_table(df_dedup, f&#8221;{gold_catalog}.{rdw_schema}.registered_vehicles_dedup&#8221;
)
   # Create metric view
   yaml_path = VIEWS_DIR / &#8220;vehicle_fleet_metrics.yml&#8221;

   yaml_content = load_metric_view_yaml(yaml_path)
   metric_view_name = f&#8221;{gold_catalog}.{rdw_schema}.vehicle_fleet_metrics&#8221;
   create_metric_view(spark, metric_view_name, yaml_content)
</code></pre><h3><strong>Orchestration</strong></h3><p>The scripts are designed to take a single table and process it. The job to run the scripts takes a <code>for_each</code> structure and is able to process multiple tables in parallel with the <code>job_concurrency</code> parameter. This can be configured in your <code>databricks.yml</code> when setting up a Databricks Asset Bundle. Currently, the <code>rdw_table_names</code> variable is manually passed. There are better ways to do this, such as config files, Pydantic YAML definitions, or even dynamic job generation using PyDABs. More on this will follow in a later blog.</p><pre><code>rdw_table_names:
   description: List of RDW table names to process
   default: &#8216;[&#8221;odometer_reading_judgment_explanation&#8221;, &#8220;registered_vehicles&#8221;, &#8220;registered_vehicles_axles&#8221;, &#8220;registered_vehicles_fuel&#8221;, &#8220;registered_vehicles_body&#8221;, &#8220;registered_vehicles_body_specification&#8221;, &#8220;registered_vehicles_vehicle_class&#8221;, &#8220;registered_vehicles_subcategory&#8221;, &#8220;registered_vehicles_special_features&#8221;, &#8220;registered_vehicles_crawler_tracks&#8221;]&#8217;
# there is a better way to do this!
&#8212;
job_concurrency:
   description: Number of parallel tasks to run concurrently
   default: 4


resources:
 jobs:
   rdw_download:
     name: &#8220;RDW Data Download - ${var.environment}&#8221;
     tasks:
       - task_key: download_tables_foreach
         for_each_task:
           inputs: ${var.rdw_table_names}
           concurrency: ${var.job_concurrency}
           task:
             task_key: download_table_iteration
             python_wheel_task:
               package_name: rdw
               entry_point: download_rdw_data
               parameters:
                 - &#8220;--table-name={{input}}&#8221;
                 - &#8220;--run-timestamp={{job.start_time.iso_date}}T{{job.start_time.hour}}-{{job.start_time.minute}}&#8221;
             environment_key: default
</code></pre><h3>Conclusions</h3><p>This post explored the basic structure of our RDW data processing pipeline and gives a high-level overview of the project. It includes the processing steps required for implementing the Medallion architecture in Databricks with custom code. A few things stood out during implementation. First, defining table schemas upfront with Pydantic paid dividends throughout the project. Column mappings, type conversions, primary keys, and documentation all flow from a single source of truth. Second, proper job orchestration is key: the <code>for_each</code> job pattern in Databricks Asset Bundles made it efficient to scale from one table to ten without duplicating job definitions, using a single script that fits all tables. Lastly, the layered approach proved its worth: when business logic needed adjusting, silver could be rebuilt from bronze without re-downloading from source.</p><p>In the upcoming blog posts we will dive deeper into various aspects of the project such, such as a data exploration webapp, DQX validation and Databricks Asset Bundles (DABs).</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.cauchy.io/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 the Cauchy.io blog! Subscribe for free to receive new posts and upcoming 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></channel></rss>