<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oskar</title>
    <description>The latest articles on DEV Community by Oskar (@osquarski).</description>
    <link>https://dev.to/osquarski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3856857%2F86e413a0-7706-4237-9f3e-ca0edafdd0e4.jpeg</url>
      <title>DEV Community: Oskar</title>
      <link>https://dev.to/osquarski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/osquarski"/>
    <language>en</language>
    <item>
      <title>FinOps X 2026 recap: the great token panic</title>
      <dc:creator>Oskar</dc:creator>
      <pubDate>Mon, 15 Jun 2026 07:25:27 +0000</pubDate>
      <link>https://dev.to/osquarski/finops-x-2026-recap-the-great-token-panic-40l0</link>
      <guid>https://dev.to/osquarski/finops-x-2026-recap-the-great-token-panic-40l0</guid>
      <description>&lt;p&gt;If you were following the FinOps X 2026 conference that just wrapped up in San Diego (June 8–11, 2026), you probably noticed a massive shift. The discipline has officially outgrown its cloud-cost-management origins. While the expo floor had the usual vendor announcements, the real story for those of us building AI products was what the keynotes dubbed: "The Great Token Panic."&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://www.gartner.com/en/newsroom/press-releases/2026-05-19-gartner-forecasts-worldwide-ai-spending-to-grow-47-percent-in-2026" rel="noopener noreferrer"&gt;Gartner forecasting $2.59 trillion in AI spending in 2026&lt;/a&gt;, the era of treating AI costs as an unattributed R&amp;amp;D expense is over. Here are the core takeaways from the event and why they matter for engineering teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Arrival of Token Economics
&lt;/h2&gt;

&lt;p&gt;For the last decade, FinOps was about CPU hours, memory, and reserved instances. Now, the atomic unit of technology spend is the token.&lt;br&gt;
Because reasoning and agentic workloads consume 5 to 30 times more tokens per task than simple chat interactions, enterprise consumption is swamping the gradual decline in per-token list prices. AI token costs are variable, hard to forecast, and prone to rapid volatility. Recognizing this, the Linux Foundation and FinOps Foundation used the event to launch the Tokenomics Foundation. It's a massive industry effort uniting hyperscalers and enterprises to establish open standards for AI cost management and billing data.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Agentic FinOps and Moving Beyond Dashboards
&lt;/h2&gt;

&lt;p&gt;We are officially moving past static dashboards and natural-language wrappers on billing exports. The conference floor was dominated by the concept of "Agentic FinOps" - autonomous systems that don't just report on costs, but actively investigate and orchestrate remediation.&lt;br&gt;
Instead of analysts manually digging through blast radiuses, the next generation of tooling uses AI to continuously scan Kubernetes clusters, cloud environments, and AI service consumption to automatically route root-cause analysis straight into engineering workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. FinOps Scopes: Expanding the Definition
&lt;/h2&gt;

&lt;p&gt;The State of FinOps 2026 report made it clear: 90% of teams now manage SaaS costs or plan to within the year. The FinOps umbrella is expanding to cover private clouds, data platforms, software licensing, and, crucially, multi-model AI endpoints.&lt;br&gt;
Optimization efforts fail without accurate allocation. If you can't attribute the cost of an Anthropic or OpenAI API call to a specific product feature or user, you can't optimize it. Teams are shifting to virtual tagging and strict governance frameworks to isolate these costs before they scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Widespread Adoption of&amp;nbsp;FOCUS
&lt;/h2&gt;

&lt;p&gt;The FinOps Open Cost and Usage Specification (FOCUS) continues to gain traction as the universal billing format. As organizations juggle multiple AI providers, standardizing billing data into a universal schema is the only way to maintain portability. If your infrastructure emits FOCUS-compliant data, you can seamlessly integrate new ecosystem tools without having to rebuild your underlying data pipeline.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>infrastructure</category>
      <category>llm</category>
      <category>news</category>
    </item>
    <item>
      <title>How we cut our Dagster Cloud bill by 60% by collapsing our dbt assets</title>
      <dc:creator>Oskar</dc:creator>
      <pubDate>Mon, 15 Jun 2026 05:17:03 +0000</pubDate>
      <link>https://dev.to/osquarski/how-we-cut-our-dagster-cloud-bill-by-60-by-collapsing-our-dbt-assets-2</link>
      <guid>https://dev.to/osquarski/how-we-cut-our-dagster-cloud-bill-by-60-by-collapsing-our-dbt-assets-2</guid>
      <description>&lt;p&gt;If your team is using Dagster Cloud's Solo or Starter tiers, &lt;a href="https://support.dagster.io/articles/3171123463-dagster-solo-and-starter-pricing-updates-may-2026" rel="noopener noreferrer"&gt;the May 2026 pricing update probably gave you a bit of a shock&lt;/a&gt;. By removing the monthly credit allowance and charging for each step-executed asset materialization, workspaces that used to cost $10–$100 a month suddenly spiked into the hundreds or even over a thousand dollars.&lt;/p&gt;

