<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article DBR 18: Streaming Workload Simplification with Improved AQE and AOS Support in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/dbr-18-streaming-workload-simplification-with-improved-aqe-and/ba-p/147752</link>
    <description>&lt;P&gt;&lt;SPAN&gt;Since 2022, Databricks Engineering has been on a mission to simplify streaming workloads through &lt;/SPAN&gt;&lt;STRONG&gt;Project Lightspeed&lt;/STRONG&gt;&lt;SPAN&gt;. We’ve democratized stateful processing with features like &lt;/SPAN&gt;&lt;A href="https://www.google.com/search?q=https://docs.databricks.com/aws/en/stateful-applications/%23what-is-transformwithstate" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;transformWithState&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; and the &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/structured-streaming/read-state" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;State Reader API&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Now, with &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/release-notes/runtime/18.0" target="_self"&gt;&lt;STRONG&gt;Databricks Runtime 18&lt;/STRONG&gt;&lt;/A&gt;&lt;SPAN&gt;, we are addressing one of the most persistent headaches in streaming optimization: &lt;/SPAN&gt;&lt;STRONG&gt;Shuffle tuning.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We are excited to announce that &lt;/SPAN&gt;&lt;STRONG&gt;Adaptive Query Execution (AQE)&lt;/STRONG&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;STRONG&gt;Auto Optimized Shuffle (AOS)&lt;/STRONG&gt;&lt;SPAN&gt; are now fully supported for &lt;/SPAN&gt;&lt;STRONG&gt;stateless Structured Streaming queries&lt;/STRONG&gt;&lt;SPAN&gt;. This update brings the "set it and forget it" simplicity of batch processing to your streaming pipelines.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Shuffle and When it Occurs&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/sql/language-manual/functions/shuffle" target="_self"&gt;Shuffle&lt;/A&gt; is the redistribution (repartitioning) of data across executors and partitions, usually inserted as an Exchange between stages; it moves rows over the network and is one of the costliest operators. If you are unsure whether your streaming job includes a shuffle stage, &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/aws/en/optimizations/spark-ui-guide/long-spark-stage" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;the Spark UI&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; can help you determine whether it is involved in the Spark plan, as not all streaming workloads require shuffle. A Spark query plan may include a shuffle stage for various reasons, including:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Joins, aggregations, and window operations: These introduce exchanges and therefore shuffles.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Global sorting: orderBy typically requires a shuffle for global ordering.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Explicit repartitioning: &lt;FONT face="courier new,courier"&gt;repartition(...)&lt;/FONT&gt; or output &lt;FONT face="courier new,courier"&gt;partitionBy(...)&lt;/FONT&gt; forces data redistribution before the write.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Non-broadcast joins: If the smaller side isn’t broadcast, the plan uses shuffle-based joins; AQE may switch to broadcast at runtime when thresholds allow.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;STRONG&gt;The Problem: The "200 Partition" Trap&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;If you’ve optimized streaming pipelines before DBR 18, you know the struggle.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;The "Auto" Illusion:&lt;/STRONG&gt;&lt;SPAN&gt; Setting &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;spark.sql.shuffle.partitions="auto"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; in a streaming query often did nothing, silently falling back to the default &lt;/SPAN&gt;&lt;STRONG&gt;200 partitions&lt;/STRONG&gt;&lt;SPAN&gt;. This left clusters underutilized on large workloads or created too many small files on tiny ones.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Manual Tuning:&lt;/STRONG&gt;&lt;SPAN&gt; You had to hard-code partition counts (e.g., 4000) based on peak traffic, leading to inefficiency during quiet periods.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;The &lt;/STRONG&gt;&lt;FONT face="courier new,courier"&gt;&lt;STRONG&gt;foreachBatch&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt; Hack:&lt;/STRONG&gt;&lt;SPAN&gt; To get around this, many developers resorted to complex &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;foreachBatch&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; workarounds to force a static batch plan, thereby triggering AQE. While effective, this added unnecessary complexity and maintenance overhead.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;STRONG&gt;The Solution: Adaptive Streaming in DBR 18&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;In DBR 18, the engine is finally smart enough to handle this for you. For stateless queries (like filters, projections, and stream-static joins), Spark now leverages the same adaptive intelligence used in batch jobs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Auto Optimized Shuffle (AOS) "Just Works"&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN&gt;When you set &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;spark.sql.shuffle.partitions&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; to &lt;/SPAN&gt;&lt;SPAN&gt;"&lt;FONT face="courier new,courier"&gt;auto&lt;/FONT&gt;"&lt;/SPAN&gt;&lt;SPAN&gt;, it actually behaves as "auto".&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;How it works:&lt;/STRONG&gt;&lt;SPAN&gt; AOS automatically determines the initial pre-shuffle partition count based on the estimated size of the micro-batch.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;The Impact:&lt;/STRONG&gt;&lt;SPAN&gt; No more hard-coded magic numbers. Whether your micro-batch is 100MB or 100GB, AOS sizes the shuffle correctly.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4&gt;&lt;STRONG&gt;AQE Enters the Chat&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN&gt;Once the shuffle happens, Adaptive Query Execution (AQE) steps in to optimize the plan on the fly.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Coalescing:&lt;/STRONG&gt;&lt;SPAN&gt; AQE combines small, empty partitions into properly sized ones, preventing the "small file problem" downstream.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Skew Handling:&lt;/STRONG&gt;&lt;SPAN&gt; It detects skewed data partitions and splits them dynamically to prevent straggler tasks from holding up the stream.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Join Optimization:&lt;/STRONG&gt;&lt;SPAN&gt; It can switch join strategies (e.g., &lt;FONT face="courier new,courier"&gt;SortMerge&lt;/FONT&gt; to &lt;FONT face="courier new,courier"&gt;Broadcast&lt;/FONT&gt;) at runtime based on actual data volume.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;STRONG&gt;Why This Matters&lt;/STRONG&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Simpler Code:&lt;/STRONG&gt;&lt;SPAN&gt; You can delete those foreachBatch wrappers and manual config overrides. Your streaming code focuses on business logic, not infrastructure tuning.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Better Performance:&lt;/STRONG&gt;&lt;SPAN&gt; Your streams instantly adapt to changes in data volume. A spike in traffic results in more partitions; a lull leads to fewer.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;Cost Efficiency:&lt;/STRONG&gt;&lt;SPAN&gt; No more over-provisioned clusters waiting on a few skewed tasks. AQE ensures resources are used efficiently.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;STRONG&gt;Getting Started&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;Upgrading is simple. Move your workspace to &lt;/SPAN&gt;&lt;STRONG&gt;DBR 18+&lt;/STRONG&gt;&lt;SPAN&gt;, and these optimizations are enabled by default for stateless queries.&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;AQE:&lt;/STRONG&gt;&lt;SPAN&gt; Enabled by default (&lt;FONT face="courier new,courier"&gt;spark.sql.adaptive.streaming.stateless.enabled = true&lt;/FONT&gt;).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;STRONG&gt;AOS:&lt;/STRONG&gt;&lt;SPAN&gt; Just set &lt;FONT face="courier new,courier"&gt;spark.sql.shuffle.partitions = "auto"&lt;/FONT&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Note: These improvements currently apply to stateless operators. Complex stateful repartitioning requires different heuristics and remains a focus for future Project Lightspeed efforts.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;With DBR 18, we are one step closer to a world where you simply write business logic, and the engine handles the rest. By bringing AQE and AOS to stateless streaming, we’re removing the "tuning tax" from data engineers, letting you focus on building value rather than managing partitions.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Stay tuned for more updates from Project Lightspeed!&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;FAQ: AQE and AOS in Streaming&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;STRONG&gt;Q:&lt;/STRONG&gt; Does this update apply to stateful streaming operations like aggregations or &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;mapGroupsWithState&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;? &lt;STRONG&gt;A:&lt;/STRONG&gt; No. Currently, these AQE and AOS improvements apply specifically to &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;stateless&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; queries (e.g., filters, projections, stream-static joins). Stateful repartitioning requires strict state store compatibility and is not yet supported by these specific features.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;STRONG&gt;Q:&lt;/STRONG&gt; Do I need to change my code to enable AQE for streaming? &lt;STRONG&gt;A:&lt;/STRONG&gt; In DBR 18+, AQE for stateless streaming is enabled by default via &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;spark.sql.adaptive.streaming.stateless.enabled&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt;. You do not need to change code, though you should ensure &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;spark.sql.shuffle.partitions&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; is set to &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;"auto"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; to leverage AOS.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;STRONG&gt;Q:&lt;/STRONG&gt; How does AOS determine the partition count for a micro-batch? &lt;STRONG&gt;A:&lt;/STRONG&gt; AOS estimates the size of the incoming micro-batch data and calculates an appropriate number of pre-shuffle partitions, ensuring the cluster isn't over-provisioned for small batches or choked by large ones.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;STRONG&gt;Q:&lt;/STRONG&gt; Will this fix "small file" problems in my downstream Delta tables? &lt;STRONG&gt;A:&lt;/STRONG&gt; Yes, indirectly. By using AQE to coalesce small partitions during the write phase, the engine writes fewer, larger files to storage, reducing the need for aggressive downstream &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;OPTIMIZE&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; or auto-compaction jobs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;STRONG&gt;Q:&lt;/STRONG&gt; Can I remove my existing &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;foreachBatch&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; logic? &lt;STRONG&gt;A:&lt;/STRONG&gt; If you were using &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;foreachBatch&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; solely to trigger batch-style AQE optimizations for a stateless write, you can likely revert to a standard streaming write in DBR 18. If the &lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&lt;SPAN&gt;foreachBatch&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN&gt; contains other custom logic (such as merging to external systems), you must keep it.&lt;/SPAN&gt;&lt;/P&gt;</description>
    <pubDate>Thu, 19 Feb 2026 17:58:34 GMT</pubDate>
    <dc:creator>craig_lukasik</dc:creator>
    <dc:date>2026-02-19T17:58:34Z</dc:date>
    <item>
      <title>DBR 18: Streaming Workload Simplification with Improved AQE and AOS Support</title>
      <link>https://community.databricks.com/t5/technical-blog/dbr-18-streaming-workload-simplification-with-improved-aqe-and/ba-p/147752</link>
      <description>&lt;P&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="0"&gt;Databricks Runtime 18 is finally ending the era of manual shuffle tuning for stateless streaming workloads. For years, data engineers struggled with the "200 Partition" trap, forcing complex&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;CODE class="appsElementsGenerativeaiAstInlineCode"&gt;foreachBatch&lt;/CODE&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="2"&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;workarounds and hard-coded partition counts to manage data fluctuations. Now, thanks to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="3"&gt;Project Lightspeed&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="4"&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="5"&gt;Adaptive Query Execution (AQE)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="6"&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="7"&gt;Auto Optimized Shuffle (AOS)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="8"&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;are fully supported for&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;I&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="9"&gt;stateless&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN class="appsElementsGenerativeaiAstAnimated" data-ast-node-id="10"&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Structured Streaming queries, automatically optimizing partition counts, handling data skew, and coalescing small files on the fly. Upgrade to DBR 18+ to instantly adapt your streams to any data volume, simplify your code, and bring the reliable "set it and forget it" performance of batch processing to your streaming pipelines.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 19 Feb 2026 17:58:34 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/dbr-18-streaming-workload-simplification-with-improved-aqe-and/ba-p/147752</guid>
      <dc:creator>craig_lukasik</dc:creator>
      <dc:date>2026-02-19T17:58:34Z</dc:date>
    </item>
  </channel>
</rss>