&lt;p&gt;At Narev, we love the developer experience of Dagster, but our 24/7 schedule was driving up our bill to the point where self-hosting Airflow was starting to look attractive.&lt;/p&gt;

&lt;p&gt;Before jumping ship, we audited our setup and found a massive quick win: we were paying Dagster to coordinate a graph that dbt already understood. Here is how we fixed it and cut our orchestration bill by 60%.&lt;/p&gt;

&lt;h2&gt;
  
  
  The culprit: &lt;code&gt;@dbt_assets&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The standard &lt;a href="https://docs.dagster.io/integrations/libraries/dbt" rel="noopener noreferrer"&gt;dagster-dbt&lt;/a&gt; component is beautiful. You use &lt;code&gt;@dbt_assets&lt;/code&gt;, and Dagster maps every single dbt model and seed into an individual node in your Dagster UI.&lt;/p&gt;

&lt;p&gt;But under the new pricing model, every asset materialization has a cost (around $0.035 to $0.040 per credit). If you have a couple hundred dbt models running on an hourly or daily partition, you are burning credits just to have Dagster say, "Yep, dbt built this view."&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: One asset, One command
&lt;/h2&gt;

&lt;p&gt;We decided to collapse our entire dbt project into a single plain @asset that just shells out to dbt. Same dbt logic, same data, but far fewer orchestration steps.&lt;br&gt;
Here is what our refactored asset looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dagster&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AssetExecutionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;asset&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dagster_dbt&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DbtCliResource&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;etl.defs.partitions&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;daily_partition&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;etl.defs.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DeploymentType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_deployment_type&lt;/span&gt;

&lt;span class="nd"&gt;@asset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;partitions_def&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;daily_partition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;group_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transformers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;deps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dw_load&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dw_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AssetExecutionContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dbt_resource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DbtCliResource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;partition_time_window&lt;/span&gt;
    &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_deployment_type&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dbt_target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DeploymentType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PROD&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;dbt_vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;start_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--target&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dbt_target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--vars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbt_vars&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

    &lt;span class="c1"&gt;# The crucial part:
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dbt_resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cli&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_successful&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dbt build failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;All models updated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The gotcha: Drop the context
&lt;/h2&gt;

&lt;p&gt;If you try this, there is one massive trap you need to avoid. Do not pass &lt;code&gt;context=context&lt;/code&gt; to &lt;code&gt;dbt_resource.cli()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you do &lt;code&gt;result = dbt_resource.cli(args, context=context).wait()&lt;/code&gt;, the dagster-dbt package will still emit individual materialization events behind the scenes for every single model. You will end up paying for per-model orchestration without getting the per-model UI benefits.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;.wait()&lt;/code&gt; instead of &lt;code&gt;.stream()&lt;/code&gt; and dropping the context ensures you only pay for one materialization per partition per run.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-offs
&lt;/h2&gt;

&lt;p&gt;This optimization isn't entirely free. By hiding dbt's complexity from Dagster, you are giving up a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No per-model UI lineage&lt;/strong&gt;: You won't see individual staging models in the Dagster graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coarser alerting&lt;/strong&gt;: If a single model fails, the entire dw_transform asset goes red. You'll have to check the dbt logs to see exactly which model broke.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For us, this was a no-brainer. We rely on dbt docs and our warehouse for deep lineage anyway, and we only need Dagster to know: "Extract done → Load done → Transform done."&lt;/p&gt;

&lt;p&gt;If you want to see exactly how this changes downstream asset dependencies and how to wire up your jobs with this new pattern, I wrote a full breakdown on our blog (along with a drop-in Cursor prompt to automate the refactor for your workspace).&lt;/p&gt;

&lt;p&gt;Read the full guide &lt;a href="https://www.narev.ai/blog/lower-dagster-bill" rel="noopener noreferrer"&gt;on the Narev blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>devops</category>
      <category>database</category>
    </item>
    <item>
      <title>It's time to get familiar with what FinOps for AI is</title>
      <dc:creator>Oskar</dc:creator>
      <pubDate>Sun, 31 May 2026 17:05:10 +0000</pubDate>
      <link>https://dev.to/osquarski/its-time-to-get-familiar-with-what-finops-for-ai-is-49lk</link>
      <guid>https://dev.to/osquarski/its-time-to-get-familiar-with-what-finops-for-ai-is-49lk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;No Generative AI was used in writing this article. If you enjoyed reading it, please let me know. It helps me dedicate more time to things that resonate with my readers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It took Uber 4 months to burn the entire AI budget for 2026. The cost if AI, the ROI and the question of AI investment have entered the picture.&lt;/p&gt;

&lt;p&gt;Uber’s COO, Andrew MacDonald, said &lt;a href="https://youtu.be/y_mQ6xLcKyc?si=qcqDSlEwOV3AShmu&amp;amp;t=1720%5D" rel="noopener noreferrer"&gt;in his recent interview&lt;/a&gt; that the costs became “harder to justify” because the link between spending on AI tokens and creating more useful features “was not there”.&lt;/p&gt;

&lt;h2&gt;
  
  
  It started with all you can eat subscriptions.
&lt;/h2&gt;

&lt;p&gt;Since the early days of tech, we’ve been conditioned to expect all you can eat subscriptions. For a month, you could watch Netflix non-stop, for 24 hours, 7 days a week and you’d still pay the same price as if you watched only one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That’s a great deal!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In fact, such a good deal, that we see it everywhere. On Netflix, on Amazon Prime, pretty much all the software.&lt;/p&gt;

&lt;h2&gt;
  
  
  The magic of zero marginal cost (in digital goods)
&lt;/h2&gt;

&lt;p&gt;In traditional businesses, selling one more unit of physical product costs the company an extra unit of resources.&lt;/p&gt;

&lt;p&gt;Each flower bouquet of 5 roses sold requires 10 roses. Selling 100 bouquets will require 100 bouquets x 5 roses = 500 roses. This is called marginal cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But that’s not the case in the digital world!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once Netflix pays the massive upfront cost to produce Stranger Things ($30 million an episode), it costs them exactly the same amount of money whether 10 people watch it or 100 million people watch it. As long as they get enough subscriber to cover the initial investment, every new subscriber after that is 100% pure profit. This is a zero marginal cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Large Language Models are more like a flower shop
&lt;/h2&gt;

&lt;p&gt;The cost of generating tokens requires significant amount of energy. This makes token generation expensive.&lt;/p&gt;

&lt;p&gt;This week news cycle brought us a story about an anonymous company accidentally burning through $500M of tokens.&lt;/p&gt;

&lt;p&gt;This very nature of LLMs requires that all-you-can-eat subscriptions have to be subsidized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it a good thing?
&lt;/h2&gt;

&lt;p&gt;Ultimately, it’s about the unit economics.&lt;/p&gt;

&lt;p&gt;We went through a very similar pain with a shift to cloud computing. The solution was to not abandon AWS completely due to spiraling bills.&lt;/p&gt;

&lt;p&gt;Instead we built dashboards, tracked usage, and an entire discipline was born: FinOps.&lt;/p&gt;

&lt;p&gt;When the costs are real, the value has to be real too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where would you start?
&lt;/h2&gt;

&lt;p&gt;I'll leave you with the &lt;a href="https://www.narev.ai/guides/finops-for-ai" rel="noopener noreferrer"&gt;FinOps for AI framework from Narev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>news</category>
    </item>
    <item>
      <title>It was never easier to make software. It was never harder to make good software</title>
      <dc:creator>Oskar</dc:creator>
      <pubDate>Sun, 31 May 2026 11:23:21 +0000</pubDate>
      <link>https://dev.to/osquarski/it-was-never-easier-to-make-software-it-was-never-harder-to-make-good-software-cfe</link>
      <guid>https://dev.to/osquarski/it-was-never-easier-to-make-software-it-was-never-harder-to-make-good-software-cfe</guid>
      <description></description>
      <category>discuss</category>
      <category>programming</category>
      <category>software</category>
      <category>softwareengineering</category>
    </item>
  </channel>
</rss>
