<?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>rss.livelink.threads-in-node</title>
    <link>https://techcommunity.microsoft.com/t5/azure-data/ct-p/AzureDatabases</link>
    <description>rss.livelink.threads-in-node</description>
    <pubDate>Mon, 01 Jun 2026 04:01:43 GMT</pubDate>
    <dc:creator>AzureDatabases</dc:creator>
    <dc:date>2026-06-01T04:01:43Z</dc:date>
    <item>
      <title>Unlocking the Power of Azure Resource Graph Explorer for Comprehensive Database Inventory</title>
      <link>https://techcommunity.microsoft.com/t5/modernization-best-practices-and/unlocking-the-power-of-azure-resource-graph-explorer-for/ba-p/4392345</link>
      <description>&lt;H1&gt;Why Taking Inventory is Crucial&lt;/H1&gt;
&lt;P&gt;Taking inventory of databases in Azure is a critical practice for any organization managing cloud resources. It ensures that all databases are accounted for, providing a comprehensive overview of the organization’s data assets. This visibility is essential for effective management and optimization of resources, as it allows for better planning and allocation based on actual usage and requirements.&lt;/P&gt;
&lt;P&gt;An accurate inventory also plays a key role in identifying potential vulnerabilities and compliance issues. By knowing exactly what databases exist and where they reside, organizations can take proactive measures to secure sensitive data and adhere to regulatory standards.&lt;/P&gt;
&lt;P&gt;Additionally, maintaining an up-to-date inventory facilitates efficient troubleshooting and maintenance. When issues arise, having detailed insights into the configuration and status of each database significantly reduces resolution time.&lt;/P&gt;
&lt;P&gt;In short, keeping an accurate inventory of Azure databases supports operational efficiency, security, and compliance.&lt;/P&gt;
&lt;H1&gt;Who Does This Matter To&lt;/H1&gt;
&lt;P&gt;For roles such as product owners or operations managers, this task becomes even more critical. You may need to query the entire data estate to consolidate information for governance, reporting, or strategic planning. Without a centralized view, managing large-scale environments becomes challenging and prone to errors.&lt;/P&gt;
&lt;H1&gt;How Azure Resource Graph Explorer Helps&lt;/H1&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview" target="_blank" rel="noopener"&gt;Azure Resource Graph Explorer&lt;/A&gt; is a powerful tool designed to extend Azure Resource Management by enabling efficient and performant resource exploration across multiple subscriptions. It allows users to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Query resources with complex filtering, grouping, and sorting by resource properties.&lt;/LI&gt;
&lt;LI&gt;Explore resources at scale across multiple subscriptions.&lt;/LI&gt;
&lt;LI&gt;Iterate queries based on governance requirements.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This makes ARG an ideal solution for managing and governing large-scale environments where visibility and control are paramount.&lt;/P&gt;
&lt;P&gt;An Azure Resource Graph query like this one can help users to get an inventory of Azure SQL installations from data estates spanning across multiple subscriptions.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;resources | where type =~ "microsoft.sqlvirtualmachine/sqlvirtualmachines" | project SubscriptionId = subscriptionId, ResourceGroup = resourceGroup, Name = name, type, Location = location, tags, elasticPoolId = "", ServiceType = "SQL VM", Edition=tostring(properties.sqlImageSku), Environment=tostring(tags.opEnvironment), PricingModel="vCores", ServiceTier=tostring(properties.sqlImageOffer), IsAHB = iff(tostring(properties.sqlServerLicenseType) =~ "AHUB", "Yes", iff(tostring(properties.sqlServerLicenseType) =~ "PAYG" and tostring(tolower(properties.sqlImageSku)) =~ "Developer", "Yes", "No")) | join kind=inner (resources | where ['type'] =~ 'microsoft.compute/virtualmachines' | project SubscriptionId = subscriptionId, ResourceGroup = resourceGroup, Name = name, Location = location, Num=tostring(properties.hardwareProfile.vmSize)) on Name, ResourceGroup, Location, SubscriptionId | project-away SubscriptionId1,ResourceGroup1,Name1,Location1 | union ( Resources | project SubscriptionId = subscriptionId, ResourceGroup = resourceGroup, Name = name, type, Location = location, tags, elasticPoolId = tolower(tostring(properties.elasticPoolId)), ServiceType = case(type =~ "microsoft.sql/managedinstances", "Azure SQL MI", type =~ "microsoft.sql/servers/databases", iff(tolower(properties.currentSku.tier)=~"datawarehouse", "Synapse", "Azure SQL DB"), type =~ "microsoft.sql/servers/elasticpools", "Azure SQL DB Elastic Pools", "Azure SQL VM"), Edition = case(type in~ ("microsoft.sql/managedinstances","microsoft.sql/servers/databases","microsoft.sql/servers/elasticpools"), iff(tolower(properties.currentSku.tier)=~"datawarehouse", "Dedicated Pools", "Azure SQL") , "SQL VM"), Environment=tostring(tags.opEnvironment), Num = tostring(case(type =~ "microsoft.sql/managedinstances", toint(sku.capacity), type =~ "microsoft.sql/servers/databases", toint(properties.currentSku.capacity), type =~ "microsoft.sql/servers/elasticpools", toint(properties.perDatabaseSettings.maxCapacity), 0)), PricingModel = case(type =~ "microsoft.sql/managedinstances", "vCores", type =~ "microsoft.sql/servers/databases", iff(tolower(properties.currentSku.tier)=~"datawarehouse", "DWU", iff((tolower(sku.tier) in ("basic","standard","premium")), "DTU", "vCores")), type =~ "microsoft.sql/servers/elasticpools", iff((tolower(sku.tier) in ("basic","standard","premium")), "DTU", "vCores"), "vCores"), ServiceTier = case(type =~ "microsoft.sql/managedinstances", sku.tier, tolower(properties.currentSku.tier)), MaxDatabaseSizeGB = iff(tostring(properties.currentSku.tier)=~"hyperscale", 1000,properties.maxSizeBytes/(1024 * 1024 * 1024)), IsAHB = case(properties.licenseType == 'BasePrice', "Yes", "No"), Is_Replica=iff(tostring(properties.secondaryType) in("Geo","Standby"), "Yes","No"), Is_Standby_Replica=iff(tostring(properties.secondaryType)=~ "Standby", "Yes","No") | where (type =~ 'Microsoft.Sql/servers/databases' or type =~ "microsoft.sql/managedinstances" or type =~ "microsoft.sql/servers/elasticpools") and ServiceTier !in~ ("system") | join kind=leftouter ( Resources | where type =~ 'microsoft.sql/servers/elasticpools' | project elasticPoolId = tolower(id), elasticPoolName = name, elasticPoolSize=tostring(properties.perDatabaseSettings.maxCapacity)) on elasticPoolId | project-away elasticPoolId1 ) | order by ['Name'] asc&lt;/LI-CODE&gt;
&lt;P&gt;This process can be further bolstered by &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/governance/resource-graph/tutorials/logic-app-calling-arg" target="_blank" rel="noopener"&gt;automating &lt;/A&gt;the running of Azure Resource Graph queries and even acting on the results.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Let us know if any of these resonate with you or if have more suggestions!&lt;/P&gt;
&lt;H1&gt;Feedback&lt;/H1&gt;
&lt;P&gt;If you have feedback or suggestions for improving this data migration asset, please comment here or contact the Azure Databases SQL Customer Success Engineering Team (&lt;A href="mailto:datasqlninja@microsoft.com" target="_blank" rel="noopener"&gt;datasqlninja@microsoft.com&lt;/A&gt;) directly. Thanks for your support!&lt;/P&gt;
&lt;P&gt;Note: For additional information about migrating various source databases to Azure, see the&amp;nbsp;&lt;A href="https://datamigration.microsoft.com/" target="_blank" rel="noopener"&gt;Azure Database Migration Guide&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Fri, 29 May 2026 16:03:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/modernization-best-practices-and/unlocking-the-power-of-azure-resource-graph-explorer-for/ba-p/4392345</guid>
      <dc:creator>akumaranchath</dc:creator>
      <dc:date>2026-05-29T16:03:38Z</dc:date>
    </item>
    <item>
      <title>The Odd Couple - Latches and KEEP_NULLS</title>
      <link>https://techcommunity.microsoft.com/t5/modernization-best-practices-and/the-odd-couple-latches-and-keep-nulls/ba-p/4516048</link>
      <description>&lt;H2&gt;Introduction&lt;/H2&gt;
&lt;P&gt;Bulk loading is one of the most heavily optimised data paths in SQL Server. When it works well, hundreds of concurrent sessions can push millions of rows per minute into large tables with minimal CPU overhead. But when it doesn't, the symptoms can be baffling: CPU sits almost idle while every session waits, and throughput collapses by orders of magnitude.&lt;/P&gt;
&lt;P&gt;We recently worked with a customer running a large-scale data processing platform on Azure SQL Hyperscale Database. The workload used Spark to bulk-insert data from hundreds of concurrent sessions into multi-billion-row tables, each using &lt;CODE&gt;SEQUENCE&lt;/CODE&gt; objects to generate surrogate keys. After the team switched from row-by-row inserts to parallel bulk loading - a change that should have been a clear win - job durations went from minutes to over an hour. CPU utilisation sat at 2–5% while latch waits consumed over 98% of elapsed time.&lt;/P&gt;
&lt;P&gt;The root cause turned out to be a surprising interaction between two seemingly unrelated SQL Server features: &lt;STRONG&gt;SEQUENCE object latch modes&lt;/STRONG&gt; and the &lt;STRONG&gt;KEEP_NULLS bulk insert option&lt;/STRONG&gt;. Each is individually well-documented, but their combined effect under high-concurrency bulk insert workloads produced catastrophic serialisation that was not obvious from the documentation alone.&lt;/P&gt;
&lt;P&gt;This post distils the lessons learnt from that engagement into a reusable guide. We explain the mechanism, demonstrate the issue with reproducible tests on SQL Server 2025, and provide four independent fixes - the simplest of which is a single client-side configuration change that requires no schema modifications, no table rebuilds, and no downtime.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; Results may vary depending on hardware, SQL Server version, and workload patterns. All tests in this post were run on SQL Server 2025 (CU3). We recommend validating in your own dev/test environment.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;HR /&gt;
&lt;H2&gt;Background: The Ingredients&lt;/H2&gt;
&lt;P&gt;The workload used a common pattern for generating surrogate keys during bulk inserts:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;SEQUENCE objects&lt;/STRONG&gt; -&amp;nbsp;&lt;CODE&gt;CREATE SEQUENCE ... AS NUMERIC(28,0)&lt;/CODE&gt; - provided unique IDs&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;DEFAULT constraints&lt;/STRONG&gt; -&amp;nbsp;&lt;CODE&gt;ALTER TABLE ... ADD CONSTRAINT ... DEFAULT (NEXT VALUE FOR dbo.MySequence)&lt;/CODE&gt; - auto-populated IDs for rows that didn't supply them&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;INSERT BULK&lt;/STRONG&gt; - Spark's JDBC &lt;CODE&gt;SQLServerBulkCopy&lt;/CODE&gt; loaded data in parallel from ~350 concurrent sessions&lt;/LI&gt;
&lt;LI&gt;The application called &lt;CODE&gt;sp_sequence_get_range&lt;/CODE&gt; to &lt;STRONG&gt;pre-allocate&lt;/STRONG&gt; ID ranges and supplied IDs with every row - the DEFAULT was there as a safety net, not the primary path&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Each component is sensible on its own. The problem emerges from their interaction.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;The Problem: Two Layers of Serialisation&lt;/H2&gt;
&lt;H3&gt;Layer 1: INSERT BULK Fires the DEFAULT - Even When You Supply Values&lt;/H3&gt;
&lt;P&gt;When &lt;CODE&gt;INSERT BULK&lt;/CODE&gt; (the TDS protocol used by BCP, &lt;CODE&gt;BULK INSERT&lt;/CODE&gt;, and JDBC &lt;CODE&gt;SQLServerBulkCopy&lt;/CODE&gt;) runs &lt;STRONG&gt;without&lt;/STRONG&gt; the &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt; option, the engine sets an internal flag (&lt;CODE&gt;HNT_KEEPDEFAULT&lt;/CODE&gt;) that wraps every DEFAULT-constrained column as:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ISNULL(source_value, default_expression)&lt;/LI-CODE&gt;
&lt;P&gt;The &lt;CODE&gt;default_expression&lt;/CODE&gt; - in this case &lt;CODE&gt;NEXT VALUE FOR&lt;/CODE&gt; - is evaluated by a &lt;STRONG&gt;Sequence Project&lt;/STRONG&gt; iterator that runs &lt;STRONG&gt;unconditionally per row&lt;/STRONG&gt;, before the &lt;CODE&gt;ISNULL&lt;/CODE&gt; decides whether to use it. Even though every row in our workload supplied a valid non-NULL ID, the sequence latch was still acquired, the counter was incremented, and the generated value was discarded.&lt;/P&gt;
&lt;P&gt;This is fundamentally different from a regular &lt;CODE&gt;INSERT ... SELECT&lt;/CODE&gt; statement, where &lt;CODE&gt;NEXT VALUE FOR&lt;/CODE&gt; only fires if the column is actually omitted from the column list.&lt;/P&gt;
&lt;H3&gt;Layer 2: NUMERIC Sequences Take Exclusive Latches&lt;/H3&gt;
&lt;P&gt;SQL Server's sequence generator uses different synchronisation strategies depending on the sequence data type:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Sequence Type&lt;/th&gt;&lt;th&gt;Latch Mode&lt;/th&gt;&lt;th&gt;Concurrency&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;NUMERIC&lt;/CODE&gt; / &lt;CODE&gt;DECIMAL&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Exclusive (EX)&lt;/STRONG&gt; per row&lt;/td&gt;&lt;td&gt;Fully serialised - one thread at a time&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;BIGINT&lt;/CODE&gt; / &lt;CODE&gt;INT&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Shared (SH)&lt;/STRONG&gt; + atomic CPU increment&lt;/td&gt;&lt;td&gt;Concurrent - multiple threads progress&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The difference is not in the sequence &lt;EM&gt;cache&lt;/EM&gt; (which only reduces disk I/O) but in the in-memory latch that protects the counter. With a &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; sequence, every single row - across all 350 concurrent sessions - must wait in line for one exclusive latch.&lt;/P&gt;
&lt;H3&gt;The Combined Effect&lt;/H3&gt;
&lt;P&gt;Combining both layers produces catastrophic serialisation:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;350 sessions × 50,000 rows each = &lt;STRONG&gt;17.5 million unnecessary exclusive latch acquisitions&lt;/STRONG&gt; per bulk load cycle&lt;/LI&gt;
&lt;LI&gt;Each acquisition blocks all other sessions&lt;/LI&gt;
&lt;LI&gt;CPU sits idle while threads wait in the latch queue&lt;/LI&gt;
&lt;LI&gt;With &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; + no &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt;, the workload was 98% wait time and 2% CPU time&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The diagnostic signature is unmistakable: &lt;CODE&gt;LATCH_EX&lt;/CODE&gt; dominant in wait stats, low CPU utilisation, and all waiting sessions blocked on &lt;CODE&gt;METADATA_SEQUENCE_GENERATOR&lt;/CODE&gt;.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;Proving It: The KEEP_NULLS Experiment&lt;/H2&gt;
&lt;P&gt;The simplest proof is to BCP 10,000 rows - all with application-supplied IDs - and check whether the sequence counter advances.&lt;/P&gt;
&lt;H3&gt;Setup&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;CREATE SEQUENCE dbo.Seq_Orders
    AS NUMERIC(28, 0)
    START WITH 1 INCREMENT BY 1 CACHE 50000000;
GO

CREATE TABLE dbo.Orders
(
    OrderID     NUMERIC(28, 0)  NOT NULL
        CONSTRAINT DF_Orders_ID DEFAULT (NEXT VALUE FOR dbo.Seq_Orders),
    CustomerID  INT             NOT NULL,
    OrderDate   DATE            NOT NULL,
    Amount      DECIMAL(10, 2)  NOT NULL,
    Filler      CHAR(80)        NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Orders PRIMARY KEY CLUSTERED (OrderID)
);
GO&lt;/LI-CODE&gt;
&lt;P&gt;Generate a BCP data file with IDs 1-10,000 pre-assigned by the application.&lt;/P&gt;
&lt;H3&gt;Test 1: BCP Without KEEP_NULLS (Default Behaviour)&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;bcp MyDB.dbo.Orders in orders.dat -c -t"," -S localhost\sql25 -T&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Result:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Metric&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Rows stored&lt;/td&gt;&lt;td&gt;10,000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Stored OrderIDs&lt;/td&gt;&lt;td&gt;1-10,000 (app-supplied - correct)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sequence current_value&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;20,000&lt;/STRONG&gt; (advanced from 1)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The sequence advanced by at least 10,000 values, even though the stored IDs are entirely from the application. The &lt;CODE&gt;NEXT VALUE FOR&lt;/CODE&gt; default fired per-row, consumed sequence values, and discarded them all.&lt;/P&gt;
&lt;H3&gt;Test 2: BCP With KEEP_NULLS&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;bcp MyDB.dbo.Orders in orders.dat -c -t"," -S localhost\sql25 -T -k&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Result:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Metric&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Rows stored&lt;/td&gt;&lt;td&gt;10,000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Stored OrderIDs&lt;/td&gt;&lt;td&gt;1-10,000 (app-supplied - correct)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Sequence current_value&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;1&lt;/STRONG&gt; (unchanged)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;With &lt;CODE&gt;-k&lt;/CODE&gt; (KEEP_NULLS), the sequence did not advance at all. The &lt;CODE&gt;ISNULL&lt;/CODE&gt; wrapper was not applied, the Sequence Project iterator was not added to the plan, and all 10,000 latch acquisitions were eliminated.&lt;/P&gt;
&lt;H3&gt;Test 3: Table Without DEFAULT (Control)&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;bcp MyDB.dbo.Orders_NoDefault in orders.dat -c -t"," -S localhost\sql25 -T&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Result:&lt;/STRONG&gt; Sequence unchanged at 1. No DEFAULT means no Sequence Project, regardless of &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt;.&lt;/P&gt;
&lt;H3&gt;Summary&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Scenario&lt;/th&gt;&lt;th&gt;DEFAULT Exists&lt;/th&gt;&lt;th&gt;KEEP_NULLS&lt;/th&gt;&lt;th&gt;Sequence Advances?&lt;/th&gt;&lt;th&gt;Latch Per Row?&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;BCP (default behaviour)&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Yes - wasted&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Yes - serialised&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;BCP with &lt;CODE&gt;-k&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Yes&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;BCP, no DEFAULT&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Regular INSERT...SELECT&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;No (column supplied)&lt;/td&gt;&lt;td&gt;No&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The fourth row is important: a standard &lt;CODE&gt;INSERT ... SELECT&lt;/CODE&gt; that includes the &lt;CODE&gt;OrderID&lt;/CODE&gt; column does &lt;STRONG&gt;not&lt;/STRONG&gt; fire the DEFAULT. This behaviour is specific to the INSERT BULK protocol.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;Proving It: NUMERIC vs BIGINT Latch Contention&lt;/H2&gt;
&lt;P&gt;Even when the DEFAULT must fire (for example, when the application genuinely relies on it), the sequence data type determines the severity of the contention.&lt;/P&gt;
&lt;P&gt;We tested three configurations at 32 concurrent sessions, each inserting 20,000 rows via &lt;CODE&gt;INSERT ... DEFAULT VALUES&lt;/CODE&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Metric&lt;/th&gt;&lt;th&gt;NUMERIC(28,0)&lt;/th&gt;&lt;th&gt;BIGINT→NUMERIC&lt;/th&gt;&lt;th&gt;BIGINT&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Latch wait requests&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;137,321&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;7&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;23&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Latch total wait (ms)&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;37,661&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;210&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;384&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Latch max single wait (ms)&lt;/td&gt;&lt;td&gt;53&lt;/td&gt;&lt;td&gt;54&lt;/td&gt;&lt;td&gt;18&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;EM&gt;(32 sessions × 20,000 rows, SQL Server 2025, localhost)&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;The "BIGINT→NUMERIC" column uses a &lt;CODE&gt;BIGINT&lt;/CODE&gt; sequence feeding a &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; column. This proves that &lt;STRONG&gt;the latch mode follows the SEQUENCE type, not the column type&lt;/STRONG&gt;. Changing the sequence from &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; to &lt;CODE&gt;BIGINT&lt;/CODE&gt; is a metadata-only operation (&lt;CODE&gt;DROP SEQUENCE&lt;/CODE&gt; + &lt;CODE&gt;CREATE SEQUENCE AS BIGINT&lt;/CODE&gt;) that delivers a &lt;STRONG&gt;99.4% reduction in latch waits&lt;/STRONG&gt; without requiring any table rebuild.&lt;/P&gt;
&lt;H3&gt;IDENTITY Columns Have the Same Issue&lt;/H3&gt;
&lt;P&gt;The NUMERIC-vs-BIGINT latch behaviour is not limited to SEQUENCE objects - it applies equally to &lt;STRONG&gt;IDENTITY columns&lt;/STRONG&gt;. An &lt;CODE&gt;IDENTITY&lt;/CODE&gt; column defined as &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; or &lt;CODE&gt;DECIMAL(28,0)&lt;/CODE&gt; takes an exclusive latch on the identity counter for every inserted row, while &lt;CODE&gt;BIGINT IDENTITY&lt;/CODE&gt; uses a shared latch with atomic increments. The identity counter latch class (&lt;CODE&gt;IDENTITYVALUE_GENERATOR&lt;/CODE&gt;) follows the same exclusive-vs-shared pattern as &lt;CODE&gt;METADATA_SEQUENCE_GENERATOR&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;For tables that use &lt;CODE&gt;NUMERIC IDENTITY&lt;/CODE&gt; under high-concurrency insert workloads, changing the column type to &lt;CODE&gt;BIGINT&lt;/CODE&gt; eliminates the serialisation. Unlike sequences, changing an identity column's data type requires &lt;CODE&gt;ALTER TABLE ... ALTER COLUMN&lt;/CODE&gt;, which triggers a table rebuild for large tables. Plan this as a maintenance window operation for billion-row tables.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;The Fixes&lt;/H2&gt;
&lt;P&gt;Four independent fixes address different layers of the problem. Any one of them helps; the combination eliminates the issue entirely.&lt;/P&gt;
&lt;H3&gt;Fix 1: Enable KEEP_NULLS in the Bulk Copy Client&lt;/H3&gt;
&lt;P&gt;This is the single highest-impact fix. When the application supplies all column values, enabling &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt; prevents the engine from evaluating any DEFAULT constraint during &lt;CODE&gt;INSERT BULK&lt;/CODE&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Spark JDBC:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;.option("bulkCopyForBatchInsertKeepNulls", "true")&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;JDBC directly:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="java"&gt;SQLServerBulkCopyOptions opts = new SQLServerBulkCopyOptions();
opts.setKeepNulls(true);&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;BCP:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;bcp ... -k&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;BULK INSERT:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;BULK INSERT dbo.Orders FROM 'data.dat' WITH (KEEPNULLS);&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Impact:&lt;/STRONG&gt; Eliminates 100% of unnecessary sequence latch acquisitions during bulk insert. If the application already supplies the ID column, this fix has zero behavioural side effects.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Warning:&lt;/STRONG&gt; &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt; applies to &lt;STRONG&gt;all&lt;/STRONG&gt; columns, not just the sequence column. When enabled, any column where the source data contains NULL will store NULL rather than the column's DEFAULT value. If your table has other DEFAULT constraints that the application relies on - for example, &lt;CODE&gt;CreatedDate DATE DEFAULT GETDATE()&lt;/CODE&gt; or &lt;CODE&gt;Status VARCHAR(20) DEFAULT 'Pending'&lt;/CODE&gt; - those defaults will &lt;STRONG&gt;not&lt;/STRONG&gt; fire for NULL values when &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt; is active. Before enabling this option, verify that the application supplies values for every column, or that NULL is acceptable for columns the application omits. If some columns genuinely need their defaults, Fix 2 (dropping only the sequence DEFAULT) is the safer server-side alternative.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Fix 2: Drop the DEFAULT Constraint&lt;/H3&gt;
&lt;P&gt;If every insert path supplies the ID column, the DEFAULT constraint serves no purpose. Dropping it is an instant metadata-only DDL operation:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER TABLE dbo.Orders DROP CONSTRAINT DF_Orders_ID;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Impact:&lt;/STRONG&gt; Same as Fix 1, but enforced server-side. No client configuration required. Consider this if multiple applications insert into the table and you cannot guarantee all of them will set &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt;.&lt;/P&gt;
&lt;H3&gt;Fix 3: Change NUMERIC Sequences to BIGINT&lt;/H3&gt;
&lt;P&gt;For scenarios where the DEFAULT must fire - for example, ad-hoc inserts, SSMS, or stored procedures that omit the ID column - changing the sequence type from &lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt; to &lt;CODE&gt;BIGINT&lt;/CODE&gt; switches from exclusive to shared latching:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Wrap in a transaction so the workload never sees a moment without the DEFAULT.
-- Without the transaction, inserts that rely on the DEFAULT would fail between
-- the DROP CONSTRAINT and the ADD CONSTRAINT.

BEGIN TRANSACTION;

    -- Step 1: Record current value
    DECLARE @current BIGINT;
    SELECT @current = CAST(current_value AS BIGINT)
    FROM sys.sequences WHERE name = 'Seq_Orders';

    -- Step 2: Drop DEFAULT, drop sequence, recreate as BIGINT, re-add DEFAULT
    ALTER TABLE dbo.Orders DROP CONSTRAINT DF_Orders_ID;
    DROP SEQUENCE dbo.Seq_Orders;

    CREATE SEQUENCE dbo.Seq_Orders
        AS BIGINT
        START WITH @current INCREMENT BY 1 CACHE 50000000;

    ALTER TABLE dbo.Orders
        ADD CONSTRAINT DF_Orders_ID DEFAULT (NEXT VALUE FOR dbo.Seq_Orders) FOR OrderID;

COMMIT TRANSACTION;&lt;/LI-CODE&gt;
&lt;P&gt;Wrapping the four statements in a single transaction ensures that concurrent inserts never see a state where the DEFAULT constraint is missing. Without the transaction, any insert that relies on the DEFAULT would fail with an error between the &lt;CODE&gt;DROP CONSTRAINT&lt;/CODE&gt; and the &lt;CODE&gt;ADD CONSTRAINT&lt;/CODE&gt;. All four operations are metadata-only and the transaction completes in under a second. The column type (&lt;CODE&gt;NUMERIC(28,0)&lt;/CODE&gt;) does not need to change - SQL Server implicitly converts &lt;CODE&gt;BIGINT&lt;/CODE&gt; to &lt;CODE&gt;NUMERIC&lt;/CODE&gt; on insert.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Impact:&lt;/STRONG&gt; 99.4% reduction in latch wait time when the DEFAULT does fire. &lt;CODE&gt;BIGINT&lt;/CODE&gt; covers values up to 9.2 × 10^18, which is sufficient for virtually all surrogate key scenarios.&lt;/P&gt;
&lt;H3&gt;Fix 4: Right-Size Sequence Cache&lt;/H3&gt;
&lt;P&gt;The sequence &lt;CODE&gt;CACHE&lt;/CODE&gt; setting controls how many values are pre-allocated in memory before the next disk write to the system catalog. The default cache is 50, which is far too small for high-volume bulk inserts:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER SEQUENCE dbo.Seq_Orders CACHE 50000000;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Impact:&lt;/STRONG&gt; Reduces disk I/O during sequence value generation. This does &lt;STRONG&gt;not&lt;/STRONG&gt; change the latch mode - it only reduces how often the latch must also perform a catalog write. Fix 3 addresses the latch mode; this fix addresses the I/O.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;When Each Fix Applies&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Scenario&lt;/th&gt;&lt;th&gt;Fix 1 (KEEP_NULLS)&lt;/th&gt;&lt;th&gt;Fix 2 (Drop DEFAULT)&lt;/th&gt;&lt;th&gt;Fix 3 (BIGINT)&lt;/th&gt;&lt;th&gt;Fix 4 (Cache)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;App supplies IDs via bulk insert&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Primary fix&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Backup/server-side&lt;/td&gt;&lt;td&gt;Reduces residual contention&lt;/td&gt;&lt;td&gt;Helpful&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;App relies on DEFAULT for IDs&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Primary fix&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Mixed: some paths supply, some don't&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;For bulk paths&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;For DEFAULT paths&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SEQUENCE used in sp_sequence_get_range only&lt;/td&gt;&lt;td&gt;Not needed&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Drop it&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Helpful&lt;/td&gt;&lt;td&gt;Helpful&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;HR /&gt;
&lt;H2&gt;How to Detect This Pattern&lt;/H2&gt;
&lt;H3&gt;Wait Stats&lt;/H3&gt;
&lt;P&gt;Query &lt;CODE&gt;sys.dm_os_wait_stats&lt;/CODE&gt; or &lt;CODE&gt;sys.dm_os_latch_stats&lt;/CODE&gt; for the signature:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Check for sequence latch contention
SELECT
    latch_class,
    waiting_requests_count,
    wait_time_ms,
    max_wait_time_ms
FROM sys.dm_os_latch_stats
WHERE latch_class = 'METADATA_SEQUENCE_GENERATOR'
  AND waiting_requests_count &amp;gt; 0;&lt;/LI-CODE&gt;
&lt;P&gt;If &lt;CODE&gt;METADATA_SEQUENCE_GENERATOR&lt;/CODE&gt; appears with high &lt;CODE&gt;waiting_requests_count&lt;/CODE&gt; alongside &lt;CODE&gt;LATCH_EX&lt;/CODE&gt; dominating &lt;CODE&gt;sys.dm_os_wait_stats&lt;/CODE&gt;, this pattern is likely active.&lt;/P&gt;
&lt;H3&gt;Sequence Consumption Rate&lt;/H3&gt;
&lt;P&gt;Compare the sequence advance rate against actual row insertions:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- If sequence advances much faster than rows are inserted,
-- DEFAULT is firing unnecessarily during bulk inserts
SELECT
    s.name AS sequence_name,
    CAST(s.current_value AS BIGINT) AS current_value,
    s.data_type,
    s.cache_size
FROM sys.sequences s
WHERE s.data_type IN ('numeric', 'decimal');&lt;/LI-CODE&gt;
&lt;P&gt;Sequences typed as &lt;CODE&gt;NUMERIC&lt;/CODE&gt; or &lt;CODE&gt;DECIMAL&lt;/CODE&gt; under high-concurrency workloads are the risk profile.&lt;/P&gt;
&lt;H3&gt;Execution Plans&lt;/H3&gt;
&lt;P&gt;Look for a &lt;STRONG&gt;Sequence Project&lt;/STRONG&gt; iterator in the execution plan of &lt;CODE&gt;INSERT BULK&lt;/CODE&gt; operations. If the application supplies the ID column, a Sequence Project indicates the DEFAULT is being evaluated unnecessarily.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2&gt;Test Scripts&lt;/H2&gt;
&lt;P&gt;The scripts used for all benchmarks in this post are included below. Each can be run on any SQL Server 2019+ instance.&lt;/P&gt;
&lt;H3&gt;Setup: Database, Sequences, and Tables&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;USE master;
GO

IF DB_ID('LatchKeepNullsDemo') IS NOT NULL
BEGIN
    ALTER DATABASE LatchKeepNullsDemo SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE LatchKeepNullsDemo;
END
GO

CREATE DATABASE LatchKeepNullsDemo;
GO
USE LatchKeepNullsDemo;
GO

-- Table WITH NEXT VALUE FOR DEFAULT (demonstrates the problem)
CREATE SEQUENCE dbo.Seq_Orders_Numeric
    AS NUMERIC(28, 0)
    START WITH 1 INCREMENT BY 1 CACHE 50000000;
GO

CREATE TABLE dbo.Orders_WithDefault
(
    OrderID     NUMERIC(28, 0)  NOT NULL
        CONSTRAINT DF_Orders_ID DEFAULT (NEXT VALUE FOR dbo.Seq_Orders_Numeric),
    CustomerID  INT             NOT NULL,
    OrderDate   DATE            NOT NULL,
    Amount      DECIMAL(10, 2)  NOT NULL,
    Filler      CHAR(80)        NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Orders_WithDefault PRIMARY KEY CLUSTERED (OrderID)
);
GO

-- Table WITHOUT DEFAULT (control)
CREATE TABLE dbo.Orders_NoDefault
(
    OrderID     NUMERIC(28, 0)  NOT NULL,
    CustomerID  INT             NOT NULL,
    OrderDate   DATE            NOT NULL,
    Amount      DECIMAL(10, 2)  NOT NULL,
    Filler      CHAR(80)        NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Orders_NoDefault PRIMARY KEY CLUSTERED (OrderID)
);
GO

-- NUMERIC(28,0) sequence for latch test
CREATE SEQUENCE dbo.Seq_Latch_Numeric
    AS NUMERIC(28, 0) START WITH 1 INCREMENT BY 1 CACHE 50000000;
GO

CREATE TABLE dbo.Inserts_Numeric
(
    ID      NUMERIC(28, 0)  NOT NULL
        DEFAULT (NEXT VALUE FOR dbo.Seq_Latch_Numeric),
    Filler  CHAR(100)       NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Inserts_Numeric PRIMARY KEY CLUSTERED (ID)
);
GO

-- BIGINT sequence for latch test
CREATE SEQUENCE dbo.Seq_Latch_BigInt
    AS BIGINT START WITH 1 INCREMENT BY 1 CACHE 50000000;
GO

CREATE TABLE dbo.Inserts_BigInt
(
    ID      BIGINT          NOT NULL
        DEFAULT (NEXT VALUE FOR dbo.Seq_Latch_BigInt),
    Filler  CHAR(100)       NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Inserts_BigInt PRIMARY KEY CLUSTERED (ID)
);
GO

-- BIGINT sequence + NUMERIC column (proves latch follows sequence type)
CREATE SEQUENCE dbo.Seq_Latch_Mixed
    AS BIGINT START WITH 1 INCREMENT BY 1 CACHE 50000000;
GO

CREATE TABLE dbo.Inserts_Mixed
(
    ID      NUMERIC(28, 0)  NOT NULL
        DEFAULT (NEXT VALUE FOR dbo.Seq_Latch_Mixed),
    Filler  CHAR(100)       NOT NULL DEFAULT ('x'),
    CONSTRAINT PK_Inserts_Mixed PRIMARY KEY CLUSTERED (ID)
);
GO
&lt;/LI-CODE&gt;&lt;LI-CODE lang="sql"&gt;-- Helper: Generate BCP test data with app-supplied IDs
CREATE OR ALTER PROCEDURE dbo.GenerateBCPData @RowCount INT = 10000
AS
BEGIN
    SET NOCOUNT ON;
    ;WITH Nums AS (
        SELECT TOP(@RowCount) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS n
        FROM sys.all_objects a CROSS JOIN sys.all_objects b
    )
    SELECT
        CAST(n AS NUMERIC(28,0))                                        AS OrderID,
        ABS(CHECKSUM(NEWID())) % 10000 + 1                              AS CustomerID,
        CAST(DATEADD(DAY, -(n % 365), '2026-03-31') AS DATE)            AS OrderDate,
        CAST(ABS(CHECKSUM(NEWID())) % 100000 / 100.0 AS DECIMAL(10,2))  AS Amount,
        REPLICATE('x', 80)                                              AS Filler
    FROM Nums;
END
GO&lt;/LI-CODE&gt;
&lt;H3&gt;Test: BCP KEEP_NULLS Comparison&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;# Step 1: Export test data
bcp "EXEC LatchKeepNullsDemo.dbo.GenerateBCPData @RowCount=10000" \
    queryout orders.dat -c -t"," -S localhost\sql25 -T

# Step 2: Record sequence starting value
sqlcmd -S localhost\sql25 -d LatchKeepNullsDemo -Q \
    "SELECT name, CAST(current_value AS VARCHAR(30)) AS val
     FROM sys.sequences WHERE name = 'Seq_Orders_Numeric';"

# Step 3a: BCP WITHOUT KEEP_NULLS (DEFAULT fires per-row)
bcp LatchKeepNullsDemo.dbo.Orders_WithDefault in orders.dat \
    -c -t"," -S localhost\sql25 -T

# Check: sequence should have advanced (values wasted)
sqlcmd -S localhost\sql25 -d LatchKeepNullsDemo -Q \
    "SELECT name, CAST(current_value AS VARCHAR(30)) AS val
     FROM sys.sequences WHERE name = 'Seq_Orders_Numeric';"

# Step 3b: Reset, then BCP WITH KEEP_NULLS (DEFAULT suppressed)
sqlcmd -S localhost\sql25 -d LatchKeepNullsDemo -Q \
    "TRUNCATE TABLE dbo.Orders_WithDefault;
     ALTER SEQUENCE dbo.Seq_Orders_Numeric RESTART WITH 1;"

bcp LatchKeepNullsDemo.dbo.Orders_WithDefault in orders.dat \
    -c -t"," -S localhost\sql25 -T -k

# Check: sequence should NOT have advanced
sqlcmd -S localhost\sql25 -d LatchKeepNullsDemo -Q \
    "SELECT name, CAST(current_value AS VARCHAR(30)) AS val
     FROM sys.sequences WHERE name = 'Seq_Orders_Numeric';"&lt;/LI-CODE&gt;
&lt;H3&gt;Test: Concurrent Latch Comparison (PowerShell)&lt;/H3&gt;
&lt;LI-CODE lang="powershell"&gt;# Compare NUMERIC vs BIGINT sequence latch contention
# under N concurrent sessions, each inserting via INSERT...DEFAULT VALUES

param(
    [int]$Sessions = 16,
    [int]$RowsPerSession = 10000,
    [string]$Server = "localhost\sql25"
)

$db = "LatchKeepNullsDemo"

function Invoke-ConcurrentInserts {
    param([string]$TableName, [string]$Label)

    sqlcmd -S $Server -E -d $db -Q "TRUNCATE TABLE dbo.$TableName;" -b 2&amp;gt;&amp;amp;1 | Out-Null
    sqlcmd -S $Server -E -d $db `
        -Q "DBCC SQLPERF('sys.dm_os_latch_stats', CLEAR) WITH NO_INFOMSGS;" `
        -b 2&amp;gt;&amp;amp;1 | Out-Null

    $sql = "SET NOCOUNT ON; DECLARE @i INT = 0; " +
           "WHILE @i &amp;lt; $RowsPerSession BEGIN " +
           "INSERT INTO dbo.$TableName DEFAULT VALUES; SET @i += 1; END"

    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    $jobs = @()
    for ($s = 0; $s -lt $Sessions; $s++) {
        $jobs += Start-Job -ScriptBlock {
            param($srv, $database, $query)
            sqlcmd -S $srv -E -d $database -Q $query -b 2&amp;gt;&amp;amp;1 | Out-Null
        } -ArgumentList $Server, $db, $sql
    }
    $jobs | Wait-Job | Out-Null
    $sw.Stop()
    $jobs | Remove-Job -Force

    # Capture latch stats
    $raw = sqlcmd -S $Server -E -d $db `
        -Q "SELECT latch_class, waiting_requests_count, wait_time_ms,
            max_wait_time_ms FROM sys.dm_os_latch_stats
            WHERE latch_class = 'METADATA_SEQUENCE_GENERATOR';" `
        -W -s "," -h -1 2&amp;gt;&amp;amp;1
    $line = $raw | Where-Object { $_ -match 'METADATA' } | Select-Object -First 1

    $requests = 0; $waitMs = 0; $maxMs = 0
    if ($line -match 'METADATA_SEQUENCE_GENERATOR\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)') {
        $requests = [long]$Matches[1]; $waitMs = [long]$Matches[2]; $maxMs = [long]$Matches[3]
    }

    Write-Host ("  {0,-20} Elapsed: {1,6} ms | Latch waits: {2,8} | Wait: {3,6} ms" `
        -f $Label, $sw.ElapsedMilliseconds, $requests, $waitMs)

    return @{ Label = $Label; Elapsed = $sw.ElapsedMilliseconds;
              Requests = $requests; WaitMs = $waitMs; MaxMs = $maxMs }
}

Write-Host "Sessions: $Sessions | Rows/session: $RowsPerSession"

$rNum = Invoke-ConcurrentInserts -TableName "Inserts_Numeric" -Label "NUMERIC(28,0)"
$rMix = Invoke-ConcurrentInserts -TableName "Inserts_Mixed"   -Label "BIGINT-&amp;gt;NUMERIC"
$rBig = Invoke-ConcurrentInserts -TableName "Inserts_BigInt"  -Label "BIGINT"

if ($rNum.WaitMs -gt 0) {
    $mixPct = [math]::Round((1 - $rMix.WaitMs / $rNum.WaitMs) * 100, 1)
    $bigPct = [math]::Round((1 - $rBig.WaitMs / $rNum.WaitMs) * 100, 1)
    Write-Host "`nBIGINT-&amp;gt;NUMERIC latch reduction: $mixPct%"
    Write-Host "BIGINT latch reduction: $bigPct%"
}&lt;/LI-CODE&gt;&lt;HR /&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;CODE&gt;INSERT BULK&lt;/CODE&gt; without &lt;CODE&gt;KEEP_NULLS&lt;/CODE&gt; evaluates DEFAULT expressions per-row&lt;/STRONG&gt; - even when the source data supplies non-NULL values. For &lt;CODE&gt;NEXT VALUE FOR&lt;/CODE&gt; defaults, this means one latch acquisition per row, per session, regardless of whether the value is used. This is &lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql#keepnulls" target="_blank" rel="noopener"&gt;documented behaviour&lt;/A&gt;, but the performance implications for sequence-based defaults under concurrency are rarely discussed.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;CODE&gt;NUMERIC&lt;/CODE&gt; / &lt;CODE&gt;DECIMAL&lt;/CODE&gt; sequences use exclusive latches; &lt;CODE&gt;BIGINT&lt;/CODE&gt; / &lt;CODE&gt;INT&lt;/CODE&gt; use shared latches with atomic increments.&lt;/STRONG&gt; The sequence cache setting reduces disk I/O only - it does not change the latch mode. The latch mode is determined by the &lt;STRONG&gt;sequence type&lt;/STRONG&gt;, not the column type.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The combination creates a force multiplier.&lt;/STRONG&gt; Each factor is tolerable in isolation. Exclusive latching with a few sessions is fine. Unnecessary DEFAULT evaluation at low concurrency has negligible cost. But 350 sessions × exclusive latch × per-row evaluation = complete serialisation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The diagnostic signature is clear.&lt;/STRONG&gt; &lt;CODE&gt;LATCH_EX&lt;/CODE&gt; dominant in wait stats + &lt;CODE&gt;METADATA_SEQUENCE_GENERATOR&lt;/CODE&gt; in &lt;CODE&gt;sys.dm_os_latch_stats&lt;/CODE&gt; + low CPU utilisation = this pattern. Low CPU under high concurrency means serialisation, not low demand.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The fix is simple.&lt;/STRONG&gt; Setting &lt;CODE&gt;KeepNulls = true&lt;/CODE&gt; in the bulk copy options eliminates the issue entirely when the application supplies all values. No schema changes required, no table rebuilds, no downtime.&lt;/LI&gt;
&lt;/OL&gt;
&lt;HR /&gt;
&lt;H2&gt;Documentation References&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/bulk-insert-transact-sql#keepnulls" target="_blank" rel="noopener"&gt;BULK INSERT (Transact-SQL) - KEEPNULLS&lt;/A&gt; - Documents the KEEPNULLS behaviour: "Specifies that empty columns should retain a null value during the bulk import operation, instead of having any default values for the columns inserted."&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/tools/bcp-utility#k" target="_blank" rel="noopener"&gt;bcp Utility -k flag&lt;/A&gt; - BCP command-line equivalent of KEEPNULLS.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/connect/jdbc/using-bulk-copy-with-the-jdbc-driver" target="_blank" rel="noopener"&gt;SQLServerBulkCopyOptions.setKeepNulls&lt;/A&gt; - JDBC bulk copy configuration for the &lt;CODE&gt;keepNulls&lt;/CODE&gt; option.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/relational-databases/sequence-numbers/sequence-numbers" target="_blank" rel="noopener"&gt;Sequence Numbers (SQL Server)&lt;/A&gt; - Overview of SEQUENCE objects, caching behaviour, and usage patterns.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-sequence-get-range-transact-sql" target="_blank" rel="noopener"&gt;sp_sequence_get_range&lt;/A&gt; - Pre-allocating contiguous ID ranges with a single latch acquisition.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql" target="_blank" rel="noopener"&gt;CREATE SEQUENCE (Transact-SQL)&lt;/A&gt; - Sequence data type options and cache configuration.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-os-latch-stats-transact-sql" target="_blank" rel="noopener"&gt;sys.dm_os_latch_stats&lt;/A&gt; - DMV for diagnosing latch contention by class.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property" target="_blank" rel="noopener"&gt;IDENTITY (Property)&lt;/A&gt; - IDENTITY column behaviour and data type considerations.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2&gt;Feedback and Suggestions&lt;/H2&gt;
&lt;P&gt;If you have feedback or suggestions, please contact the Databases SQL Customer Success Engineering (Ninja) Team (&lt;A href="mailto:datasqlninja@microsoft.com" target="_blank" rel="noopener"&gt;datasqlninja@microsoft.com&lt;/A&gt;).&lt;/P&gt;
&lt;P&gt;Note: For additional information about migrating various source databases to Azure, see the &lt;A href="https://datamigration.microsoft.com/" target="_blank" rel="noopener"&gt;Azure Database Migration Guide&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Fri, 29 May 2026 15:58:10 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/modernization-best-practices-and/the-odd-couple-latches-and-keep-nulls/ba-p/4516048</guid>
      <dc:creator>David_Lyth</dc:creator>
      <dc:date>2026-05-29T15:58:10Z</dc:date>
    </item>
    <item>
      <title>PostgreSQL Meets AI at POSETTE: An Event for Postgres 2026 (T-3 weeks)</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/postgresql-meets-ai-at-posette-an-event-for-postgres-2026-t-3/ba-p/4523958</link>
      <description>&lt;P&gt;&lt;A href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;POSETTE: An Event for Postgres 2026&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; is where that evolution comes into focus, please visit conference’s site to register and add the event to your calendar!&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Artificial intelligence is changing how we build applications, but not in the way many people expected. The hardest problems aren’t about writing the perfect prompt or choosing the “best” model. Once teams move past demos and start putting systems in front of real users, the pain shows up somewhere else: in the data layer.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The recurring failure modes of production AI are remarkably consistent. Systems return answers that sound plausible but aren’t grounded. They pull the wrong records, miss key context, or stitch together fragments from unrelated sources. Sometimes they are correct, but wildly expensive. And when you let an AI system generate queries dynamically, the operational questions get sharper very quickly: what stops it from issuing a destructive statement, scanning a massive table, or repeatedly hammering a hot index until your p95 latency falls off a cliff?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;In other words, the hard part is not generation. The hard part is &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;retrieval&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, how data is accessed, shaped, governed, and observed. That’s exactly why the AI track at &lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;POSETTE: An Event for Postgres 2026&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; is so compelling this year: it treats PostgreSQL not as a passive database at the end of a request, but as an active foundation for the next wave of AI, native applications.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;What’s emerging across the agenda is a new mental model. PostgreSQL, long trusted as a durable, transactional system, has become the place where “truth” lives for many applications. And as AI agents become the interface to those applications, Postgres increasingly becomes the retrieval backbone that keeps those agents honest.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;From queries to agents: when the database becomes a tool&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;In traditional application design, we assume a deterministic relationship between intent and query. The application decides what it needs, SQL expresses it precisely, and the database returns a predictable result set. We tune the query, we add an index, we cache the hot path, and we move on.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Agentic systems break that contract.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;An agent doesn’t just execute a query. It interprets intent, decides what tools to use, and often iterates, sometimes several times, based on intermediate results. That “tool use” framing is central to &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/2026/talks/an-mcp-for-your-postgres-db/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Pamela Fox’s session An MCP for your Postgres DB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;, which explores how MCP (Model Context Protocol) turns a database into an explicit, discoverable interface, one where design choices directly influence whether an LLM behaves safely and predictably when it interacts with Postgres.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;In parallel, &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/2026/talks/from-queries-to-agents-the-next-era-of-data-retrieval-on-postgresql/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;A&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;be Omorogbe’s From Queries to Agents: The Next Era of Data Retrieval on PostgreSQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; frames the evolution in a way that resonates with anyone building production systems: as agents move from demos to reality, the challenge isn’t the model, it’s “reliable, safe, and context, aware data retrieval.” In practice, that means dealing with failures that don’t show up in toy examples: agents producing SQL that’s syntactically valid but semantically wrong; pulling the right table but the wrong slice; or forming queries that quietly explode costs because there’s no natural “stop” condition.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Once you accept that agents are going to query your system in ways you didn’t anticipate, PostgreSQL becomes part of your application’s safety boundary. It must handle unpredictable access patterns without falling over. It must protect you from unsafe operations, whether accidental or adversarial. And increasingly, it must support multi, modal retrieval, because the context an agent needs rarely lives in a single shape of data.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That’s the pivot &lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;POSETTE: An Event For Postgres 2026&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; is capturing: the database is no longer just queried, it is increasingly &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;negotiated with&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; by AI systems.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;RAG in practice: why PostgreSQL keeps showing up&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Retrieval, Augmented Generation (RAG) has become the default architecture for serious AI applications. It’s a pragmatic response to a simple reality: models are good at language, but they aren’t systems of record. If you care about accuracy, freshness, or traceability, you retrieve relevant information first, then generate a response grounded in that retrieved context.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The interesting question isn’t “does RAG work?”, it does. The interesting question is where teams choose to implement it.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A growing number of teams are using PostgreSQL as the core retrieval substrate for RAG pipelines because it lets them keep the system cohesive. You can store structured records, join across metadata, filter and rank, and now, thanks to the ecosystem, incorporate vector similarity search without standing up a separate database whose contents need to be continuously synchronized.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That’s the practical framing behind &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/2026/talks/production-rag-at-scale-with-azure-database-for-postgresql/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Julia Schröder Langhaeuser and Paula Santamaría’s session Production RAG at Scale with Azure Database for PostgreSQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;. Their talk centers on what it takes to go from prototype to production, including architecture choices, performance tuning, and the operational discipline required when you’re serving RAG workloads at meaningful scale. The message is less “Postgres can do vectors” and more “RAG becomes real when you can observe it, tune it, and trust it.”&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This distinction matters, because the failure modes of RAG systems are rarely about embeddings. They are about &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;context assembly&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. The best answer in the world is useless if the system retrieved the wrong snippets, missed an important constraint, or pulled stale policy text from last quarter.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL’s value here is subtle but powerful: it gives you a place to combine retrieval signals, structured filters, semantic similarity, graph, like relationships, business rules, inside a system whose behavior you can reason about.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;The real problem is retrieval, not generation&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If you spend time around production AI teams, you start to hear the same phrase: retrieval is the hard part.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Models can generate fluent text easily. But without high, quality input, and without guardrails around what the system is allowed to do, they generate confident nonsense, partial answers, and occasionally harmful advice. In the worst cases, they can become operational liabilities: issuing expensive queries repeatedly, pulling sensitive data into prompts, or creating “self, inflicted incidents” that look like outages but are really uncontrolled tool usage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That’s why POSETTE’s AI programming doesn’t just celebrate capability. It spends real time on safety and operational control.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Building safety tooling for risk, free AI tuning of Postgres: &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/2026/talks/building-safety-tooling-for-risk-free-ai-tuning-of-postgres-fast-cars-need-fast-brakes/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Fast cars need fast &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;brakes&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt; by Mohsin Ejaz captures this mindset perfectly&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;. The title says what many teams learn too late: if you’re going to let an automated system tune or optimize database behavior, the safety net matters more than the accelerator. Guardrails, validation, monitoring, and rollback discipline aren’t “nice to have”, they’re the difference between a neat demo and a system you can run while you sleep.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;When you connect that back to the agent conversation, you get a coherent picture. Whether the system is generating queries, selecting tools, or attempting optimizations, the foundation of reliability is the same: controlled access, predictable performance, and strong observability.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL contributes here not because it’s magical, but because it’s mature. It has deep access control primitives, transactional guarantees, and an ecosystem that has spent decades building operational muscle. The AI shift doesn’t eliminate those fundamentals, it makes them more important.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;The emerging retrieval stack: what sits between agents and data&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;One of the most useful ways to interpret this year’s sessions is as the early shape of a new architectural layer: a &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;retrieval stack&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; that lives between AI agents and your data systems.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This stack is not a single product. It’s a set of practices and components that make agent, to, data interactions safe and effective. It includes abstraction layers (like MCP, style tool interfaces), orchestration logic that can combine relational queries with vector similarity (and, increasingly, graph, aware traversal), context shaping that ranks and filters results into something a model can actually use, and governance controls that define what data may be accessed in which situations.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;What’s exciting about POSETTE: An Event For Postgres 2026 is that the agenda treats this as a real engineering problem, not a buzzword. Pamela Fox’s work on MCP surfaces the interface, design angle: when you expose Postgres as tools, the shape of those tools determines whether the agent behaves well. Abe Omorogbe’s framing pushes toward retrieval architectures that are robust by design rather than bespoke glue code. Julia Schröder Langhaeuser and Paula Santamaría bring the production perspective: what breaks at scale, and what you need to monitor. And Mohsin Ejaz anchors the safety story: the more automation you introduce, the more you need reliable brakes. &lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That same story now extends all the way to the developer experience. In &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-tooling-across-ai-editors-and-agents/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Matt McFarland’s &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;session&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt; PostgreSQL Tooling Across AI Editors and Agents&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;, the&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; focus shifts from retrieval architecture inside applications to the environments where developers and AI assistants actually work. By showing how PostgreSQL capabilities such as connection management, query execution, schema analysis, plan inspection, and performance insights can be surfaced consistently across VS Code, Cursor, and the GitHub Copilot CLI through an MCP server, the session adds an important dimension to the overall AI track: if agents are going to become part of everyday software development, PostgreSQL tooling also needs to become agent-aware, portable, and usable wherever those workflows happen. It’s a practical reminder that the AI future of Postgres is not only about what runs in production, but also about how humans and AI systems collaborate around the database during development itself.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Together, these sessions sketch a coherent future: PostgreSQL isn’t just where data sits. It’s becoming one of the engines that powers retrieval, first application design.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Why this matters if you build real systems&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If you’re building applications today, this shift is not theoretical. It changes how you think about database design, performance tuning, security, and cost.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;You can’t assume query predictability anymore, because agents don’t behave like carefully written application code. You can’t treat access control as a static checklist, because prompts are leaky abstractions and tool use creates new attack surfaces. And you can’t ignore cost modeling, because AI, generated queries can be expensive in ways that traditional workloads rarely are, especially when they iterate.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;POSETTE: An Event For Postgres 2026&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; tackles these realities head, on. Not with hype, but with practical patterns, real failure modes, and the kind of engineering trade, offs you only learn when systems meet production constraints.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;What &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;you’ll&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt; take away from the AI track at &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;POSETTE: An Event for Postgres this year&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If there’s a single theme to keep in mind, it’s this: AI isn’t replacing databases. It’s forcing us to use them differently.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The AI sessions at &lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;POSETTE: An Event For Postgres 2026&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; will help you build a clearer mental model of how agents interact with PostgreSQL, how RAG systems become production, ready, and what it means to design retrieval layers with safety and observability from day one. And, importantly, you’ll leave with a vocabulary for discussing these systems without hand, waving: where the risk is, where the cost is, and where the true engineering work lives.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL’s flexibility and extensibility make it a natural foundation for this transition, but the real advantage will go to teams that treat retrieval as an engineering discipline, not an afterthought.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;At POSETTE, that transformation is on full display.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;A quick call to action&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;POSETTE: An Event for Postgres 2026&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; is a can’t, miss event for the PostgreSQL community. Register to get updates and save the livestream sessions you want to attend on your calendar.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 29 May 2026 17:24:40 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/postgresql-meets-ai-at-posette-an-event-for-postgres-2026-t-3/ba-p/4523958</guid>
      <dc:creator>scoriani</dc:creator>
      <dc:date>2026-05-29T17:24:40Z</dc:date>
    </item>
    <item>
      <title>Why do I see many VDI_CLIENT_WORKER sessions in Azure SQL Database — and do they impact performance?</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/why-do-i-see-many-vdi-client-worker-sessions-in-azure-sql/ba-p/4523817</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Sometimes you’ll notice many sessions showing the command &lt;STRONG&gt;VDI_CLIENT_WORKER&lt;/STRONG&gt; in Azure SQL Database—often around &lt;STRONG&gt;scaling, replica/copy workflows, or internal seeding operations&lt;/STRONG&gt;. These sessions can look alarming, especially during a performance investigation, but they are typically &lt;STRONG&gt;internal background workers&lt;/STRONG&gt;. This post explains how to recognize them, what’s safe to do (and what isn’t), and how to focus on the real bottlenecks like &lt;STRONG&gt;blocking/deadlocks&lt;/STRONG&gt; or &lt;STRONG&gt;log rate throttling&lt;/STRONG&gt; when you’re troubleshooting slowness.&lt;/P&gt;
&lt;H1&gt;Why you might see VDI_CLIENT_WORKER sessions in Azure SQL Database&lt;/H1&gt;
&lt;img /&gt;
&lt;H2&gt;The symptom&lt;/H2&gt;
&lt;P&gt;You run a session query (for example, using sys.dm_exec_requests or a monitoring tool) and observe:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Many sessions&lt;/STRONG&gt; with command text &lt;STRONG&gt;VDI_CLIENT_WORKER&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;They may appear to be “stuck,” persist longer than expected, and &lt;STRONG&gt;can’t be killed&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Teams may worry these sessions are “the cause” of slowness&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Why it shows up in Azure SQL&lt;/H2&gt;
&lt;P&gt;In Azure SQL, VDI_CLIENT_* wait types and VDI_CLIENT_WORKER sessions are commonly associated with platform operations that involve &lt;STRONG&gt;copying/seeding&lt;/STRONG&gt;—for example:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Scaling operations (service objective changes)&lt;/LI&gt;
&lt;LI&gt;Geo-replication / copy workflows&lt;/LI&gt;
&lt;LI&gt;Replica seeding-like behaviors&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Important: The presence of these sessions&amp;nbsp;&lt;STRONG&gt;does not automatically mean they are the bottleneck&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;How to validate whether VDI_CLIENT_WORKER is benign?&lt;/H1&gt;
&lt;H2&gt;1) Correlate to recent platform operations.&lt;/H2&gt;
&lt;P&gt;Ask: did you recently perform (or did the platform perform) one of these?&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Scale up/down.&lt;/LI&gt;
&lt;LI&gt;Creation of replicas / geo-secondary operations.&lt;/LI&gt;
&lt;LI&gt;Any database copy-like workflow.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If yes, it’s a strong indicator you’re seeing background workers tied to that lifecycle event.&lt;/P&gt;
&lt;H2&gt;2) Check whether they consume resources.&lt;/H2&gt;
&lt;P&gt;A practical approach:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Look for CPU/IO/log pressure at the database level.&lt;/LI&gt;
&lt;LI&gt;Compare the timing of slowness reports with spikes in waits/locks/log write percentage.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If these sessions show &lt;STRONG&gt;minimal resource consumption&lt;/STRONG&gt; and are just “present,” treat them as background noise while you investigate real contention.&lt;/P&gt;
&lt;H2&gt;3) Don’t try to kill them!&lt;/H2&gt;
&lt;P&gt;These sessions are typically &lt;STRONG&gt;system/internal&lt;/STRONG&gt;. Attempts to kill them may fail or be ineffective—and generally aren’t recommended.&lt;/P&gt;
&lt;H2&gt;4) If you need them to disappear.&lt;/H2&gt;
&lt;P&gt;In many cases, these internal workers naturally age out. If they remain visible and you need a cleanup path, operational actions like &lt;STRONG&gt;failover/restart&lt;/STRONG&gt; may clear stale workers (use change control / maintenance windows as appropriate for your environment).&lt;BR /&gt;&lt;EM&gt;(This is a practical operational observation; always weigh downtime/impact.)&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;When performance is actually slow: focus on what usually hurts.&lt;/H1&gt;
&lt;P&gt;In many real-world incidents, the main causes of slowness are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Blocking chains / deadlocks.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Transaction log rate throttling (LOG_RATE_GOVERNOR)&lt;/STRONG&gt; during heavy DML.&lt;/LI&gt;
&lt;LI&gt;Hot queries running concurrently and contending on the same objects.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Key takeaways&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;Seeing many VDI_CLIENT_WORKER sessions is often &lt;STRONG&gt;expected&lt;/STRONG&gt; around platform copy/seeding workflows and doesn’t automatically indicate a bottleneck.&lt;/LI&gt;
&lt;LI&gt;Don’t attempt to kill system/internal workers; instead, validate resource impact and focus on actual bottlenecks.&lt;/LI&gt;
&lt;LI&gt;For real slowness, prioritize diagnosing &lt;STRONG&gt;blocking/deadlocks&lt;/STRONG&gt; and &lt;STRONG&gt;LOG_RATE_GOVERNOR&lt;/STRONG&gt;-driven DML throttling.&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Fri, 29 May 2026 06:52:21 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/why-do-i-see-many-vdi-client-worker-sessions-in-azure-sql/ba-p/4523817</guid>
      <dc:creator>Ashriti_Jamwal</dc:creator>
      <dc:date>2026-05-29T06:52:21Z</dc:date>
    </item>
    <item>
      <title>General Availability of the MySQL Flexible Server Quota Management Self-Service Experience</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-for-mysql-blog/general-availability-of-the-mysql-flexible-server-quota/ba-p/4523373</link>
      <description>&lt;H4 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;What’s New?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The updated experience introduces a dedicated&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Azure Database for MySQL Flexible Server Quotas&amp;nbsp;blade&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;in the Azure portal, offering a streamlined and intuitive interface to:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;View current usage and limits across the various SKU families and regions&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Request quota increases tailored to your MySQL Flexible Server deployment needs&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This new experience empowers developers, DBAs, and IT admins to proactively manage resources, avoid deployment failures, and&amp;nbsp;optimize&amp;nbsp;database performance — all without needing to file a support ticket for most scenarios.&lt;/SPAN&gt; &lt;SPAN data-ccp-props="{&amp;quot;335572071&amp;quot;:4,&amp;quot;335572072&amp;quot;:0,&amp;quot;335572073&amp;quot;:4278190080,&amp;quot;469789798&amp;quot;:&amp;quot;single&amp;quot;}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Benefits&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;at a Glance&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; height: 374px; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Benefit&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Description&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 67px;"&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Self-Service&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Request quota increases directly from the Azure portal without filing a support ticket for most scenarios.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 67px;"&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Real-Time Visibility&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;View current&amp;nbsp;vCore&amp;nbsp;usage and limits across all SKU families and regions at a glance.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 67px;"&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Automatic Approval&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Many&amp;nbsp;quota&amp;nbsp;increase requests are automatically approved within minutes — no waiting for manual review.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 67px;"&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Inline Adjustments&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Request increases directly from the quota table — no need to navigate to a separate page or form.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 67px;"&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Proactive Management&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 67px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Identify&amp;nbsp;SKU families nearing their limits before they cause deployment failures.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Fraud and UPA as Safeguard&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-teams="true"&gt;Requests that exceed limits or indicate risk are automatically escalated for review, not blindly approved.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.0463%" /&gt;&lt;col style="width: 50.0463%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P aria-level="2"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H4 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;How It Works&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0,&amp;quot;335572071&amp;quot;:4,&amp;quot;335572072&amp;quot;:0,&amp;quot;335572073&amp;quot;:4278190080,&amp;quot;469789798&amp;quot;:&amp;quot;single&amp;quot;}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Each MySQL Flexible Server compute tier is represented as a separate&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;SKU family&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. If you intend to scale up or down within a specific tier, ensure you have sufficient quota for each applicable SKU family in that tier.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;You can filter by&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;region&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;subscription&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;provider&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, or&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;usage&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. Note that your portal will show&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"Azure Database for MySQL&amp;nbsp;Flexible Server"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;for the Provider name.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;You can also group the results by&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;usage&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;quota&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;(SKU family), or&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;location&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;(region).&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Current usage is represented as&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;vCores&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. This allows you to quickly&amp;nbsp;identify&amp;nbsp;which SKU families are nearing their quota limits.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Adjustments can be made inline:&amp;nbsp;there is no&amp;nbsp;need to visit another page. This is covered in detail in the next section.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H4 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Step-by-Step: Viewing Usage and Requesting a Quota Increase&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 1: Navigate to the Quotas Blade&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Sign in to the Azure portal at&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://portal.azure.com/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://portal.azure.com&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;In the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;search bar&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;at the top, type&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"Quotas"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Select&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"Quotas"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;from the search results under&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Services&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Alternative navigation:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;You can also navigate via&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Subscriptions&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&amp;gt; select your subscription &amp;gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Usage + quotas&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;in the left-hand menu.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 2: Select the Azure Database for MySQL Provider&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;On the Quotas page,&amp;nbsp;locate&amp;nbsp;and select&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"Azure Database for MySQL"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;from the list of resource providers.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Use the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Subscription&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;filter at the top to select the subscription you want to review&amp;nbsp;and apply&amp;nbsp;additional&amp;nbsp;filters for&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;regions&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;as needed.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 3: Review Your Quota Usage and Limits&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;The quota details page displays a table with the following information:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Quota Name&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;— The SKU family name (e.g., "Burstable BS Series&amp;nbsp;vCores", "General Purpose DS Series&amp;nbsp;vCores", "Business Critical DS Series&amp;nbsp;vCores").&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Region&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;— The Azure region where the quota applies.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Current Usage&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;— The number of&amp;nbsp;vCores&amp;nbsp;currently in use.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Limit&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;— The&amp;nbsp;maximum&amp;nbsp;quota limit for that SKU family.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Usage Bar&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;— A visual indicator showing how much of the quota is consumed.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;Review the usage bars to identify quotas that are nearing their limits. Use the &lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;search box&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&amp;nbsp;to find specific SKU families quickly.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 4: Request a Quota Increase&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Clicking the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;pen icon&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; next to a quota opens a fly-out window to capture the quota request.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 5: Enter the New Limit&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;The quota type (MySQL Flexible Server SKU family) is already populated, along with current usage. Note that&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;your request is not incremental&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;: you must specify the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;new limit&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;that you wish to see reflected in the portal.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;For example, to request an additional 10 vCores for Burstable Series (BS family), and your current limit is 35, you would enter 45 as the new limit.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Enter the desired new limit in the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"New limit"&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;field.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;The portal will&amp;nbsp;indicate&amp;nbsp;whether the request can be&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;automatically approved&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;or if it requires manual review.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 6:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Submit&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;&amp;nbsp;and Monitor the Request&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Click&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Submit&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;to send the request for automatic processing.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Immediately upon&amp;nbsp;submitting&amp;nbsp;a quota request, you will see a processing dialog:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;If the quota request can be&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;automatically fulfilled&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, then no support request is needed.&amp;nbsp;You should receive confirmation within a few minutes of submission:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;If the request&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;cannot be automatically fulfilled&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, then you will be given the&amp;nbsp;option&amp;nbsp;to file a support request with the same information:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Step 7: Verify the Quota Increase&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Navigate back to the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Quotas&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;blade and select the Azure Database for MySQL provider.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Confirm that the&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Limit&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;column now reflects the new, increased value.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;If you forget the region or SKU family that was requested, you can reference them in your&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;notifications pane.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;H5 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Filing a Support Ticket&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;When creating a support ticket, you will need to repopulate the Region and MySQL Flexible Server SKU family details; the new limit has already been populated for you.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;If you choose to create a support ticket, you will interact with the capacity management team for that region. This is a 24x7 service, so requests may be created at any time. Once you have filed the support request, you can track its status via the&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://ms.portal.azure.com/#view/Microsoft_Azure_Support/HelpAndSupportBlade/~/overview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Help + support dashboard&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;If your deployment requires quota for many subscriptions, then we recommend filing a support ticket with issue type&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;"Service and subscription limits (quotas)"&amp;nbsp;and quota type “Quota increase”:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H5 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Known Limitations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Closing the quota request fly-out window will stop meaningful notifications for that request. You can still view the outcome of your quota requests by checking actual quota, but if you want to rely on notifications for alerts, we recommend leaving the quota request window open for the few minutes that it is processing.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Feedback&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:200,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;If you notice any aspect of the experience that does not work as expected or you have feedback on how to make it better, please share your thoughts! Your feedback is critical as we work toward an improved quota management self-service experience.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 28 May 2026 05:58:27 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-for-mysql-blog/general-availability-of-the-mysql-flexible-server-quota/ba-p/4523373</guid>
      <dc:creator>karlaescobar</dc:creator>
      <dc:date>2026-05-28T05:58:27Z</dc:date>
    </item>
    <item>
      <title>Introducing PostgreSQL Hub for Azure Developers</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/introducing-postgresql-hub-for-azure-developers/ba-p/4522897</link>
      <description>&lt;P&gt;When you're building applications with PostgreSQL, finding the right resources can be harder than it should be. Documentation lives in one place, samples in another, tutorials scattered across blogs, and community discussions fragmented across forums. You end up with multiple browser tabs open just to piece together a working architecture for your project. Whether you're just getting started or you've been building for years, if all you want is a faster path from "I have an idea" to "this is running in production", then &lt;A class="lia-external-url" href="https://aka.ms/postgres-hub" target="_blank" rel="noopener"&gt;PostgreSQL Hub for Azure Developers&lt;/A&gt; is for you.&lt;/P&gt;
&lt;P&gt;It brings everything together in one place. But it's more than just a content aggregator. Here's what makes it different:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Curated resources to help you build.&lt;/STRONG&gt; From sample apps and solution accelerators to tutorials, videos, workshops, and relevant documentation, you'll find what you need to build core applications, AI-powered solutions, and multi-agent architectures on PostgreSQL. Resources are maintained and updated as new capabilities ship.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Structured learning pathways.&lt;/STRONG&gt; Instead of navigating documentation on your own, you get guided paths that take you from fundamentals through intermediate patterns to advanced AI scenarios like vector search, AI functions, and building agents. The pathways are designed to help you develop a solid understanding at every stage.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Community space.&lt;/STRONG&gt; Beyond content, the hub also includes a &lt;A class="lia-external-url" href="https://aka.ms/postgres-hub-developer-forum" target="_blank" rel="noopener"&gt;Developer Forum powered by GitHub Discussions&lt;/A&gt; where you can share product feedback, learn from fellow developers, and collaborate directly with Microsoft engineers on your use cases. Whether you want to discuss an architecture decision, share what you've built, or contribute a sample, the forum is the place for it. Real-time chat for quick questions and webinars is coming soon.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Who is this for?&lt;/H3&gt;
&lt;P&gt;No matter what stage you're at in building with PostgreSQL on Azure, there's something here for you. The hub is especially relevant if you are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;An &lt;STRONG&gt;application developer&lt;/STRONG&gt; looking for curated resources, end-to-end guidance, and patterns to build or scale your projects on PostgreSQL&lt;/LI&gt;
&lt;LI&gt;An &lt;STRONG&gt;AI builder&lt;/STRONG&gt; exploring use cases like vector search, embeddings, AI functions, or agent architectures&lt;/LI&gt;
&lt;LI&gt;A &lt;STRONG&gt;new learner&lt;/STRONG&gt; looking for a clear starting point with structured content to guide you&lt;/LI&gt;
&lt;LI&gt;An &lt;STRONG&gt;enterprise user with existing workloads on Azure&lt;/STRONG&gt; looking to understand the full breadth of intelligent application development capabilities available with PostgreSQL&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The sample apps, patterns, and learning content are valuable irrespective of whether you're already building on PostgreSQL or just exploring what's possible.&lt;/P&gt;
&lt;H3&gt;Get Started&lt;/H3&gt;
&lt;P&gt;The surface area of what you can build with PostgreSQL has expanded significantly, and finding the right resource at the right time shouldn't slow you down. That's exactly what this hub is here to solve.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's a quick walkthrough of the Postgres Hub:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Head over to &lt;A class="lia-external-url" href="https://aka.ms/postgres-hub" target="_blank" rel="noopener"&gt;aka.ms/postgres-hub&lt;/A&gt; to explore further! Browse the sample apps, pick a learning pathway that matches where you are, or join the community discussions to connect with other developers and Microsoft engineers.&lt;/P&gt;
&lt;P&gt;We're actively growing this hub based on what the community needs. Your feedback, your questions, and your contributions will shape what comes next.&lt;/P&gt;</description>
      <pubDate>Wed, 27 May 2026 16:33:28 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/introducing-postgresql-hub-for-azure-developers/ba-p/4522897</guid>
      <dc:creator>ShreyaAithal</dc:creator>
      <dc:date>2026-05-27T16:33:28Z</dc:date>
    </item>
    <item>
      <title>Demystifying LWLock: MultiXact SLRU Wait Events in Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/demystifying-lwlock-multixact-slru-wait-events-in-azure-database/ba-p/4518504</link>
      <description>&lt;H2&gt;&lt;STRONG&gt;What Is the MultiXact Subsystem?&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;Before diving into the wait events, it helps to understand what PostgreSQL is protecting. When a single transaction modifies a row, PostgreSQL stores that transaction's ID (&lt;STRONG&gt;XID&lt;/STRONG&gt;) directly in the row header's &lt;STRONG&gt;xmax&lt;/STRONG&gt; field. Simple and fast. But what happens when two or more transactions need to hold locks on the same row simultaneously? For example:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Two sessions run SELECT ... FOR KEY SHARE on the same row, OR&lt;/LI&gt;
&lt;LI&gt;A SELECT ... FOR UPDATE session encounters a row already locked by a foreign key check (FOR KEY SHARE), OR&lt;/LI&gt;
&lt;LI&gt;Multiple sub-transactions created by SAVEPOINT all reference the same row&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In these cases, PostgreSQL cannot store two XIDs in a single xmax field. Instead, it creates a MultiXact ID (&lt;STRONG&gt;MXID&lt;/STRONG&gt;) — a composite identifier that points to a list of all involved transaction IDs. These mappings are stored in two on-disk structures:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;pg_multixact/offsets/ — maps each MXID to its position in the member's file&lt;/LI&gt;
&lt;LI&gt;pg_multixact/members/ — stores the actual list of member XIDs&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;To avoid reading these files from disk on every row visibility check, PostgreSQL caches them in memory using a &lt;STRONG&gt;SLRU &lt;/STRONG&gt;(Simple Least Recently Used) cache — a small, fixed-size ring buffer with just 8 buffer slots by default (64 KB) for offsets and 16 slots (128 KB) for members.&lt;/P&gt;
&lt;P&gt;Each of those buffer slots is protected by an &lt;STRONG&gt;LWLock &lt;/STRONG&gt;(Lightweight Lock). And that LWLock is exactly where the bottleneck hides.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;The Core Insight: &lt;BR /&gt;&lt;/STRONG&gt;Cache Hits and Lock Contention are &lt;STRONG&gt;not mutually exclusive&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;This is the most important concept in this entire post:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;pg_stat_slru&lt;/STRONG&gt; measures I/O misses. &lt;STRONG&gt;pg_stat_activity&lt;/STRONG&gt; wait events measure lock contention.&lt;/P&gt;
&lt;P&gt;Here is what actually happens at the microsecond level:&lt;/P&gt;
&lt;P&gt;Session A: Needs MXID 5,000,023 → Page is in SLRU cache (blks_hit++) → LWLock is needed on buffer slot 3 → Session B already holds that LWLock → Session A WAITS → wait_event = 'MultiXactOffsetSLRU' recorded&lt;/P&gt;
&lt;P&gt;The cache is warm, the page is in memory, but what happens when 50 concurrent sessions suddenly all need that same buffer slot's &lt;STRONG&gt;LWLock?&amp;nbsp; &lt;/STRONG&gt;Only one request can hold the LWLock at a time. Every session that queues behind the lock holder generates a wait event record, all while no disk I/O is occurring.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;What Triggers MultiXact SLRU Wait Events?&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;Below are the scenario's which could trigger MultiXact SLRU Wait Events.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;Thundering Herd — Mass Concurrent Row Locking&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;When dozens or hundreds of sessions simultaneously attempt to lock the same small set of rows, PostgreSQL must create and resolve MXIDs at high frequency. Each resolution requires an SLRU lookup. When all lookups target the same few SLRU pages, the buffer lock becomes a serialization point. A classic reconnect avalanche triggered when the connection pool detected server slowness and all clients retried simultaneously.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;Foreign Key FOR KEY SHARE vs. FOR UPDATE Conflicts&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;This is one of the most common hidden triggers. Every time a child row is inserted or updated, PostgreSQL implicitly acquires FOR KEY SHARE on the referenced parent row to prevent the parent from being deleted. If another session simultaneously holds FOR UPDATE on that same parent row, PostgreSQL &lt;STRONG&gt;must combine both lock modes into a new MXID&lt;/STRONG&gt;:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Session A (updater): 
SELECT * FROM orders WHERE id = 1 FOR UPDATE; 

-- Session B (child inserter — FK check): 
INSERT INTO order_items (order_id, amount) VALUES (1, 99.00); 

-- Implicitly: 
SELECT * FROM orders WHERE id = 1 FOR KEY SHARE; 

-- PostgreSQL creates MXID combining both transactions → SLRU write&lt;/LI-CODE&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;SAVEPOINT and Sub-transaction Churn&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Every SAVEPOINT creates a sub-transaction XID. ORM frameworks and JDBC drivers with autosave=always silently wrap every statement in a SAVEPOINT, generating sub-XIDs that accumulate rapidly. When these sub-XIDs reference the same rows across concurrent sessions, MXID creation accelerates. Each exception handler internally creates a SAVEPOINT, even when no explicit savepoint is declared.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;Idle Sessions Holding MXID References Open&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Long-running idle-in-transaction sessions hold their MXID references open, preventing PostgreSQL's autovacuum from cleaning up old multixact entries. As the MXID space grows without cleanup, the SLRU cache (fixed at 8 pages) cannot hold all active pages simultaneously. New MXID lookups begin evicting cached pages, and under concurrency the eviction/reload cycle itself creates LWLock contention.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;VACUUM FREEZE During High Concurrency&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;When autovacuum runs VACUUM FREEZE to prevent MXID wraparound, it reads and resolves every MXID on every row in the table. During this process it holds SLRU buffer locks for each lookup. Concurrent application sessions needing the same SLRU pages must wait; generating MultiXactOffsetSLRU wait events even when the underlying cause is a routine maintenance operation.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;How to Diagnose This in Real Time&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1: Confirm Active Wait Events&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Start by querying pg_stat_activity to confirm which sessions are actively waiting on MultiXact SLRU events. Use \watch 1 to refresh every second since SLRU LWLocks are held for microseconds and brief spikes can be missed. Pay close attention to the wait_event column, MultiXactOffsetSLRU and MultiXactMemberSLRU indicate pure lock contention on cached pages, while MultiXactOffsetBuffer indicates the page was evicted from cache and is being reloaded from disk.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT pid, wait_event_type, wait_event, state
, now() - query_start AS duration, left(query, 100) AS query 
FROM pg_stat_activity 
WHERE wait_event IN ( 'MultiXactOffsetSLRU', 'MultiXactMemberSLRU', 'MultiXactOffsetBuffer' ) 
ORDER BY duration DESC;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2: Distinguish Lock Contention From Disk I/O&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Once wait events are confirmed, determine whether the root cause is cache under sizing (disk I/O problem) or LWLock queue depth (lock contention problem). These look identical in pg_stat_activity but require completely different fixes. Query pg_stat_slru and focus on the blks_read and blks_zeroed columns. A blks_read = 0 alongside active wait events is the definitive signature of pure lock contention: the cache is warm but the LWLock protecting each buffer slot is the bottleneck.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT name, blks_hit, blks_read, blks_zeroed, flushes
, ROUND(100.0 * blks_hit / NULLIF(blks_hit + blks_read, 0), 2) AS hit_pct 
FROM pg_stat_slru 
WHERE name LIKE 'MultiXact%';&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Interpretation&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Meaning&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;blks_read = 0 AND wait events are present&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Pure lock contention&lt;/STRONG&gt; — the cache is warm, the lock is the bottleneck&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;blks_read &amp;gt; 0 AND wait events are present&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Cache miss + lock contention&lt;/STRONG&gt; — the SLRU cache is undersized&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;blks_zeroed are increasing rapidly&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;High MXID creation rate — inspect application pattern issues&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;flushes are high (2,000+)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Frequent checkpoint SLRU flushes holding an exclusive lock&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3: Check MXID Age and Identify Hot Tables&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A high MXID age means autovacuum is not keeping pace with MXID creation. This causes the MXID space to span far more SLRU pages than the 8-slot cache can hold, directly worsening lock contention. Check MXID age at both the database and table level. Any database approaching 1.5 billion should be treated as a critical incident. At the table level, focus on tables with the highest mxid_age combined with high row counts and stale last_autovacuum timestamps — these are your primary VACUUM FREEZE targets.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Database-level MXID age (watch for values &amp;gt; 1 billion) 
SELECT datname, mxid_age(datminmxid) AS mxid_age 
FROM pg_database 
ORDER BY mxid_age DESC; 

-- Table-level — find the worst offenders 
SELECT relname, mxid_age(relminmxid) AS mxid_age
, pg_size_pretty(pg_total_relation_size(oid)) AS table_size, n_live_tup 
FROM pg_stat_user_tables t 
JOIN pg_class c USING (relname) 
WHERE c.relkind = 'r' 
ORDER BY mxid_age DESC 
LIMIT 10;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4: Find Queries Driving MXID Creation&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Once the hot tables are identified, use pg_stat_statements to pinpoint the specific queries generating MXIDs at a high rate. Focus on queries using FOR UPDATE, FOR KEY SHARE, or FOR SHARE, as these are the direct triggers for concurrent row locking. Also watch for INSERT-heavy workloads on child tables with FK references, as these implicitly acquire FOR KEY SHARE on parent rows and are a common hidden driver of MXID creation.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT left(query, 200) AS query, calls, mean_exec_time::numeric(10,2) AS avg_ms 
FROM pg_stat_statements 
WHERE query ILIKE '%for update%' 
OR query ILIKE '%for key share%' 
OR query ILIKE '%for share%' 
ORDER BY calls DESC 
LIMIT 10;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 5: Catch Long-Running Idle Transactions&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Idle-in-transaction sessions are one of the most damaging contributors to SLRU contention. They hold row-level locks while doing nothing, preventing autovacuum from cleaning up MXIDs and forcing other sessions to queue on the same SLRU pages indefinitely. Query pg_stat_activity filtered to idle-in-transaction states and focus on sessions idle for more than 2 minutes; these are almost always stuck client tool connections (DBeaver, pgAdmin) or misbehaving application threads that opened a transaction and never committed.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT pid, usename, application_name, state, now() - xact_start AS txn_age
, now() - state_change AS idle_duration, left(query, 100) AS last_query 
FROM pg_stat_activity 
WHERE state IN ('idle in transaction', 'idle in transaction (aborted)') 
AND now() - state_change &amp;gt; interval '2 minutes' 
ORDER BY idle_duration DESC;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;Fixes and Mitigation Strategies&lt;/STRONG&gt;&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Terminate long-running idle-in-transaction sessions&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The fastest way to break the contention cycle during an active incident is to terminate sessions holding locks while idle. This immediately releases row-level locks, unblocks autovacuum, and allows MXID cleanup to resume. Always preview before terminating to avoid disrupting legitimate long-running batch jobs.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Preview candidates first 
SELECT pid, usename, application_name, now() - state_change AS idle_duration 
FROM pg_stat_activity 
WHERE state = 'idle in transaction' 
AND now() - state_change &amp;gt; interval '5 minutes' 
ORDER BY idle_duration DESC;

--then run the terminate 
SELECT pg_terminate_backend(pid) 
FROM pg_stat_activity 
WHERE state = 'idle in transaction' 
AND now() - state_change &amp;gt; interval '5 minutes';&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL start="2"&gt;
&lt;LI&gt;&lt;STRONG&gt; Set timeouts to prevent recurrence&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;After immediate relief, set timeouts to automatically kill idle-in-transaction sessions before they accumulate again. Both parameters take effect immediately via pg_reload_conf() with no server restart required. Choose values appropriate to your workload, use more aggressive for high-concurrency OLTP, more lenient for batch or reporting workloads.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;ALTER SYSTEM SET idle_in_transaction_session_timeout = 'XXmin'; 
ALTER SYSTEM SET statement_timeout = 'XXmin'; 
SELECT pg_reload_conf();&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL start="3"&gt;
&lt;LI&gt;&lt;STRONG&gt; VACUUM FREEZE the most affected table&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;Running VACUUM FREEZE on the tables identified in Step 3 immediately clears old MXIDs from row headers, replacing them with frozen values that never require SLRU lookups. This directly reduces SLRU page access and LWLock contention. For very large tables, use INDEX_CLEANUP FALSE on the first pass for speed, then run a full vacuum during off-peak hours.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;VACUUM FREEZE VERBOSE your_hot_table;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL start="4"&gt;
&lt;LI&gt;&lt;STRONG&gt; Connection pooling&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Connection pooling is the most impactful long-term fix for preventing thundering herd connection storms. PgBouncer in transaction mode absorbs connection spikes at the pooler layer, ensuring PostgreSQL never sees more simultaneous sessions than the pool size, and directly reducing the number of concurrent MXID lookups and SLRU LWLock contention. On Azure PostgreSQL Flexible Server, PgBouncer is available as a &lt;STRONG&gt;built-in feature. &lt;/STRONG&gt;Simply enable it via Server Parameters (pgbouncer.enabled = ON) and connect on &lt;STRONG&gt;port 6432&lt;/STRONG&gt;. No separate installation is required.&lt;/P&gt;
&lt;P&gt;# Key PgBouncer settings for OLTP workloads&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;PRE&gt;pool_mode&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = transaction&amp;nbsp;&amp;nbsp; # Release connection after each transaction&lt;/PRE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;PRE&gt;default_pool_size = 100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Real PG connections per database/user pair&lt;/PRE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;PRE&gt;max_client_conn&amp;nbsp;&amp;nbsp; = 5000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Total clients PgBouncer will accept&lt;/PRE&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;MultiXact SLRU wait events are deceptive. A server can show 100% cache hit ratio, nominal disk I/O, and moderate CPU, all while &lt;EM&gt;simultaneously &lt;/EM&gt;stalling hundreds of sessions on a lock held for microseconds. The cache appears healthy, and the problem is invisible... until sessions start piling up.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The single most important diagnostic insight is this: &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;pg_stat_slru measures I/O efficiency. &lt;BR /&gt;pg_stat_activity measures lock contention.&lt;/P&gt;
&lt;P&gt;A 100% hit ratio does not mean there are no problems, it means the bottleneck is the lock protecting the cached page, not the cache itself.&lt;/P&gt;
&lt;P&gt;Once you know this, the path forward is clear. Use pg_stat_slru and pg_stat_activity together, never in isolation. Track mxid_age proactively, and do not wait for autovacuum to raise the alarm. Eliminate idle-in-transaction sessions before they become lock holders. Use the weakest lock mode that satisfies your application's consistency requirements.&amp;nbsp; Use FOR NO KEY UPDATE instead of FOR UPDATE wherever possible. And deploy PgBouncer (available as a built-in feature on Azure Database for PostgreSQL Flexible Server) to absorb connection storms before they reach the SLRU layer.&lt;/P&gt;
&lt;P&gt;MultiXact contention is not inevitable. It is the compounded result of concurrent locking patterns, under-tuned autovacuum, and unbounded connection growth, all of which are fully controllable. The earlier you instrument for it, the less likely it becomes an incident.&lt;/P&gt;</description>
      <pubDate>Wed, 27 May 2026 14:20:20 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/demystifying-lwlock-multixact-slru-wait-events-in-azure-database/ba-p/4518504</guid>
      <dc:creator>Gayathri_Paderla</dc:creator>
      <dc:date>2026-05-27T14:20:20Z</dc:date>
    </item>
    <item>
      <title>SELECT * FROM build2026_sessions WHERE postgres = true;</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/select-from-build2026-sessions-where-postgres-true/ba-p/4522093</link>
      <description>&lt;P&gt;&lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3EBreakout" target="_blank" rel="noopener"&gt;Microsoft Build 2026&lt;/A&gt; is around the corner, and this year it’s shaping up to be a big one for PostgreSQL experts and enthusiasts. If you’re a developer working with Postgres, or just love exploring new database technology, there's plenty to get excited about. Microsoft’s new cloud-first evolution of PostgreSQL,&amp;nbsp;&lt;A href="https://azure.microsoft.com/products/horizondb" target="_blank" rel="noopener"&gt;Azure HorizonDB&lt;/A&gt;, alongside sessions featuring &lt;A href="https://azure.microsoft.coms/products/postgresql" target="_blank" rel="noopener"&gt;Azure Database for PostgreSQL&lt;/A&gt;, will highlight how Postgres is powering the next wave of AI-driven applications.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;A new horizon in Postgres&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Build 2026 arrives at a time when the role of databases in modern apps is evolving rapidly. From enabling AI model integration to scaling seamlessly across the cloud, PostgreSQL developers today are dealing with more complex demands than ever. That’s why Azure HorizonDB – Microsoft’s new cloud-native PostgreSQL service – is generating so much buzz ahead of Build.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;What is Azure HorizonDB?&lt;/EM&gt; In short, it’s a reimagined version of PostgreSQL designed for cloud-scale performance and AI-era workloads. Azure HorizonDB, introduces a distributed architecture that decouples compute and storage, delivering sub-millisecond latencies and three times the throughput of self-managed Postgres at massive scale. It aims to preserve Postgres’s beloved features and SQL ecosystem while adding next-generation capabilities: built-in vector indexing for high-speed AI/ML retrieval, the ability to run AI models and vector operations directly in the database, and multi-zone replication for resilience. For Postgres developers, this means less time stitching together external data stores or machine learning services – and more time building powerful apps on a unified platform that’s both familiar and built for the future.&lt;/P&gt;
&lt;P&gt;The bottom line: Microsoft Build 2026 is an ideal opportunity for developers to see Azure HorizonDB in action, learn best practices for modern PostgreSQL architectures, and understand how to leverage Postgres in new scenarios like generative AI and multi-agent applications. Read on for a rundown of sessions covering these topics, complete with what you’ll learn from each one.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Top sessions for PostgreSQL databases on Azure &amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Below are key sessions tailored for PostgreSQL users and those interested in Azure HorizonDB, with session types and highlights of what you’ll gain by attending.&lt;/P&gt;
&lt;P&gt;🎤 &lt;STRONG&gt;Breakout&lt;/STRONG&gt;: &lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3EBreakout" target="_blank" rel="noopener"&gt;From Rows to Reasoning: Designing Databases for AI Apps and Agents&lt;/A&gt; (&lt;STRONG&gt;BRK223&lt;/STRONG&gt;, 45 min, in-person and digital options)&lt;/P&gt;
&lt;P&gt;Discover how to architect databases that can power tomorrow’s intelligent applications. This technical breakout will show how AI-ready databases can move beyond plain transactions. You’ll see live demos of integrating transactional, analytical, and vector data in one unified platform, with Azure’s new database capabilities, including Azure HorizonDB. Learn how to simplify your stack by eliminating separate analytics engines or vector stores. The session will highlight patterns that reduce data movement and latency so your apps can efficiently reason over live data with minimal complexity.&lt;/P&gt;
&lt;P&gt;🧪 &lt;STRONG&gt;Hands-on lab&lt;/STRONG&gt;: &lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3ELab&amp;amp;filter=sessionType%2FlogicalValue%3EDigital+Lab" target="_blank" rel="noopener"&gt;Create Advanced Postgres-Powered Agentic Apps with Azure HorizonDB&lt;/A&gt; (&lt;STRONG&gt;LAB511&lt;/STRONG&gt;, 75 min, in person and digital options)&lt;/P&gt;
&lt;P&gt;Roll up your sleeves and get hands-on building a real multi-agent AI application with Postgres. In this advanced lab, you’ll create a production-ready AI agent powered by Azure HorizonDB as an all-in-one data, search, and intelligence layer. Experiment with retrieval-augmented generation (RAG) by combining semantic vector search (DiskANN) with traditional SQL queries right inside the database. Implement hybrid search and agent workflows without resorting to external vector databases or glue code – thanks to HorizonDB’s built-in vector indexing and in-database AI model capabilities. This lab is perfect for developers who want to experience how HorizonDB can simplify your stack and boost performance for AI-driven apps.&amp;nbsp;&lt;BR /&gt;&lt;EM&gt;Multiple hands-on labs&amp;nbsp;are offered to suite your schedule.&amp;nbsp;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;💻 Demo&lt;/STRONG&gt;:&amp;nbsp;&lt;A href="https://build.microsoft.com/sessions/DEM364?source=sessions" target="_blank" rel="noopener"&gt;Simplify App Dev with Cloud-Native PostgreSQL in Azure HorizonDB&lt;/A&gt; (&lt;STRONG&gt;DEM364&lt;/STRONG&gt;, 25 min, in-person and digital options)&lt;/P&gt;
&lt;P&gt;See how to cut your development time and complexity with built-in AI and search features in Postgres. This fast-paced demo shows how Azure HorizonDB helps eliminate the need for separate search engines and AI services by pulling those capabilities straight into PostgreSQL. Expect to learn how you can run hybrid vector + keyword queries using SQL, integrate AI models directly from within the database, and apply full-text search (BM25) and semantic ranking to get smarter results. If you’re eager to deliver intelligent apps faster, with fewer moving parts, this session will show how HorizonDB simplifies your architecture without sacrificing performance.&lt;/P&gt;
&lt;P&gt;⚡&lt;STRONG&gt;Lightning Talk&lt;/STRONG&gt;: &lt;A href="https://build.microsoft.com/sessions/LTG413?source=sessions" target="_blank" rel="noopener"&gt;Cloud-Native PostgreSQL, Rebuilt for Scale: Azure HorizonDB&lt;/A&gt; (&lt;STRONG&gt;LTG413&lt;/STRONG&gt;, 15 min, in-person only)&lt;/P&gt;
&lt;P&gt;Get a rapid-fire introduction to the architecture behind HorizonDB’s eye-popping performance. This short talk dives into how HorizonDB re-architects core PostgreSQL to deliver effortless scale out and blazing speed. Learn how decoupled compute and storage, predictive caching, and multi-region replication combine to achieve sub-millisecond query latencies and 3× higher throughput than standard Postgres. If you care about performance tuning and high-scale database design, don’t miss this quick primer on the tech under HorizonDB’s hood.&lt;/P&gt;
&lt;P&gt;👥 &lt;STRONG&gt;Interactive Table Talk&lt;/STRONG&gt;: &lt;A href="https://build.microsoft.com/sessions/TT622?source=sessions" target="_blank" rel="noopener"&gt;Scaling PostgreSQL for AI Apps: Patterns and Tradeoffs&lt;/A&gt; (&lt;STRONG&gt;TT622&lt;/STRONG&gt;, 45 min, in-person only)&lt;/P&gt;
&lt;P&gt;Bring your questions and ideas to this collaborative discussion. In this open round-table session with community and Microsoft experts, you’ll explore architecture patterns for scaling PostgreSQL to meet the demands of agent-based and AI-driven applications. Discuss real-world strategies for handling vector embeddings in Postgres, unifying relational and document data, integrating with AI models, and more. Compare the trade-offs between different scaling approaches – from monolithic to microservices, sharding strategies, and new technologies like HorizonDB – and learn where each design shines or struggles in production. Come ready to share your experiences and learn from others in the room.&lt;/P&gt;
&lt;P&gt;▶️ &lt;STRONG&gt;On-Demand&lt;/STRONG&gt;: Smarter PostgreSQL Migrations to Power Modern, Intelligent Apps (&lt;STRONG&gt;OD822&lt;/STRONG&gt;, 30 min, digital only)&lt;/P&gt;
&lt;P&gt;Planning to migrate to Postgres or move your databases to Azure? Start here. This on-demand session focuses on new tools and proven strategies to migrate large-scale databases to Azure Database for PostgreSQL quickly and safely. You’ll see AI-assisted migration tools in action that minimize downtime and risk when moving terabytes of data. Just as importantly, you’ll learn how migrating to Azure unlocks advanced capabilities – from boosted performance and enhanced security to AI-ready features – helping you turn your newly migrated data into intelligent apps and services.&lt;EM&gt; &lt;BR /&gt;&lt;/EM&gt;&lt;EM&gt;On-demand session will be available to stream on the first day of Build.&lt;BR /&gt;&lt;BR /&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Meet the team: PostgreSQL expert meetups &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If you’re attending Build in person, stop by the Expert Meetup (EMU) area and head to the &lt;STRONG&gt;relational cloud databases &lt;/STRONG&gt;booth. This is your chance to talk directly with the engineers and product teams behind PostgreSQL on Azure.&lt;/P&gt;
&lt;P&gt;Bring your questions about architecture decisions, scaling patterns, migrations, AI workloads, or anything else on your mind. Whether you want to sanity-check a design, dig deeper into something you saw in a session, or give direct feedback, the EMU space is designed for exactly that convo.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How to get the most out of Build (and what to do next)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;With so much great content lined up, how do you decide where to start? It really depends on what you’re most excited about:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;Curious about AI and agentic apps:&lt;/EM&gt; Start with &lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3EBreakout" target="_blank" rel="noopener"&gt;From Rows to Reasoning&lt;/A&gt;, then go deeper with the &lt;A href="https://build.microsoft.com/sessions/DEM364?source=sessions" target="_blank" rel="noopener"&gt;Simplify App Dev with HorizonDB&lt;/A&gt; demo or get hands-on at the &lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3ELab&amp;amp;filter=sessionType%2FlogicalValue%3EDigital+Lab" target="_blank" rel="noopener"&gt;Azure HorizonDB lab&lt;/A&gt;s to see how these ideas work in practice.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Performance and scale are your focus:&lt;/EM&gt; The short &lt;A href="https://build.microsoft.com/sessions/LTG413?source=sessions" target="_blank" rel="noopener"&gt;Lightning Talk&lt;/A&gt; on HorizonDB’s cloud-native architecture and the &lt;A href="https://build.microsoft.com/sessions/TT622?source=sessions" target="_blank" rel="noopener"&gt;Table Talk on scaling Postgres&lt;/A&gt; will both provide unique insights and pro tips for running Postgres at massive scale.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Planning a migration to PostgreSQL on Azure:&lt;/EM&gt;&amp;nbsp;Watch the Smarter PostgreSQL Migrations on-demand session to learn how to migrate large workloads with minimal downtime, and the benefits you can unlock after moving to Azure.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;Looking for real answers to your specific questions: &lt;/EM&gt;Make time for the PostgreSQL Expert Meetup area to connect directly with the team.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;No matter which sessions you choose, Build 2026 promises to be an exciting event for the PostgreSQL developer community. Browse the &lt;A href="https://build.microsoft.com/sessions?search=postgres&amp;amp;sortBy=relevance&amp;amp;filter=sessionType%2FlogicalValue%3EBreakout" target="_blank" rel="noopener"&gt;session catalog&lt;/A&gt;, save the sessions that match your interests, and we’ll see you at Build. &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 26 May 2026 14:13:21 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/select-from-build2026-sessions-where-postgres-true/ba-p/4522093</guid>
      <dc:creator>Pooja_Y</dc:creator>
      <dc:date>2026-05-26T14:13:21Z</dc:date>
    </item>
    <item>
      <title>Regex support for LOB types in T-SQL—available in Azure SQL &amp; SQL Server 2025</title>
      <link>https://techcommunity.microsoft.com/t5/azure-sql-blog/regex-support-for-lob-types-in-t-sql-available-in-azure-sql-sql/ba-p/4522396</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;At a glance&lt;/STRONG&gt; — Native regular expression (regex) functions in T-SQL now accept varchar(max) and nvarchar(max) inputs of up to&amp;nbsp;&lt;STRONG&gt;2 MB&lt;/STRONG&gt;&amp;nbsp;across&amp;nbsp;&lt;STRONG&gt;all seven&lt;/STRONG&gt;&amp;nbsp;regex functions, including the two table-valued functions (REGEXP_MATCHES&amp;nbsp;and&amp;nbsp;REGEXP_SPLIT_TO_TABLE). This capability ships in&amp;nbsp;&lt;A href="https://learn.microsoft.com/troubleshoot/sql/releases/sqlserver-2025/cumulativeupdate5" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;SQL Server 2025 CU5&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;and is already available in&amp;nbsp;&lt;STRONG&gt;Azure SQL Database, SQL Database in Fabric&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;Azure SQL Managed Instance&lt;/STRONG&gt; configured with the Always-up-to-date update policy. It will reach Managed Instances on the SQL Server 2025 update policy as part of the CU5 rollout. You no longer need to split log files, HTML documents, or large JSON payloads into 8,000-byte chunks just to run a pattern match.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;1. Introduction&lt;/H2&gt;
&lt;P&gt;Regular expressions have long been a cornerstone of modern data processing — used for validation, parsing, transformation, and extracting structured insights from unstructured text. With&amp;nbsp;&lt;STRONG&gt;SQL Server 2025&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;Azure SQL&lt;/STRONG&gt;, regex is now a first-class T-SQL capability, removing the historical need to rely on SQLCLR functions or application-tier processing.&lt;/P&gt;
&lt;P&gt;While the initial release made native regex broadly available, large-object (LOB) inputs were not yet supported on every function. CU5 closes that gap.&lt;/P&gt;
&lt;P&gt;Under the hood, T-SQL regex implements&amp;nbsp;&lt;STRONG&gt;POSIX&amp;nbsp;&lt;/STRONG&gt;Extended Regular Expression&lt;STRONG&gt;&amp;nbsp;(ERE)&lt;/STRONG&gt;&amp;nbsp;semantics, augmented by a curated set of Perl-style features, and is powered by the RE2 engine. RE2 is a&amp;nbsp;&lt;EM&gt;linear-time&lt;/EM&gt;, non-backtracking implementation, which means it is not susceptible to catastrophic backtracking (a class of denial-of-service issue commonly known as ReDoS). That guarantee becomes far more important when the input is a 1.8 MB log blob than when it is an 8,000-byte string.&lt;/P&gt;
&lt;H3&gt;Release timeline&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table class="lia-border-style-solid" border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Milestone&lt;/td&gt;&lt;td&gt;What shipped&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Ignite 2025 — General Availability&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Regex went GA in&amp;nbsp;&lt;STRONG&gt;SQL Server 2025&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;Azure SQL&lt;/STRONG&gt;. LOB inputs were initially supported only on&amp;nbsp;REGEXP_LIKE,&amp;nbsp;REGEXP_COUNT, and&amp;nbsp;REGEXP_INSTR. LOB support on&amp;nbsp;REGEXP_REPLACE&amp;nbsp;and&amp;nbsp;REGEXP_SUBSTR&amp;nbsp;was deferred, and the two table-valued functions (TVFs) accepted only non-LOB string types.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Azure SQL (post-GA service updates)&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;LOB inputs enabled across all seven functions.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;A href="https://learn.microsoft.com/troubleshoot/sql/releases/sqlserver-2025/cumulativeupdate5" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;SQL Server 2025 CU5&lt;/STRONG&gt;&lt;/A&gt;&lt;/td&gt;&lt;td&gt;LOB inputs up to&amp;nbsp;&lt;STRONG&gt;2 MB&lt;/STRONG&gt;&amp;nbsp;enabled on&amp;nbsp;&lt;STRONG&gt;all seven&lt;/STRONG&gt; functions in the SQL Server.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;What’s new in CU5&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;varchar(max)&amp;nbsp;and&amp;nbsp;nvarchar(max)&amp;nbsp;inputs are accepted on&amp;nbsp;&lt;STRONG&gt;every&lt;/STRONG&gt;&amp;nbsp;regex function.&lt;/LI&gt;
&lt;LI&gt;The input string is capped at&amp;nbsp;&lt;STRONG&gt;2 MB per function call&lt;/STRONG&gt;. The pattern is still capped at&amp;nbsp;&lt;STRONG&gt;8,000 bytes&lt;/STRONG&gt;, which is far larger than any maintainable regular expression should ever need.&lt;/LI&gt;
&lt;LI&gt;Behavior is consistent between Azure SQL and SQL Server, so code you write today is fully portable.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&amp;nbsp;— The 2 MB limit applies to the&amp;nbsp;&lt;STRONG&gt;input passed to a single function call&lt;/STRONG&gt;, not to the column or row. A single value in a varchar(max) column can still store up to 2 GB; the constraint is that no single regex evaluation can consume more than 2 MB of that value.&lt;/P&gt;
&lt;H3&gt;Prerequisites&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;SQL Server 2025 CU5&lt;/STRONG&gt;&amp;nbsp;or later,&amp;nbsp;&lt;STRONG&gt;or&lt;/STRONG&gt;&amp;nbsp;Azure SQL Database,&amp;nbsp;&lt;STRONG&gt;or&lt;/STRONG&gt;&amp;nbsp;SQL Database in Fabric&amp;nbsp;&lt;STRONG&gt;or&lt;/STRONG&gt;&amp;nbsp;Azure SQL Managed Instance configured with the SQL Server 2025 / Always-up-to-date&amp;nbsp;&lt;A href="https://learn.microsoft.com/azure/azure-sql/managed-instance/update-policy" target="_blank" rel="noopener"&gt;update policy&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;The two table-valued functions (REGEXP_MATCHES&amp;nbsp;and&amp;nbsp;REGEXP_SPLIT_TO_TABLE) require&amp;nbsp;&lt;STRONG&gt;database compatibility level 170&lt;/STRONG&gt;, unless the database-scoped configuration ALLOW_BUILTIN_TVF_IN_ALL_COMPAT_LEVELS (preview) is enabled.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt; — On Azure SQL Managed Instance (Always-up-to-date), this capability is rolling out region by region. It is already live in regions where the rollout has completed and will light up in the remaining regions as the deployment finishes. Instances on the&amp;nbsp;&lt;STRONG&gt;SQL Server 2025&lt;/STRONG&gt; update policy will receive it as part of the CU5 rollout — coming soon.&lt;/P&gt;
&lt;P&gt;Verify compatibility level (170 required for the TVFs) –&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT name, compatibility_level FROM sys.databases WHERE name = DB_NAME(); 

-- If necessary: 
-- ALTER DATABASE [&amp;lt;your-database&amp;gt;] SET COMPATIBILITY_LEVEL = 170;&lt;/LI-CODE&gt;
&lt;H2&gt;2. Working with LOB Data&lt;/H2&gt;
&lt;P&gt;This section demonstrates the CU5 capabilities against a realistic LOB data. We build a LogEntries table whose RawPayload column holds multi-KB to multi-MB chunks of web server and application output, plus an HtmlPages table for HTML cleansing examples.&lt;/P&gt;
&lt;H3&gt;2.1 Create the sample schema and data&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;IF OBJECT_ID('dbo.LogEntries', 'U') IS NOT NULL DROP TABLE dbo.LogEntries;
IF OBJECT_ID('dbo.HtmlPages',  'U') IS NOT NULL DROP TABLE dbo.HtmlPages;

CREATE TABLE dbo.LogEntries
(
    LogId       BIGINT IDENTITY(1,1) PRIMARY KEY,
    Source      SYSNAME       NOT NULL,
    IngestedAt  DATETIME2(3)  NOT NULL DEFAULT SYSUTCDATETIME(),
    RawPayload  VARCHAR(MAX)  NOT NULL   -- LOB column
);

CREATE TABLE dbo.HtmlPages
(
    PageId      INT IDENTITY(1,1) PRIMARY KEY,
    Url         NVARCHAR(2048) NOT NULL,
    Body        NVARCHAR(MAX)  NOT NULL  -- LOB column (Unicode)
);&lt;/LI-CODE&gt;
&lt;P&gt;Now generate realistically large rows. The&amp;nbsp;REPLICATE(CAST(...&amp;nbsp;AS varchar(max)),&amp;nbsp;n)&amp;nbsp;pattern is required because&amp;nbsp;REPLICATE&amp;nbsp;returns&amp;nbsp;NULL&amp;nbsp;when the result would exceed 8,000 bytes unless its first argument is a max type.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Synthetic web access-log payload (~252 KB in row 1, plus a separate ~586 KB row).
DECLARE @logLine VARCHAR(500) =
    '127.0.0.1 - alice [21/May/2026:10:15:32 +0000] "GET /api/orders/42 HTTP/1.1" 200 1532 ' +
    'user-agent="Mozilla/5.0" ip=10.0.0.7 email=alice@contoso.com card=4111-1111-1111-1234' + CHAR(10);

DECLARE @bigLog VARCHAR(MAX) =
    REPLICATE(CAST(@logLine AS VARCHAR(MAX)), 1500)                -- ~252 KB
    + '127.0.0.1 - mallory [21/May/2026:10:16:01 +0000] "POST /login HTTP/1.1" 500 0 ' +
      'ip=203.0.113.99 ssn=123-45-6789' + CHAR(10);

INSERT INTO dbo.LogEntries (Source, RawPayload) VALUES
    ('web-01', @bigLog),                                            -- ~252 KB
    ('web-02', REPLICATE(CAST('OK ' AS VARCHAR(MAX)), 200000));     -- ~586 KB

-- Synthetic HTML page (~775 KB / ~396,000 characters).
DECLARE @htmlChunk NVARCHAR(MAX) =
    N'&amp;lt;div class="row"&amp;gt;&amp;lt;p&amp;gt;Hello &amp;lt;b&amp;gt;world&amp;lt;/b&amp;gt;! Contact &amp;lt;a href="mailto:bob@contoso.com"&amp;gt;bob&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;';

INSERT INTO dbo.HtmlPages (Url, Body) VALUES
    (N'https://contoso.example/page-1',
     N'&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Big Page&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;'
     + REPLICATE(@htmlChunk, 4000)
     + N'&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;');

-- Confirm payload sizes in bytes.
SELECT LogId, Source, DATALENGTH(RawPayload) AS PayloadBytes FROM dbo.LogEntries;
SELECT PageId, DATALENGTH(Body) AS BodyBytes, LEN(Body) AS BodyChars FROM dbo.HtmlPages;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Results:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;Source&lt;/td&gt;&lt;td&gt;PayloadBytes&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;web-01&lt;/td&gt;&lt;td&gt;258,110&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;web-02&lt;/td&gt;&lt;td&gt;600,000&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;PageId&lt;/td&gt;&lt;td&gt;BodyBytes&lt;/td&gt;&lt;td&gt;BodyChars&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;792,124&lt;/td&gt;&lt;td&gt;396,062&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Before CU5, feeding any of these payloads into&amp;nbsp;REGEXP_REPLACE,&amp;nbsp;REGEXP_SUBSTR,&amp;nbsp;REGEXP_MATCHES, or&amp;nbsp;REGEXP_SPLIT_TO_TABLE&amp;nbsp;would have failed with a type-mismatch error or required a&amp;nbsp;LEFT(RawPayload,&amp;nbsp;8000)-style truncation. The same queries now run end-to-end.&lt;/P&gt;
&lt;H3&gt;2.2 REGEXP_LIKE — Filter rows by LOB content&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Find logs that contain at least one HTTP 5xx response.
SELECT LogId, Source, DATALENGTH(RawPayload) AS PayloadBytes
FROM   dbo.LogEntries
WHERE  REGEXP_LIKE(RawPayload, '"[A-Z]+\s[^"]+\sHTTP/1\.[01]"\s5[0-9]{2}\s');&lt;/LI-CODE&gt;
&lt;P&gt;REGEXP_LIKE&amp;nbsp;is a Boolean predicate: it evaluates to&amp;nbsp;true&amp;nbsp;when the pattern matches anywhere in the input and&amp;nbsp;false&amp;nbsp;otherwise. Because it returns a Boolean rather than a&amp;nbsp;bit, use it directly in&amp;nbsp;WHERE,&amp;nbsp;CASE WHEN,&amp;nbsp;IIF, or&amp;nbsp;CHECK&amp;nbsp;constraint contexts — do&amp;nbsp;&lt;STRONG&gt;not&lt;/STRONG&gt;&amp;nbsp;compare it with = 1 or = 0 (the parser rejects that syntax).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;REGEXP_LIKE&amp;nbsp;itself requires database compatibility level&amp;nbsp;&lt;STRONG&gt;170&lt;/STRONG&gt;. The other scalar regex functions (REGEXP_COUNT,&amp;nbsp;REGEXP_INSTR,&amp;nbsp;REGEXP_REPLACE,&amp;nbsp;REGEXP_SUBSTR) are available at all compatibility levels.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Results:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;Source&lt;/td&gt;&lt;td&gt;PayloadBytes&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;web-01&lt;/td&gt;&lt;td&gt;258,110&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;2.3 REGEXP_COUNT — Counting at scale&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Per-row tally of GET requests, POST requests, and 5xx responses
-- across the entire LOB payload.
SELECT LogId,
       Source,
       REGEXP_COUNT(RawPayload, '"GET\s')        AS Gets,
       REGEXP_COUNT(RawPayload, '"POST\s')       AS Posts,
       REGEXP_COUNT(RawPayload, '\s5[0-9]{2}\s') AS ServerErrors
FROM   dbo.LogEntries;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Results:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;Source&lt;/td&gt;&lt;td&gt;Gets&lt;/td&gt;&lt;td&gt;Posts&lt;/td&gt;&lt;td&gt;ServerErrors&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;web-01&lt;/td&gt;&lt;td&gt;1,500&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;web-02&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;2.4 REGEXP_INSTR — Locate the first error&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- 1-based character position (or 0 if no match) of the FIRST 5xx response in each payload.
SELECT LogId,
       Source,
       REGEXP_INSTR(RawPayload, '\s5[0-9]{2}\s', 1, 1, 0) AS FirstErrorPos
FROM   dbo.LogEntries;&lt;/LI-CODE&gt;
&lt;P&gt;Parameter recap:&amp;nbsp;REGEXP_INSTR(string,&amp;nbsp;pattern,&amp;nbsp;start,&amp;nbsp;occurrence,&amp;nbsp;return_option&amp;nbsp;[,&amp;nbsp;flags&amp;nbsp;[,&amp;nbsp;group&amp;nbsp;]]). A&amp;nbsp;return_option&amp;nbsp;of&amp;nbsp;0&amp;nbsp;returns the starting position of the match;&amp;nbsp;1&amp;nbsp;returns the position immediately after the last character of the match.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Results:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;Source&lt;/td&gt;&lt;td&gt;FirstErrorPos&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;web-01&lt;/td&gt;&lt;td&gt;258,072&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;web-02&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;2.5 REGEXP_REPLACE — Redact sensitive data in place&lt;/H3&gt;
&lt;P&gt;PII redaction over LOB payloads was one of the most-requested CU5 scenarios. Before CU5, it required a custom chunked-replace routine; it is now a single expression.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Redact credit-card-shaped tokens, U.S. SSN-shaped tokens, and email addresses
-- across the entire payload.
SELECT LogId,
       REGEXP_REPLACE(
           REGEXP_REPLACE(
               REGEXP_REPLACE(
                   RawPayload,
                   '\b[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\b',
                   '****-****-****-****'),
               '\b[0-9]{3}-[0-9]{2}-[0-9]{4}\b',
               '***-**-****'),
           '\b[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}\b',
           '[redacted-email]'
       ) AS RedactedPayload
FROM   dbo.LogEntries;&lt;/LI-CODE&gt;
&lt;P&gt;Or strip every HTML tag from an&amp;nbsp;nvarchar(max)&amp;nbsp;page in a single call:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT PageId,
       LEN(Body)                                     AS OriginalLen,
       LEN(REGEXP_REPLACE(Body, N'&amp;lt;[^&amp;gt;]+&amp;gt;', N''))    AS TextOnlyLen
FROM   dbo.HtmlPages;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Results&lt;/STRONG&gt;&amp;nbsp;— the ~775 KB HTML document collapses from 396,062 to 100,008 characters of plain text in a single call:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;PageId&lt;/td&gt;&lt;td&gt;OriginalLen&lt;/td&gt;&lt;td&gt;TextOnlyLen&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;396,062&lt;/td&gt;&lt;td&gt;100,008&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;2.6 REGEXP_SUBSTR — Extract a single value&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Pull the first IPv4 address out of each log payload.
SELECT LogId,
       REGEXP_SUBSTR(RawPayload,
                     '\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b',
                     1,    -- start position
                     1,    -- occurrence
                     'c',  -- flags: case-sensitive
                     0     -- group: 0 returns the whole match
                    ) AS FirstIp
FROM   dbo.LogEntries;&lt;/LI-CODE&gt;
&lt;P&gt;To return the contents of a specific capture group instead of the entire match, pass its 1-based group number as the final argument.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Results:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;FirstIp&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;NULL&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;2.7 REGEXP_MATCHES — Every match, set-based&lt;/H3&gt;
&lt;P&gt;This is where the combination of TVF and LOB delivers the largest productivity gain: extract every structured value from a megabyte of unstructured text in a single set-based query, with no client round-trips.&lt;/P&gt;
&lt;P&gt;REGEXP_MATCHES&amp;nbsp;returns one row per match with these columns:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Column&lt;/td&gt;&lt;td&gt;Type&lt;/td&gt;&lt;td&gt;Description&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;match_id&lt;/td&gt;&lt;td&gt;bigint&lt;/td&gt;&lt;td&gt;Sequence number of the match (1-based).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;start_position&lt;/td&gt;&lt;td&gt;int&lt;/td&gt;&lt;td&gt;1-based start index of the match.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;end_position&lt;/td&gt;&lt;td&gt;int&lt;/td&gt;&lt;td&gt;1-based end index of the match.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;match_value&lt;/td&gt;&lt;td&gt;same type as&amp;nbsp;string_expression&lt;/td&gt;&lt;td&gt;The entire matched substring.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;substring_matches&lt;/td&gt;&lt;td&gt;json&lt;/td&gt;&lt;td&gt;JSON array describing each capture group, with the shape&amp;nbsp;[{"value":"…","start":N,"length":N},&amp;nbsp;…].&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;LI-CODE lang="sql"&gt;-- Every email address in every log payload, alongside its row of origin.
SELECT  l.LogId,
        m.match_id,
        m.match_value AS EmailFound
FROM    dbo.LogEntries AS l
CROSS APPLY REGEXP_MATCHES(
        l.RawPayload,
        '\b[A-Za-z0-9._%+\-]+@[A-Za-z0-9.\-]+\.[A-Za-z]{2,}\b'
) AS m
ORDER BY l.LogId, m.match_id;&lt;/LI-CODE&gt;
&lt;P&gt;Capture groups are even more useful — you can project the parts of every log line as columns by reading from the&amp;nbsp;substring_matches&amp;nbsp;JSON document:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Parse Common-Log-Format-ish entries into ip, user, status, and bytes columns.
-- The pattern has four capture groups, accessed below as $[0] through $[3].
SELECT  l.LogId,
        m.match_id,
        JSON_VALUE(m.substring_matches, '$[0].value') AS Ip,
        JSON_VALUE(m.substring_matches, '$[1].value') AS UserName,
        JSON_VALUE(m.substring_matches, '$[2].value') AS Status,
        JSON_VALUE(m.substring_matches, '$[3].value') AS Bytes
FROM    dbo.LogEntries AS l
CROSS APPLY REGEXP_MATCHES(
        l.RawPayload,
        '^([0-9.]+)\s-\s(\S+)\s\[[^\]]+\]\s"[^"]+"\s([0-9]{3})\s([0-9]+)',
        'm'    -- multi-line: ^ and $ anchor to each line, not just the whole input
) AS m
ORDER BY l.LogId, m.match_id;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Important&lt;/STRONG&gt;&amp;nbsp;— Without the&amp;nbsp;'m'&amp;nbsp;flag, the&amp;nbsp;^&amp;nbsp;anchor matches only at the start of the entire 250 KB input, so you would receive exactly one match for the first line. The multi-line flag is what unlocks per-line extraction.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Results&lt;/STRONG&gt;&amp;nbsp;(first two parsed rows):&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;match_id&lt;/td&gt;&lt;td&gt;Ip&lt;/td&gt;&lt;td&gt;UserName&lt;/td&gt;&lt;td&gt;Status&lt;/td&gt;&lt;td&gt;Bytes&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;alice&lt;/td&gt;&lt;td&gt;200&lt;/td&gt;&lt;td&gt;1532&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;127.0.0.1&lt;/td&gt;&lt;td&gt;alice&lt;/td&gt;&lt;td&gt;200&lt;/td&gt;&lt;td&gt;1532&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 16.67%" /&gt;&lt;col style="width: 16.67%" /&gt;&lt;col style="width: 16.67%" /&gt;&lt;col style="width: 16.67%" /&gt;&lt;col style="width: 16.67%" /&gt;&lt;col style="width: 16.67%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;2.8 REGEXP_SPLIT_TO_TABLE — Shred a LOB into rows&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Project the entire log payload as one row per non-empty line.
SELECT  l.LogId,
        s.ordinal AS [LineNo],
        s.value   AS LineText
FROM    dbo.LogEntries AS l
CROSS APPLY REGEXP_SPLIT_TO_TABLE(l.RawPayload, '\r?\n') AS s
WHERE   l.LogId = 1
  AND   s.value &amp;lt;&amp;gt; ''
ORDER BY s.ordinal;&lt;/LI-CODE&gt;
&lt;P&gt;You now have a tabular projection of a multi-megabyte text blob without leaving the engine. You can feed it into a CTE, aggregate it, join it to dimension tables, or materialize it into a staging table — all set-based.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Results&lt;/STRONG&gt;&amp;nbsp;(first three rows):&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;LogId&lt;/td&gt;&lt;td&gt;ordinal&lt;/td&gt;&lt;td&gt;LineText (first 80 chars)&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;127.0.0.1&amp;nbsp;-&amp;nbsp;alice&amp;nbsp;[21/May/2026:10:15:32&amp;nbsp;+0000]&amp;nbsp;"GET /api/orders/42 HTTP/1.1"&amp;nbsp;200&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;127.0.0.1&amp;nbsp;-&amp;nbsp;alice&amp;nbsp;[21/May/2026:10:15:32&amp;nbsp;+0000]&amp;nbsp;"GET /api/orders/42 HTTP/1.1"&amp;nbsp;200&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;127.0.0.1&amp;nbsp;-&amp;nbsp;alice&amp;nbsp;[21/May/2026:10:15:32&amp;nbsp;+0000]&amp;nbsp;"GET /api/orders/42 HTTP/1.1"&amp;nbsp;200&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;Tip — composing LOB regex pipelines&lt;/STRONG&gt; — CROSS APPLY (and OUTER APPLY when you need to preserve rows that produce no matches) is the primary composition primitive. You can stack REGEXP_SPLIT_TO_TABLE (lines) feeding REGEXP_MATCHES (fields per line) feeding ordinary aggregates, all within a single query plan.&lt;/P&gt;
&lt;H3&gt;2.9 The 2 MB ceiling — strategies for larger inputs&lt;/H3&gt;
&lt;P&gt;The 2 MB limit applies to the&amp;nbsp;&lt;STRONG&gt;input string of a single regex call&lt;/STRONG&gt;. If the value passed to a regex function exceeds 2 MB, the call raises an error (&lt;STRONG&gt;error number&amp;nbsp;19311&lt;/STRONG&gt;, severity 16) rather than silently truncating. That is the intended behavior — silent truncation would hide correctness bugs.&lt;/P&gt;
&lt;P&gt;In practice, 2 MB is a generous ceiling: a single log file or HTML document of that size is already unusual, and most real-world LOB data sit comfortably below it. When individual values do exceed the limit, the most reliable approach is to&amp;nbsp;&lt;STRONG&gt;split them into smaller logical units before they land in the column you want to query&lt;/STRONG&gt; — for example, by writing one log line, one document section, or one record per row at ingestion time. Because every regex function (including the two TVFs) shares the same 2 MB ceiling, sharding at query time is not generally feasible; doing it at the load path keeps every regex call well under the limit and avoids per-query workarounds.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Bytes vs. characters&lt;/STRONG&gt;&amp;nbsp;— The 2 MB limit is measured in&amp;nbsp;&lt;STRONG&gt;bytes&lt;/STRONG&gt;, not characters, and the byte count is based on the UTF-8 encoding of the input regardless of the column’s declared type. ASCII characters take 1 byte each, so plain ASCII text can run to roughly two million characters; non-ASCII characters take 2–4 bytes in UTF-8, so fewer characters fit. Keep in mind that&amp;nbsp;DATALENGTH()&amp;nbsp;reports storage size in the column’s own encoding, which may differ from the UTF-8 byte count used by the limit, and&amp;nbsp;LEN()&amp;nbsp;(which counts characters) is best avoided as a sizing check here.&lt;/P&gt;
&lt;P&gt;To measure the UTF-8 byte length that the limit actually checks, cast the value to varchar(max) under a UTF-8 collation and take its DATALENGTH:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT DATALENGTH(
           CONVERT(varchar(max),
                   Body COLLATE Latin1_General_100_CI_AS_SC_UTF8)
       ) AS Utf8Bytes
FROM   dbo.HtmlPages;&lt;/LI-CODE&gt;
&lt;P&gt;Anything above 2 * 1024 * 1024 (2,097,152) bytes will be rejected by a regex call on that value.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Have a scenario that genuinely needs more than 2 MB?&lt;/STRONG&gt;&amp;nbsp;If your workload requires regex evaluation on individual values larger than the current 2 MB ceiling, we would like to hear about it. Please share the details — data shape, payload size, pattern, and business need — on the&amp;nbsp;&lt;A href="https://feedback.azure.com/d365community/forum/04fe6ee0-3b25-ec11-b6e6-000d3a4f0da0" target="_blank" rel="noopener"&gt;Azure SQL feedback portal&lt;/A&gt;. Customer feedback directly informs how we prioritize future limit changes.&lt;/P&gt;
&lt;H3&gt;2.10 Cleanup&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;DROP TABLE IF EXISTS dbo.LogEntries;
DROP TABLE IF EXISTS dbo.HtmlPages;&lt;/LI-CODE&gt;
&lt;H2&gt;3. Summary&lt;/H2&gt;
&lt;H3&gt;What changed in CU5&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Before CU5&lt;/STRONG&gt;&amp;nbsp;— LOB inputs were accepted on&amp;nbsp;REGEXP_LIKE,&amp;nbsp;REGEXP_COUNT, and&amp;nbsp;REGEXP_INSTR. The remaining functions —&amp;nbsp;REGEXP_REPLACE,&amp;nbsp;REGEXP_SUBSTR, and the two TVFs (REGEXP_MATCHES,&amp;nbsp;REGEXP_SPLIT_TO_TABLE) — required non-LOB string inputs, which often meant truncating with&amp;nbsp;LEFT(...,&amp;nbsp;8000)&amp;nbsp;or chunking in the application tier.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;After CU5 (and already in Azure SQL)&lt;/STRONG&gt;&amp;nbsp;— All seven functions accept&amp;nbsp;varchar(max)&amp;nbsp;and&amp;nbsp;nvarchar(max)&amp;nbsp;inputs of up to&amp;nbsp;&lt;STRONG&gt;2 MB&lt;/STRONG&gt;. The pattern remains capped at 8,000 bytes.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Quick reference&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Function&lt;/td&gt;&lt;td&gt;Returns&lt;/td&gt;&lt;td&gt;LOB input (CU5)&lt;/td&gt;&lt;td&gt;Common use case&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;REGEXP_LIKE&lt;/td&gt;&lt;td&gt;Boolean (predicate)&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Filter rows in&amp;nbsp;WHERE&amp;nbsp;/&amp;nbsp;CASE&amp;nbsp;/&amp;nbsp;CHECK&amp;nbsp;predicates&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_COUNT&lt;/td&gt;&lt;td&gt;int&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Count occurrences of a pattern&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_INSTR&lt;/td&gt;&lt;td&gt;int&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Position of the&amp;nbsp;&lt;EM&gt;n&lt;/EM&gt;th match&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_REPLACE&lt;/td&gt;&lt;td&gt;string&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Redact, cleanse, or normalize text&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_SUBSTR&lt;/td&gt;&lt;td&gt;string&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Extract a single value&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_MATCHES&amp;nbsp;(TVF)&lt;/td&gt;&lt;td&gt;(match_id,&amp;nbsp;start_position,&amp;nbsp;end_position,&amp;nbsp;match_value,&amp;nbsp;substring_matches)&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Extract every match plus capture groups (via JSON), set-based&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;REGEXP_SPLIT_TO_TABLE&amp;nbsp;(TVF)&lt;/td&gt;&lt;td&gt;(value,&amp;nbsp;ordinal)&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Split a LOB into rows by a regex delimiter&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;Further reading&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Official documentation: &lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-like-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_LIKE&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-count-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_COUNT&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-instr-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_INSTR&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-replace-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_REPLACE&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-substr-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_SUBSTR&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-matches-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_MATCHES&lt;/A&gt;,&amp;nbsp;&lt;A href="https://learn.microsoft.com/sql/t-sql/functions/regexp-split-to-table-transact-sql" target="_blank" rel="noopener"&gt;REGEXP_SPLIT_TO_TABLE&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/sql/relational-databases/regular-expressions/overview" target="_blank" rel="noopener"&gt;Regular expressions overview&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/troubleshoot/sql/releases/sqlserver-2025/cumulativeupdate5" target="_blank" rel="noopener"&gt;SQL Server 2025 CU5 release notes&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Closing thought.&lt;/STRONG&gt;&amp;nbsp;Native regex was already a significant quality-of-life improvement when it became generally available. CU5 completes the picture: every function, every input size up to 2 MB, every shape — scalar or table-valued. The next time you are tempted to export a column out of the database in order to grep it, try one of the seven regex functions first.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Happy matching. 🧠&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 22 May 2026 20:28:26 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-sql-blog/regex-support-for-lob-types-in-t-sql-available-in-azure-sql-sql/ba-p/4522396</guid>
      <dc:creator>abhimantiwari</dc:creator>
      <dc:date>2026-05-22T20:28:26Z</dc:date>
    </item>
    <item>
      <title>Real-World Success Stories with PostgreSQL on Azure</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/real-world-success-stories-with-postgresql-on-azure/ba-p/4519862</link>
      <description>&lt;P&gt;Organizations rarely leap into cloud migrations or AI-powered systems overnight. They progress in deliberate stages, establishing a reliable data foundation, optimizing for performance, and then accelerating innovation. Across healthcare, financial services, and AI startups, companies are navigating this journey on Azure Database for PostgreSQL: a fully managed, enterprise-ready PostgreSQL environment with 58% lower total cost of ownership (TCO) compared to on-premises deployments.&lt;/P&gt;
&lt;P&gt;This post walks through &lt;A href="https://aka.ms/PostgresCustomerStoriesEbook" target="_blank" rel="noopener"&gt;real customer stories&lt;/A&gt; that span the full arc, from lift-and-shift migration to production-grade AI agent development, illustrating how Azure Database for PostgreSQL supports scalability, performance, security, and AI-readiness at every stage.&lt;/P&gt;
&lt;H2&gt;Migrating with Confidence: Apollo Hospitals &amp;amp; August AI&lt;/H2&gt;
&lt;P&gt;&lt;A href="https://www.microsoft.com/en/customers/story/25629-apollo-hospitals-azure-database-for-postgresql" target="_blank" rel="noopener"&gt;Apollo Hospitals&lt;/A&gt; operates a network of more than 74 hospitals and needed to move beyond a legacy on-premises Oracle system that had become difficult to manage and couldn't keep pace with growing data volumes. IT teams were spending their time on maintenance rather than innovation.&lt;/P&gt;
&lt;P&gt;Apollo migrated its core hospital information system backend to Azure Database for PostgreSQL. Working with partner Quadrant Technologies, the team lifted and shifted critical applications while using Azure DevOps to orchestrate CI/CD pipelines and Azure Application Insights for telemetry and observability. The results:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;99.95% availability across hospital systems&lt;/LI&gt;
&lt;LI&gt;Database transactions executing within 5 seconds&lt;/LI&gt;
&lt;LI&gt;40% reduction in deployment times via modern CI/CD pipelines&lt;/LI&gt;
&lt;LI&gt;Decreased operational overhead, freeing IT staff for higher-value work&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;With a stable, scalable PostgreSQL backend in place, Apollo is now exploring real-time analytics and AI-enabled tools like Microsoft 365 Copilot to advance patient care.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"We saw Azure Database for PostgreSQL as the right foundation for the future. It's open, cost-effective, and capable of supporting the hospital information system we built in-house."&lt;/EM&gt; — Shankar Krishna A., General Manager of IT, Apollo Hospitals&lt;/P&gt;
&lt;P&gt;Apollo's experience is not unique. &lt;A href="https://www.microsoft.com/en/customers/story/25636-august-ai-linux-on-azure" target="_blank" rel="noopener"&gt;August AI&lt;/A&gt;, a healthcare-tech startup offering an AI-driven medical companion, migrated its entire stack to Azure—with Azure Database for PostgreSQL storing mission-critical patient data while meeting strict compliance requirements such as HIPAA. The result: scaling from roughly 500,000 users to 3.5 million+ users worldwide, with zero downtime during the cutover, completed in just three months. As Founder and CEO Anuruddh Mishra noted: &lt;EM&gt;"We receive a log of queries that are not performing optimally, and within a couple of minutes we can optimize that query with PostgreSQL on Azure and move on"&lt;/EM&gt;.&lt;/P&gt;
&lt;H2&gt;Modernizing at Scale: Nasdaq&lt;/H2&gt;
&lt;P&gt;Migration is often the first step. &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/nasdaq-builds-thoughtfully-designed-ai-for-board-governance-with-postgresql-on-a/4493078" target="_blank" rel="noopener"&gt;Nasdaq&lt;/A&gt; demonstrates what becomes possible when organizations modernize their architecture on a scalable data foundation.&lt;/P&gt;
&lt;P&gt;To improve its Nasdaq Boardvantage platform—used by corporate boards to collaborate on governance documents—Nasdaq re-architected on Azure. The team containerized services with Azure Kubernetes Service (AKS) and adopted Azure Database for PostgreSQL alongside Azure Database for MySQL as persistent data stores for governance workloads. This architecture provided the flexibility, performance, and security required for a multitenant platform handling sensitive board materials.&lt;/P&gt;
&lt;P&gt;With the data layer in place, Nasdaq integrated Microsoft Foundry and Azure OpenAI to deliver AI-powered summarization and workflow automation. The measurable outcomes:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;60% reduction in reading time through AI-powered document summarization&lt;/LI&gt;
&lt;LI&gt;25% decrease in administrative preparation time across board workflows&lt;/LI&gt;
&lt;LI&gt;Up to 97% accuracy in AI-generated summaries and meeting minutes&lt;/LI&gt;
&lt;LI&gt;A reusable AI framework established for future extensibility&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;"Both Azure Database for PostgreSQL and Azure Database for MySQL gave us the right balance of performance, security, and control. The governance workloads we handle are unique, so we needed something that could meet those isolation and encryption requirements."&lt;/EM&gt; — Scott Ellison, Vice President of Technology, Nasdaq&lt;/P&gt;
&lt;H2&gt;Building Intelligent Applications: SubgenAI and OpenAI&lt;/H2&gt;
&lt;P&gt;Azure Database for PostgreSQL now supports native vector search via pgvector, high-performance DiskANN indexing, semantic operators and AI model management, and integrated graph capabilities for relationship reasoning—making it a production-ready foundation for intelligent applications.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/subgenai-makes-ai-practical-scalable-and-sustainable-with-azure-database-for-pos/4475021" target="_blank" rel="noopener"&gt;SubgenAI&lt;/A&gt;, a European generative AI company, built its flagship platform Serenity Star on Azure Database for PostgreSQL and Microsoft Foundry to transform AI agent development from a code-heavy, fragmented process into a streamlined, no-code experience. A core technical requirement: the platform's retrieval-augmented generation (RAG) system needs efficient vector search against embedded content while maintaining enterprise-grade reliability. After evaluating several database options, SubgenAI chose Azure Database for PostgreSQL with pgvector for its accurate and scalable vector similarity search. Serenity Star customers can now:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Launch AI agents in as little as 15 minutes&lt;/LI&gt;
&lt;LI&gt;Cut coding and development time by 50%&lt;/LI&gt;
&lt;LI&gt;Resolve most AI agent queries in under 60 seconds &lt;A href="https://microsoft-my.sharepoint.com/personal/pyarabothu_microsoft_com/Documents/Microsoft%20Copilot%20Chat%20Files/Customer%20success%20stories%20for%20Azure%20Database%20for%20PostgreSQL%20e-book.PDF" target="_blank" rel="noopener"&gt;[&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;"With Microsoft and Azure Database for PostgreSQL we have total control and an environment that is truly dynamic and can adapt to the evolution we're looking for."&lt;/EM&gt; — Julia Schröder Langhaeuser, VP of Product Serenity Star, SubgenAI&lt;/P&gt;
&lt;P&gt;At the extreme end of scale, &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/supporting-chatgpt-on-postgresql-in-azure/4490247" target="_blank" rel="noopener"&gt;OpenAI&lt;/A&gt; runs PostgreSQL on Azure to support production systems behind ChatGPT. As write scalability limits emerged on an initially unsharded single primary instance, OpenAI offloaded write-heavy operations to other systems and optimized read workloads using PgBouncer for connection pooling. The Azure Database for PostgreSQL team responded by developing the elastic clusters feature, enabling horizontal scaling through row-based and schema-based sharding. The team reduced connection latency from approximately 50 ms to under 5 ms, scaled reads horizontally with multiple replicas, and improved reliability by prioritizing critical requests—all achieved by a small team making systematic optimizations on open-source PostgreSQL.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;"After all the optimization we did, we are super happy with Postgres right now for our read-heavy workloads. It's really scalable and reliable."&lt;/EM&gt; — Bohan Zhang, Member of the Technical Staff, OpenAI&lt;/P&gt;
&lt;H2&gt;Meeting You Where You Are&lt;/H2&gt;
&lt;P&gt;Beyond these stories, organizations like &lt;A href="https://www.microsoft.com/en/customers/story/19769-bmw-ag-azure-app-service" target="_blank" rel="noopener"&gt;BMW Group&lt;/A&gt; (cloud-native applications at global scale), &lt;A href="https://www.microsoft.com/en/customers/story/25672-ahold-delhaize-usa-azure" target="_blank" rel="noopener"&gt;Ahold Delhaize&amp;nbsp;&lt;/A&gt;(highly available retail applications),&amp;nbsp;&lt;A href="https://www.microsoft.com/en/customers/story/25658-mott-macdonald-azure" target="_blank" rel="noopener"&gt;Mott MacDonald&lt;/A&gt; (an AI agent accelerating onboarding and spreading best practices across 220,000 employees), and &lt;A href="https://techcommunity.microsoft.com/blog/azure-customer-innovation-blog/multitude-builds-resilient-banking-platform-with-postgresql-and-mysql-on-azure/4512470" target="_blank"&gt;Multitude &lt;/A&gt;(scaling responsibly in regulated environments) all run on Azure Database for PostgreSQL. The service offers 99.99% availability with automatic failover and SLA, independent compute and storage scaling, and intelligent performance recommendations, available across 60+ Azure regions. Developer tooling including the PostgreSQL extension for Visual Studio Code with GitHub Copilot further accelerates productivity.&lt;/P&gt;
&lt;P&gt;Whether you are planning your first migration or building production AI agents, these stories share a clear signal: Azure Database for PostgreSQL delivers a scalable, secure, AI-ready data foundation at every stage of growth.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Explore full customer stories in depth in the eBook: &lt;/STRONG&gt;&lt;A class="lia-external-url" href="https://cdn-dynmedia-1.microsoft.com/is/content/microsoftcorp/azure/acom/documents/pdfs/en-us/Customer-Evidence-For-Azure-Database-For-PostgreSQL-Ebook.pdf" target="_blank"&gt;Customer Success Stories with Azure Database for PostgreSQL&lt;/A&gt;&lt;STRONG&gt;.&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2026 17:34:35 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/real-world-success-stories-with-postgresql-on-azure/ba-p/4519862</guid>
      <dc:creator>Pooja_Y</dc:creator>
      <dc:date>2026-05-20T17:34:35Z</dc:date>
    </item>
    <item>
      <title>Native Database/Query Monitoring with Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/native-database-query-monitoring-with-azure-database-for/ba-p/4503346</link>
      <description>&lt;H2&gt;Monitoring PostgreSQL Database Engine&lt;/H2&gt;
&lt;P&gt;The PostgreSQL database engine provides multiple administrative views, which can be leveraged to capture metrics of activities inside of the database engine including, but not limited to, database activities, query activities, execution time, database resource locks etc for initial and deep analysis on database &amp;amp; query performance. Database Administrators should use these views and their corresponding metrics to perform initial level analysis. Critical insights can be gathered around database activity, performance and system activity for reactive and proactive analysis.&lt;/P&gt;
&lt;P&gt;In this blog, I am going to show the important administrative views and their corresponding SQL statements for capturing database and query details.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The following section provides details about the statistics views and their usage. It contains the most important and mostly used statistics views, there are other views available that can be used to get into further details.&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;NOTE&lt;/STRONG&gt;&lt;/U&gt;&lt;STRONG&gt;:&lt;/STRONG&gt; The queries and flows provided below are a few of the ways for each scenario. Eventually, the final approach will depend on and be dictated by the issue at hand or its symptoms.&lt;/P&gt;
&lt;H2&gt;Pre-requisites&lt;/H2&gt;
&lt;P&gt;The following parameters should be enabled in Azure Database for PostgreSQL “Server parameters” before using the statistics views:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;track_activities&lt;/LI&gt;
&lt;LI&gt;track_counts&lt;/LI&gt;
&lt;LI&gt;track_io_timing&lt;/LI&gt;
&lt;LI&gt;pg_stat_statements.track = ALL&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The following extensions should be installed before using the stats:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;create extension pg_stat_statements; create extension pgstattuple;&lt;/LI-CODE&gt;
&lt;P&gt;NOTE: All SQL queries mentioned below are as per PostgreSQL version 18.&lt;/P&gt;
&lt;H2&gt;Schema &amp;amp; Data for Analysis&lt;/H2&gt;
&lt;P&gt;All the "Example Scenario" mentioned in the analysis queries are based on the following schema and corresponding volumetrics:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 29.0738%; height: 94px; border-width: 1px;"&gt;&lt;colgroup&gt;&lt;col style="width: 50.0294%" /&gt;&lt;col style="width: 50.0294%" /&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr style="height: 34.6131px;"&gt;&lt;td style="height: 34.6131px;"&gt;&lt;STRONG&gt;Table Name&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.6131px;"&gt;&lt;STRONG&gt;No. of rows&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.6131px;"&gt;&lt;td style="height: 34.6131px;"&gt;customer&lt;/td&gt;&lt;td style="height: 34.6131px;"&gt;993,814&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.6131px;"&gt;&lt;td style="height: 34.6131px;"&gt;invoice&lt;/td&gt;&lt;td style="height: 34.6131px;"&gt;20,229,119&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.6131px;"&gt;&lt;td style="height: 34.6131px;"&gt;orders&lt;/td&gt;&lt;td style="height: 34.6131px;"&gt;4,497,292&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.6131px;"&gt;&lt;td style="height: 34.6131px;"&gt;product&lt;/td&gt;&lt;td style="height: 34.6131px;"&gt;2,818,000&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;Statistics Views and SQL Queries for Analysis&lt;/H2&gt;
&lt;P&gt;The following SQL statements can be used to perform 1&lt;SUP&gt;st&lt;/SUP&gt; level monitoring on the database, tables and queries. Note that the output counters and metrics from the SQL statements represent cumulative data since the last server restart. The statistics should be reset to zero before performing troubleshooting or performance tuning exercises. Use the below mentioned SQL statements to reset statistics at database, table and IO level.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Database level stats reset&amp;nbsp;
&lt;UL&gt;
&lt;LI&gt;&lt;LI-CODE lang="sql"&gt;SELECT pg_stat_reset();&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;IO level stats reset.
&lt;UL&gt;
&lt;LI&gt;&lt;LI-CODE lang="sql"&gt;SELECT pg_stat_reset_shared('io');&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;Reset pg_stat_statements metrics per user, query and database id or for the entire database - pg_stat_statements contain query level metrics for a database, user or a single query. We can reset the statistics at these individual levels. If any of the parameters are not specified, the default value 0 is used for each of them and the statistics that match with other parameters will be reset. "userid", "dbid" (Database ID), "queryid" &amp;nbsp;can be fetched from pg_roles (column - oid), pg_stat_database (column - datid) and pg_stat_activity (column - query_id) respectively.&amp;nbsp;
&lt;UL&gt;
&lt;LI&gt;&lt;LI-CODE lang="sql"&gt;SELECT pg_stat_statements_reset(userid, dbid, queryid);&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;LI-CODE lang="sql"&gt;SELECT pg_stat_statements_reset();&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;SQL Activity Monitoring:&lt;/H3&gt;
&lt;P&gt;This query uses pg_stat_activity statistics view, which contains details of current activities in the database server. It can be used to track queries in transactions, transaction execution time, wait event details if any etc. The WHERE clause can be used to filter activities based on client IP address (client_addr), application name (application_name), user (usename) who has submitted the query and text of the SQL statement.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT datname AS dbname, 
       pid, 
       usename as username, 
       application_name, 
       client_addr as client_ip_addr, 
       xact_start AS transaction_start_time, 
       query_start AS query_start_time, 
       wait_event_type AS db_waitign_on, 
       wait_event AS waiting_activity, 
       CAST(query AS varchar(100)) AS sql_query, 
       backend_type AS db_operation 
FROM pg_stat_activity 
WHERE &amp;lt;conditions&amp;gt;;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: This output should be used to find overall activity in your database.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;username, application_name, client_ip_addr - The user, application and client IP address from where the query is being executed.&lt;/LI&gt;
&lt;LI&gt;transaction_start_time - When transaction started (using BEGIN keyword or corresponding API).&lt;/LI&gt;
&lt;LI&gt;query_start_time - Start time of currently active query in the transaction.&lt;/LI&gt;
&lt;LI&gt;wait_event and wait_event_type columns output the events on which the query is waiting, if applicable. Refer to the official links for details on &lt;A href="https://www.postgresql.org/docs/current/monitoring-stats.html#WAIT-EVENT-TABLE" target="_blank"&gt;wait events&lt;/A&gt; and &lt;A href="https://www.postgresql.org/docs/current/monitoring-stats.html#WAIT-EVENT-ACTIVITY-TABLE" target="_blank"&gt;wait event types&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;db_operation - Type of database operation that is being performed by the application. E.g. autovacuum, parallel worker, client backend, etc.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario&lt;/STRONG&gt;: Application team is complaining about higher load in "retail_db" database and it is causing multiple SQL statements to run slow, team wants to know whether ad-hoc SQL statements are being run using "psql" client by application developers. As a DBA, you want to look at the entire database activity - no. of SQL statements, who are running to SQLs and which client are they coming from. Above mentioned SQL can be used with filters on "application_name" (value = "psql") and "dbname" (value = "retail_db"). It generates the following output:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Analysis:&lt;/STRONG&gt; From the above output, it can be seen that "psql" client is indeed getting used from a few IP addresses.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step: &lt;/STRONG&gt;pg_terminate_backend(&amp;lt;pid&amp;gt;) can be used to kill the applications with pid 22210, 22209 and 21993.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Similarly, the same SQL statement can be used to look at overall SQL activities in individual database.&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;SQL Statement Level monitoring&lt;/H3&gt;
&lt;P&gt;This is one of the most important SQL statements that describes operations at query level. It provides execution time detail of queries, read time, write time, disk read and disk write. Output of this query should serve as one of the starting point of query troubleshooting and query optimization.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT queryid , 
       CAST(query AS varchar(100)) AS sql_stmt, 
       calls AS no_of_executions, 
       total_exec_time, 
       min_exec_time, 
       max_exec_time, 
       mean_exec_time AS avg_exec_time, 
       rows AS rows_fetched, 
       shared_blks_hit AS blocks_read_from_buffer, 
       shared_blks_read AS blocks_read_from_disk, 
       shared_blks_written AS blks_written_to_disk, 
       shared_blk_read_time, 
       shared_blk_write_time 
FROM pg_stat_statements
WHERE query LIKE '%&amp;lt;sql-stmt&amp;gt;%';&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: Output of this query can be used to dive deeper into SQL performance issues.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;sql_stmt - Provides the SQL statement that is being run. This is the query that is being analyzed for tuning.&lt;/LI&gt;
&lt;LI&gt;no_of_executions - How many times this SQL statement has been executed so far (since the reset of pg_stat_statements).&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;total_exec_time - This is the execution time for the query combining all runs. e.g. if the query was run 10 times and each time took 1.5s, then total_exec_time would be 15s.&lt;/LI&gt;
&lt;LI&gt;min_exec_time - Min. time the query took to execute. This can be considered as the benchmark execution time for this query.&lt;/LI&gt;
&lt;LI&gt;max_exec_time - Max. time the query took to execute.&lt;/LI&gt;
&lt;LI&gt;avg_exec_time - Avg. execution time of the query. This time should fall within the query SLA.&lt;/LI&gt;
&lt;LI&gt;rows_fetched - No. of rows needed by application (SQL query)&lt;/LI&gt;
&lt;LI&gt;blocks_read_from_buffer &amp;amp; blocks_read_from_disk - Data blocks (8KB size) read from PostgreSQL shared memory and from disk respectively.&lt;/LI&gt;
&lt;LI&gt;shared_blk_read_time &amp;amp; shared_blk_write_time - Total time spent in reading from and writing to disk. This time is included in total_exec_time. If ratio of shared_blk_read_time or shared_blk_write_time or both with total_exec_time is higher, then IO is causing high execution time in this query. If the ratio is less then other complex SQL operations like join, order by, group by, functions etc. are taking longer to execute.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario&lt;/STRONG&gt;: We will be using the same SQL statement that was used in the example scenario of "3. Application-wise IO Activities". But in this case, using "SQL Statement Level monitoring" we will look at the execution details of the query rather than IO usage. Following is the output of first execution (after server restart - shared memory was empty) of the SQL statement&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Analysis:&lt;/STRONG&gt; Here is the observation, execution time of the query was 154.81 seconds. Total rows needed by application was 4,497,292 out of which 341 8KB blocks were read from shared memory (PostgreSQL bufferpool) and 58504 8KB blocks were read from disk.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Following is the output after 2nd execution (after resetting pg_stat_statements):&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Analysis: &lt;/STRONG&gt;The query was executed 4 times. Execution time got reduced to 95 seconds, but it is still high. Even though all rows (4497292 x 4) were read from shared memory (buffer pool) as blocks_read_from_disk was zero, execution time is very high.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step: &lt;/STRONG&gt;Even if the execution time is found to be within SLA, the query needs to be analyzed for its execution plan. Use EXPLAIN ANALYZE command to analyze the access plan or execution path of the query. Query optimization must be done for this SQL statement.&lt;/P&gt;
&lt;H3&gt;Table-level Bloat Statistics&lt;/H3&gt;
&lt;P&gt;PostgreSQL uses MVCC (Multi Version Concurrency Control) to avoid read and write conflicts, which means one application can read rows while they are being modified by another application. This is done by storing multiple versions of the same row. But over time older versions, which are not needed by applications, become overhead as they occupy space. This is known as "Bloating". It can cause both storage and performance issue. The query mentioned below provides bloating percentage on a table, which should be monitored on a regular basis and DBAs should decide on the autovaccuum settings.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT (table_len/1024/1024) AS table_size_mb, 
       tuple_count AS no_of_live_rows, 
       (tuple_len/1024/1024) AS live_row_size_mb, 
       dead_tuple_count AS no_of_dead_rows, 
       (dead_tuple_len/1024/1024) AS dead_row_size_mb, 
       tuple_percent AS live_rows_percent, 
       dead_tuple_percent AS dead_rows_percent, 
       free_percent AS free_space_percent, 
        (((table_len – tuple_len)/table_len)*100) AS bloat_percent 
FROM pgstattuple('&amp;lt;table-name&amp;gt;');&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;table_size_mb - This is the total table size, including bloating.&lt;/LI&gt;
&lt;LI&gt;no_of_live_rows - No. of actual usable rows in the table.&lt;/LI&gt;
&lt;LI&gt;live_row_size_mb - This is the actual size of the table. This is the amount of data in this table that can be used by applications.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;no_of_dead_rows - No. of irrelevant rows in the table.&lt;/LI&gt;
&lt;LI&gt;dead_row_size_mb - Size of irrelevant rows in the table. This is the amount of data that is not needed by any application, but is still there in the table and occupying storage. This is the data that has to be removed from the table.&lt;/LI&gt;
&lt;LI&gt;bloat_percent - Percentage of dead rows occupying the table. If it goes beyond 25-30%, manual VACUUM should be used to remove bloating.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario&lt;/STRONG&gt;: invoice_history table contains more than 20 M rows and has a size of 1630 MB. Deleting records from a table does not reduce the size in PostgreSQL because of MVCC support to keep multiple versions of the same row. The deleted rows still occupy storage space, it is known as bloating as shown below.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;"Table level Bloat Statistics" can be used to find the bloat percentage of a table.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step:&lt;/STRONG&gt; Aggressive AUTOVACUUM has to be configured to remove bloating on time. As AUTOVACUUM does not free up storage space, manual FULL VACUUM has to be executed to reclaim storage space. Note that full vacuum takes exclusive lock on tables. Bloat percentage changed after executing full vacuum.&lt;/P&gt;
&lt;img /&gt;
&lt;H3&gt;Table Bloat using Stat table&lt;/H3&gt;
&lt;P&gt;Table bloating information using statistics table.&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT schemaname, 
       relname AS tblname, 
       n_live_tup AS live_rows, 
       n_dead_tup AS dead_rows, 
       ((n_dead_tup - n_live_tup)/100) AS tbl_bloat_percent, 
       last_vacuum AS last_manual_vacuum, 
       last_autovacuum 
FROM pg_stat_all_tables 
WHERE relname = '&amp;lt;tblname&amp;gt;';&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: Same as "Table-level Bloat Statistics".&lt;/P&gt;
&lt;H3&gt;Database Activity Monitoring&lt;/H3&gt;
&lt;P&gt;This SQL statement provides row level counters of DML statements for a database.&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT datname AS dbname, 
       blks_read AS total_no_of_read_ops, 
       blks_hit AS no_of_blks_read_from_bufferpool, 
       tup_returned AS no_of_rows_scanned, 
       tup_fetched AS no_of_rows_fetched, 
       tup_inserted AS no_of_rows_inserted, 
       tup_updated AS no_of_rows_updated, 
       tup_deleted AS no_of_rows_deteled, 
       deadlocks AS no_of_deadlocks, 
       (blk_read_time/1000) AS blk_read_time_s, 
       (blk_write_time/1000) AS blk_write_time_s 
FROM pg_stat_database;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: Output shows the impact of DML operations in a database.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;total_no_of_read_ops - This is the total block read request executed by the database engine.&lt;/LI&gt;
&lt;LI&gt;no_of_blks_read_from_bufferpool - Out of total read requests, how many blocks were already there in memory or shared_mem.&lt;/LI&gt;
&lt;LI&gt;no_of_rows_scanned &amp;amp; no_of_rows_fetched - Total no. of rows read from the database and the total no. of rows actually needed by application. Higher difference in the two metrics should call for query tuning using better indexes, join strategies etc.&lt;/LI&gt;
&lt;LI&gt;blk_read_time_s &amp;amp; blk_read_write_s - Time taken in seconds, to perform read and write operations.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;no_of_deadlocks - Higher no. of deadlocks should be investigated. Execution of application SQL queries might have to be re-looked if higher deadlocks create performance or application issues.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Index-level Bloat Statistics – Live rows, dead rows, bloat&lt;/H3&gt;
&lt;P&gt;This is similar to query no. 8, but it provides bloating information at index level.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT (index_size/1024/1024) AS idx_size_mb, 
       (index_size/8192) AS index_pages, 
       empty_pages, 
       deleted_pages, 
       ((index_pages - deleted_pages)/index_pages) * 100 AS idx_bloat_percent 
FROM pgstatindex('&amp;lt;idx-name&amp;gt;');&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: The output is similar to table-level bloat statistics, but it is for indexes.&lt;/P&gt;
&lt;H3&gt;Monitor IO activities&lt;/H3&gt;
&lt;P&gt;Output of the following SQL statement shows the overall IO (Input/Output) activities for a database. It can be used to infer whether database workload is read heavy or write heavy. For read workloads, database level bufferpool_hit_ratio metrics can be used to increase or decrease shared memory configuration parameter.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT backend_type , 
       object, 
       context AS reason_for_io, 
       reads AS no_of_reads, 
       (read_bytes/1024) AS read_data_kb, 
       read_time AS read_time_ms, 
       writes AS no_of_writes, 
       (write_bytes/1024) AS write_data_kb, 
       write_time AS write_time_ms, 
       writebacks AS no_of_blocks_to_storage, 
       writeback_time AS block_to_storge_write_time_ms , 
       hits AS no_of_reads_from_bufferpool, 100 * (hits / (hits + reads)) AS bufferpool_hit_ratio 
FROM pg_stat_io;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: The output showcases database level IO metrics.&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;backend_type - Type of database operation that is being performed by the application. E.g. autovacuum, parallel worker, client backend, etc.&lt;/LI&gt;
&lt;LI&gt;reason_for_io - corresponding IO operation. Following are the possible output values to look out for.
&lt;UL&gt;
&lt;LI&gt;normal - Read from or write to shared buffers.&lt;/LI&gt;
&lt;LI&gt;vacuum - IO used by VACUUM operation.&lt;/LI&gt;
&lt;LI&gt;bulkread &amp;amp; bulkwrite - Disk read and write operations.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;no_of_reads - Total read operations.&lt;/LI&gt;
&lt;LI&gt;read_data_kb - Amount of data read (in KB) across all operations.&lt;/LI&gt;
&lt;LI&gt;no_of_writes - Total write operations.&lt;/LI&gt;
&lt;LI&gt;write_data_kb - Amount of data written (in KB) across all operations.&lt;/LI&gt;
&lt;LI&gt;read_time_ms &amp;amp; write_time_ms - Duration of all read &amp;amp; write operations.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario&lt;/STRONG&gt;: Extending the previous example, application team is complaining about overall performance of the database. As a DBA you want to find out the overall read and write operations to confirm whether it is causing slowness in the database. It will give an idea about how busy the database has been. "Monitor IO Activities" SQL can be used to find out the trigger of higher IO activities in the database. Following is the output:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Analysis:&lt;/STRONG&gt; Output above shows that most of the read and write operations are emanating from applications ("backend_type" = "client backend"). This gives an idea of database usage by the applications.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step: &lt;/STRONG&gt;If resource utilization of this database is high, we can create read replica to offload the reads and increase server memory and CPU to handle the load. Or else, if possible, application throttling can be infused by reducing the no. of max connections or using application level throttling.&lt;/P&gt;
&lt;OL start="3"&gt;
&lt;LI&gt;
&lt;H3&gt;Application-wise IO Activities&lt;/H3&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Query no. 2 above provides database level IO, the following SQL statement can be used to track application level IO summary. As there is to one-to-one mapping between application id in pg_stat_activity and pg_stat_io, backend_type is the only way to relate these two admin views.&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT psa.datname AS dbname, 
       pid, 
       psa.usename AS username, 
       psa.application_name, 
       psa.client_addr as client_ip_addr, 
       psa.xact_start AS transaction_start_time, 
       psa.query_start AS query_start_time, 
       psa.wait_event_type AS db_waitign_on, 
       psa.wait_event AS waiting_activity, 
       CAST(psa.query AS varchar(100)) AS sql_query, 
       state as current_state, 
       psa.backend_type AS db_operation, 
       psi.context AS reason_for_io, 
       psi.reads AS no_of_reads, 
       psi.writes AS no_of_writes 
FROM pg_stat_activity psa JOIN pg_stat_io psi ON psa.backend_type = psi.backend_type
WHERE psa.query LIKE '%&amp;lt;sql-stmt&amp;gt;%';&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;username, application_name and client_ip_addr column output can be used to track user who submitted the query, application from where the query was submitted and IP address of the application server from where query was executed.&lt;/LI&gt;
&lt;LI&gt;transaction_start_time &amp;amp; query_start_time show the execution start time of transaction and currently active query inside of the transaction. These metrics should be used to find the execution time of transaction and queries inside of the transaction.&lt;/LI&gt;
&lt;LI&gt;wait_event and wait_event_type columns output the events on which the query is waiting, if applicable. Refer to the official links for details on &lt;A class="lia-external-url" href="https://www.postgresql.org/docs/current/monitoring-stats.html#WAIT-EVENT-TABLE" target="_blank" rel="noopener"&gt;wait events&lt;/A&gt; and &lt;A class="lia-external-url" href="https://www.postgresql.org/docs/current/monitoring-stats.html#WAIT-EVENT-ACTIVITY-TABLE" target="_blank" rel="noopener"&gt;wait event types&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;reason_for_io column outputs corresponding IO operation. Following are the possible output values to look out for.
&lt;UL&gt;
&lt;LI&gt;normal - Read from or write to shared buffers.&lt;/LI&gt;
&lt;LI&gt;vacuum - IO used by VACUUM operation.&lt;/LI&gt;
&lt;LI&gt;bulkread &amp;amp; bulkwrite - Disk read and write operations.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;no_of_reads &amp;amp; no_of_writes - Total no. of read and write operations by the query.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario&lt;/STRONG&gt;: So far we have been looking at database-level activities. In most of the cases, we need to track application level activities like read, write operations, application elapsed time (how long the query is getting executed for). These are some of the critical information that DBA should use while troubleshooting query performance or application slowness issue. Whereas pg_stat_statements should be the go to place to look at SQL or application-level statistics, above SQL statement can be used to monitor application level IO operations.&lt;/P&gt;
&lt;P&gt;Executed SQL statement :&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT
    c.cust_id, 
    c.cust_email, 
    c.cust_type, 
    o.order_no, 
    o.order_date 
FROM customer c, orders o 
WHERE c.cust_id = o.cust_id 
ORDER BY o.order_date DESC;&lt;/LI-CODE&gt;
&lt;P&gt;Output of the query can be filtered using partial SQL statement in the WHERE clause or using PID of the SQL statement as shown below.&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Following is the output of the query above (showing only relevant columns):&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Analysis: &lt;/STRONG&gt;Highlighted output above shows 3 types of IO operations - normal, bulkwrite and bulkread. "normal" means that client is reading from buffer, but "bulkread" and "bulwrite" indicates read from disk and write to disk (temporary file write for sorting!).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step:&amp;nbsp;&lt;/STRONG&gt;SQL statement should to be analysed further for index usage, high disk read and write IO. EXPLAIN (with ANALYZE) statement can be used to understand query behaviour. Other monitoring SQL statements should be used to dig deeper into the execution details.&amp;nbsp;&lt;/P&gt;
&lt;OL start="5"&gt;
&lt;LI&gt;
&lt;H3&gt;Table &amp;amp; Index Operations&lt;/H3&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The following SQL statement can be used to capture table-level DML operations and its corresponding index read operations. Output of this query can be used to create index if sequential scans on a table is high, also, how an application is impacting the table rows using INSERT, UPDATE, DELETE statements.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT t.schemaname AS tabschema, 
       t.relname AS tabname, 
       t.seq_scan AS no_of_seq_scan, 
       t.seq_tup_read AS seq_scan_rows_read, 
       t.n_tup_ins AS rows_inserted, 
       t.n_tup_upd AS rows_updated, 
       t.n_tup_del AS rows_deleted, 
       t.n_live_tup AS total_active_rows, 
       t.n_dead_tup AS total_dead_rows, 
       i.schemaname AS idxschema, 
       i.indexrelname AS idxname, 
       i.idx_tup_read AS idx_rows_read, 
       i.idx_tup_fetch AS idx_rows_fetched 
FROM pg_stat_all_tables t JOIN pg_stat_all_indexes i 
ON t.relid = i.relid AND t.relname = i.relname ;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: It is almost similar to database activity monitoring except for the following columns.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;total_dead_rows - Total no. of rows that are not relevant for any transaction in PostgreSQL.&lt;/LI&gt;
&lt;LI&gt;total_active_rows - Total no. of actual rows in the table.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If the ratio of dead rows vs active rows is higher, it shows VACUUM is not working properly. It can be fixed by running manual vacuum or changing the configuration of AUTOVACUUM.&lt;/P&gt;
&lt;H3&gt;Table level Read IO&lt;/H3&gt;
&lt;P&gt;This SQL statement provides critical metrics on read operations for all or individual tables. heap_blks_read and heap_blks_hit should be used to find out the disk read vs memory read in tables. Higher disk read indicates memory crunch and can be a factor in deciding whether to increase shared memory size.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT schemaname AS tabschema, 
       relname AS tabname, 
       heap_blks_read AS no_of_tab_blks_read, 
       heap_blks_hit AS no_of_buffer_blks_read, 
       idx_blks_read AS no_of_idx_blks_read, 
       idx_blks_hit AS no_of_buffer_idx_blks_read 
FROM pg_statio_all_tables 
WHERE relname = '&amp;lt;table-name&amp;gt;';&lt;/LI-CODE&gt;
&lt;H3&gt;Lock Information&lt;/H3&gt;
&lt;P&gt;Data modification by applications or system commands locks rows and tables. Other application trying to modify the same row will get into waiting state thereby increasing the response time. Following SQL statement can be used to find out what type of locks is being held by applications on all or specific tables.&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT db.datname AS dbname, 
       tbl.relname AS tblname, 
       lck.pid, lck.locktype , 
       mode AS lock_mode, 
       CASE lck.granted 
          WHEN True THEN 'lock_held' 
          WHEN False THEN 'lock_waiting' 
          ELSE 'not_known' 
       END AS lock_status, 
       lck.waitstart AS lock_wait_start_time 
FROM pg_database db JOIN pg_locks lck ON lck.database = db.oid 
JOIN pg_class tbl ON lck.relation = tbl.oid 
WHERE tbl.relname NOT LIKE '%pg_%' 
AND tbl.relname = '&amp;lt;tablename&amp;gt;';&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: Output rows contain database name, table name, process id of the query and the following fields.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;locktype - Object of the lock. E.g. table, page, row (tuple) etc.&lt;/LI&gt;
&lt;LI&gt;lock_status - Whether the lock has been granted to this application or application is waiting for lock.&lt;/LI&gt;
&lt;LI&gt;lock_wait_start_time - If lock waiting state, then when the wait was started.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario:&lt;/STRONG&gt; Following SQL statement takes a lock on "orders" table as it is getting executed inside of a transaction which has not been either committed or rolled back. "Lock Information" SQL can be used to find out who is holding lock on a table as shown below:&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step:&lt;/STRONG&gt;&amp;nbsp;If lock needs to be released then the application with pid 15505 must be terminated using pg_terminate_backend(15505).&lt;/P&gt;
&lt;OL start="12"&gt;
&lt;LI&gt;
&lt;H3&gt;Who is Holding and who is Waiting for Locks&lt;/H3&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;If locks are being held long enough to block a critical application, it becomes imperative to terminate the application holding the lock. Following SQL statement provides information about applications waiting for locks and applications holding those locks so that necessary actions can be taken by DBA.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;WITH lock_holder AS 
(SELECT db.datname AS dbname, 
        tbl.relname AS tblname, 
        pid, 
        locktype , 
        mode AS lock_mode 
 FROM pg_database db JOIN pg_locks lck ON lck.database = db.oid 
 JOIN pg_class tbl ON lck.relation = tbl.oid 
 WHERE granted = true), 
lock_waiter AS 
(SELECT db.datname AS dbname, 
        tbl.relname AS tblname, 
        pid, 
        locktype , 
        mode AS lock_mode 
 FROM pg_database db JOIN pg_locks lck ON lck.database = db.oid 
 JOIN pg_class tbl ON lck.relation = tbl.oid) 
SELECT lh.pid AS pid_holding, 
       lh.locktype AS holding_lock_type, 
       lh.lock_mode AS holding_lock_mode, 
       lh.tblname AS holding_lock_table, 
       lw.pid AS pid_waiting, 
       lw.locktype AS waiting_lock_type, 
       lw.lock_mode AS waiting_lock_mode, 
       lw.tblname AS waiting_lock_table 
FROM lock_holder lh JOIN lock_waiter lw ON lh.tblname = lw.tblname 
WHERE lw.tblname='&amp;lt;tbl-name&amp;gt;';&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Interpreting output&lt;/STRONG&gt;: This is an extension of query 11 above. Following are the output columns:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;pid_holding - Application that is holding lock.&lt;/LI&gt;
&lt;LI&gt;holding_lock_type - Object (table, page, row) that has been locked.&lt;/LI&gt;
&lt;LI&gt;holding_lock_mode - Lock mode that is being held.&lt;/LI&gt;
&lt;LI&gt;holding_lock_table - Table that is being locked.&lt;/LI&gt;
&lt;LI&gt;pid_waiting - Application that is waiting for lock.&lt;/LI&gt;
&lt;LI&gt;waiting_lock_type - Object (table, page, row) that is waiting for lock.&lt;/LI&gt;
&lt;LI&gt;waiting_lock_mode - Lock mode that is needed.&lt;/LI&gt;
&lt;LI&gt;waiting_lock_table - Lock on table that is waiting.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example Scenario:&lt;/STRONG&gt; There can be scenarios where multiple applications can take write lock on the same rows at the same time. Depending on lock_timeout, one of the applications has to wait for that duration. Criticality of an application might dictate the terms of waiting on locks and DBAs have to terminate application holding the lock. Following is an application that is updating rows in a transaction, but has not released the lock.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;And following application has timed out because of lock wait.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Next Step:&amp;nbsp;&lt;/STRONG&gt;Using above query we can find out which application is waiting and who is holding lock on a table as shown below. Depending on priority one of the applications can be terminated by DBA.&lt;/P&gt;
&lt;img /&gt;
&lt;H2&gt;Diagnostic Flow:&lt;/H2&gt;
&lt;P&gt;The following chart can be used to decide which admin view to use and when. It also shows how Azure Monitor and PostgreSQL admin views work in tandem at any analysis scenarios.&lt;/P&gt;
&lt;img /&gt;
&lt;H2&gt;Summary:&lt;/H2&gt;
&lt;P&gt;PostgreSQL provides helpful administrative views that can be used by DBAs (Database Administrators) to perform initial level of analysis at engine side before looking at any infrastructure level issues. The initial analysis can be useful in relating infrastructure issues with database performance as well, if there is any.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2026 14:14:33 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/native-database-query-monitoring-with-azure-database-for/ba-p/4503346</guid>
      <dc:creator>soudey</dc:creator>
      <dc:date>2026-05-20T14:14:33Z</dc:date>
    </item>
    <item>
      <title>TLS Certificate Pinning and Best Practices in Azure Database for MySQL</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-for-mysql-blog/tls-certificate-pinning-and-best-practices-in-azure-database-for/ba-p/4521345</link>
      <description>&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;Transport Layer Security (TLS)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;encrypts&amp;nbsp;data in transit between client applications and the&amp;nbsp;server and&amp;nbsp;authenticates&amp;nbsp;the service endpoint&amp;nbsp;in&amp;nbsp;client-server authentication.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Azure Database&amp;nbsp;for MySQL&amp;nbsp;server certificates are issued by&amp;nbsp;well-known&amp;nbsp;trusted&amp;nbsp;public&amp;nbsp;Certificate Authorities&amp;nbsp;(CAs),&amp;nbsp;including&amp;nbsp;Microsoft-issued&amp;nbsp;certificates,&amp;nbsp;and&amp;nbsp;are&amp;nbsp;validated&amp;nbsp;by clients during the TLS handshake.&amp;nbsp;Customers do not manage certificates on the server side.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/security/fundamentals/certificate-pinning" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;&lt;STRONG&gt;Certificate pinning&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;is&amp;nbsp;a&amp;nbsp;client-side&amp;nbsp;security technique where an application restricts trust to a specific certificate,&amp;nbsp;for example&amp;nbsp;by&amp;nbsp;thumbprint, public key, or CA,&amp;nbsp;rather than relying solely on the default OS or platform trust store. The trust store&amp;nbsp;contains&amp;nbsp;pre-installed root&amp;nbsp;CAs and may also include&amp;nbsp;additional&amp;nbsp;certificates configured by the client. During standard TLS validation, the client will trust any server certificate that chains to one of those root&amp;nbsp;CAs.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Why detecting TLS certificate pinning is not possible by design&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;Certificate pinning is entirely&amp;nbsp;client-side&amp;nbsp;logic&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&amp;nbsp;The server has no visibility into whether pinning is configured on the&amp;nbsp;client.&amp;nbsp;From the server’s&amp;nbsp;perspective,&amp;nbsp;the client either completes the TLS handshake or aborts it. The server never sees:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Which certificate(s) the client trusts&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Whether the client is comparing&amp;nbsp;root CA,&amp;nbsp;intermediate CA,&amp;nbsp;leaf&amp;nbsp;certificate&amp;nbsp;or SPKI hash&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Whether the trust decision was static or dynamic&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;What&amp;nbsp;the server&amp;nbsp;can see is&amp;nbsp;TLS handshake failure patterns,&amp;nbsp;TLS protocol, and&amp;nbsp;cipher negotiation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Why certificate pinning is risky&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;While certificate pinning was historically used to reduce the risk of man-in-the-middle attacks, it introduces significant operational fragility in cloud environments, particularly during certificate rotations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Server certificates and certificate authorities (CAs) must be rotated periodically to&amp;nbsp;maintain&amp;nbsp;security and compliance. In Azure Database for MySQL,&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;when certificate pinning is used&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt;, clients bind trust to a specific certificate or CA. As a result,&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;any change to the server certificate chain — including CA updates — can cause connection failures&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt;, even when the new certificates are fully valid and secure.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;One of the most common complications during certificate rotations is certificate pinning.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Recommended TLS certificate trust model for Azure Database for &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;MySQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:360,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:279}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Instead of pinning, adopt a CA&lt;/SPAN&gt;‑&lt;SPAN data-contrast="none"&gt;based&amp;nbsp;trust model that allows certificates to change safely.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Trust root CAs, not individual certificates.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Configure clients to use standard TLS validation against Azure-documented root CAs, rather than restricting trust to specific certificates or a narrowly scoped set of certificate authorities. Avoid configurations that effectively implement certificate pinning—such as trusting only a single certificate, public key, or limited CA set—unless explicitly&amp;nbsp;required.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233118&amp;quot;:false,&amp;quot;335559739&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Maintain a flexible and up-to-date trust store&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Clients rely on a trust store, key store, or equivalent certificate bundle to&amp;nbsp;validate&amp;nbsp;server certificates during TLS negotiation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Include the&amp;nbsp;appropriate root&amp;nbsp;and intermediate certificate authorities (CAs)&amp;nbsp;required&amp;nbsp;to&amp;nbsp;validate&amp;nbsp;the server certificate chain&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Ensure that trust stores are periodically reviewed and updated in line with provider guidance and announced certificate authority changes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;For the current TLS certificates visit the&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/mysql/flexible-server/security-tls" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure Database for MySQL documentation&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233118&amp;quot;:false,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559739&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Use certificate validation modes that rely on standard CA-based trust rather than pinning&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;For&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;MySQL client&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;configurations, prefer:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;ssl-mode=VERIFY_CA&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Validates the server certificate chain against trusted&amp;nbsp;CAs&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;ssl-mode=VERIFY_IDENTITY&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Validates CA&amp;nbsp;and&amp;nbsp;hostname (like PostgreSQL verify-full)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;These modes ensure that clients&amp;nbsp;validate&amp;nbsp;the&amp;nbsp;server&amp;nbsp;certificate chain against trusted&amp;nbsp;CAs, and in stricter modes, verify hostname identity. They do not imply certificate pinning by themselves. They rely on standard CA-based trust.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:279}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Configurations only become rigid when trust is narrowly restricted,&amp;nbsp;such&amp;nbsp;as to&amp;nbsp;a single certificate or limited CA set,&amp;nbsp;often through custom or overly constrained trust stores. This effectively introduces certificate pinning.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;When properly configured, these modes authenticate the service endpoint and protect against spoofing, while&amp;nbsp;remaining&amp;nbsp;resilient to certificate rotations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233118&amp;quot;:false,&amp;quot;335559739&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Maintain a combined CA during certificate rotations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:279}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Azure may rotate root or intermediate&amp;nbsp;CAs&amp;nbsp;over time.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;When Azure announces a CA&amp;nbsp;rotation:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Add&amp;nbsp;the&amp;nbsp;new root&amp;nbsp;and intermediate CAs&amp;nbsp;to&amp;nbsp;the client&amp;nbsp;trust store before the rotation&amp;nbsp;begins&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Retain&amp;nbsp;existing root&amp;nbsp;or intermediate&amp;nbsp;CAs&amp;nbsp;until the transition is&amp;nbsp;fully&amp;nbsp;complete&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Avoid removing older&amp;nbsp;certificates&amp;nbsp;prematurely&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;This combined CA approach, using both the current and upcoming certificate authorities during the transition window, allows clients to continue&amp;nbsp;validating&amp;nbsp;the&amp;nbsp;server&amp;nbsp;certificate chain without interruption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;As you review your current client configurations, ensure your applications rely on CA-based trust, avoid overly restrictive certificate configurations such as certificate pinning, and are prepared to handle routine certificate rotations without disruption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For a deeper dive, see the full article:&amp;nbsp;&lt;SPAN data-ccp-props="{}"&gt;&lt;A href="https://techcommunity.microsoft.com/blog/coreinfrastructureandsecurityblog/tls-certificate-pinning-and-best-practices-in-azure-open-source-relational-datab/4519531" target="_blank" rel="noopener"&gt;TLS Certificate Pinning in PostgreSQL and MySQL: Risks, Rotations, and Best Practices.&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;Stay Connected&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;We welcome your feedback and invite you to share your experiences or suggestions at&amp;nbsp;&lt;A href="mailto:AskAzureDBforMySQL@service.microsoft.com" target="_blank" rel="noopener"&gt;AskAzureDBforMySQL@service.microsoft.com&lt;/A&gt; &amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you for choosing Azure Database for MySQL!&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 20 May 2026 13:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-for-mysql-blog/tls-certificate-pinning-and-best-practices-in-azure-database-for/ba-p/4521345</guid>
      <dc:creator>TameikaL</dc:creator>
      <dc:date>2026-05-20T13:00:00Z</dc:date>
    </item>
    <item>
      <title>Know before you go: Azure Managed Redis at Microsoft Build 2026</title>
      <link>https://techcommunity.microsoft.com/t5/azure-managed-redis/know-before-you-go-azure-managed-redis-at-microsoft-build-2026/ba-p/4520874</link>
      <description>&lt;P&gt;&lt;A href="https://build.microsoft.com/en-US/home" target="_blank" rel="noopener"&gt;Microsoft Build 2026 is almost here&lt;/A&gt;, and this year’s event boasts a new format, as well as a deeper technical focus across key themes such as AI agents, cloud-native applications, data platforms, developer tooling, and intelligent infrastructure. The updates showcased at Build signal where Microsoft is investing next—and how customers can start preparing now.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;Whether you’re joining in person or online, this is your opportunity to see how Azure is shaping the next generation of AI-powered applications—and where &lt;A href="https://azure.microsoft.com/en-us/products/managed-redis" target="_blank" rel="noopener"&gt;Azure Managed Redis&lt;/A&gt; fits into that future.&lt;/P&gt;
&lt;P&gt;In this post, we’ll cover everything you need to know to prepare, including what Build is (and how to participate), as well as where you can find Azure Managed Redis across sessions, demos, and the in-person expo experience.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Where to find Azure Managed Redis at Build&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Azure Managed Redis’s presence at Build 2026 spans a mix of on-demand digital and in-person experiences, ranging from technical deep dives to open ended developer conversations. No matter your stage of development, Microsoft has you covered.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Lightning talk&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Stop by our lightning talk for fast, focused 15-minute sessions designed to give you an early look at what’s new. These in-person discussions spotlight emerging capabilities and real-world scenarios, offering a quick way to understand where the platform is evolving next.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A href="https://build.microsoft.com/en-US/sessions?search=redis&amp;amp;sortBy=relevance" target="_blank" rel="noopener"&gt;LTG41 | Faster and smarter agents with Redis and Foundry&lt;/A&gt;&lt;/STRONG&gt;&lt;BR /&gt;📅 Wednesday, June 3&lt;BR /&gt;🕛 4:20 PM – 4:35 PM PDT&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The Azure Managed Redis &lt;STRONG&gt;L&lt;/STRONG&gt;&lt;STRONG&gt;ightning Talk&lt;/STRONG&gt; will focus on:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;How Azure Managed Redis and Microsoft Foundry help developers build more effective AI agents&lt;/LI&gt;
&lt;LI&gt;High-performance in-memory data patterns for powering agent memory and context&lt;/LI&gt;
&lt;LI&gt;Vector search and semantic caching to reduce latency, lower cost, and return more relevant responses&lt;/LI&gt;
&lt;LI&gt;Practical approaches for RAG, persistent memory, and event-driven agent workflows&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This session is ideal for anyone looking to understand how Redis can serve as the data and memory layer for production-ready AI agents—helping deliver the right context in milliseconds and enabling richer, real-time reasoning.&lt;/P&gt;
&lt;P&gt;Expect to see a preview of upcoming investments across performance, developer experience, and AI-powered workflows. These sessions are ideal if you want a concise view of what’s changing and what it enables—before diving deeper into the full roadmap.&lt;/P&gt;
&lt;P&gt;➡️ &lt;STRONG&gt;Tip:&lt;/STRONG&gt; Lightning talks are &lt;EM&gt;in-person only and not available on demand&lt;/EM&gt;—plan to attend live.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;On-demand session&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;If you prefer to explore at your own pace, our on-demand sessions provide deeper walkthroughs of key updates and product capabilities. You’ll find detailed demos, scenario-based guidance, and technical insights that help you translate new features into real-world value.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;OD823 | Faster AI Responses with Semantic Caching in Azure Managed Redis&lt;/STRONG&gt; on-demand session will cover:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Building AI agents with Azure Managed Redis and Microsoft Foundry&lt;/LI&gt;
&lt;LI&gt;Real-time memory and context for agent workflows&lt;/LI&gt;
&lt;LI&gt;Vector search, semantic caching, and agent memory&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This session is ideal for:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Developers building copilots or autonomous agents&lt;/LI&gt;
&lt;LI&gt;Architects designing large scale LLM chatbots&lt;/LI&gt;
&lt;LI&gt;Teams modernizing applications for AI&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;➡️ &lt;STRONG&gt;Tip:&lt;/STRONG&gt; Sessions are designed to help you move from awareness to action, with a clearer understanding of how to apply what’s coming next&lt;STRONG&gt;&lt;EM&gt;. &lt;/EM&gt;&lt;/STRONG&gt;&lt;EM&gt;On-demand session will be available on Build Day 1&lt;/EM&gt;, so &lt;STRONG&gt;keep an eye out for our Azure Managed Redis Build 2026 announcements blog for the on-demand session link and access details.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Booth and expo presence&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Visit us on-site to connect directly with product experts, see live demos, and explore real customer scenarios in action. Build’s interactive spaces are designed for hands-on engagement, giving you the opportunity to ask questions, test capabilities, and get guidance tailored to your environment.&lt;/P&gt;
&lt;P&gt;Azure Managed Redis will be represented within a &lt;STRONG&gt;shared Azure Data / NoSQL booth experience&lt;/STRONG&gt;, showcasing:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Real-time AI application scenarios&lt;/LI&gt;
&lt;LI&gt;Vector search and semantic caching demos&lt;/LI&gt;
&lt;LI&gt;Integration with Azure AI Foundry and agent frameworks&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;At the booth, you’ll get an early look at upcoming enhancements and how they fit into the broader Azure ecosystem. From performance improvements to new integrations and AI-driven experiences, you’ll leave with a clearer picture of how the product is evolving—and how to take advantage of it.&lt;/P&gt;
&lt;P&gt;➡️ &lt;STRONG&gt;Tip:&lt;/STRONG&gt;&amp;nbsp; Expect a &lt;STRONG&gt;cross-product narrative&lt;/STRONG&gt; aligned with Azure Data + AI platform positioning.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What to expect at Build 2026&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Microsoft Build 2026 is the company’s flagship developer conference, bringing together engineers, architects, and technical leaders for two days of hands-on sessions, product announcements, and deep technical engagement.&lt;/P&gt;
&lt;P&gt;This year’s event is focused on real code, real systems, and practical AI development, with a strong emphasis on how developers can build, deploy, and scale intelligent applications using Azure and the broader Microsoft platform.&lt;/P&gt;
&lt;P&gt;Across keynotes, breakout sessions, demos, and labs, attendees will get early access to the next wave of platform capabilities—from advancements in AI agents and model deployment to updates across cloud infrastructure and developer tooling.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;How to prepare&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Register for &lt;A href="https://build.microsoft.com/en-US/home" target="_blank" rel="noopener"&gt;Microsoft Build 2026&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Browse the &lt;A href="https://build.microsoft.com/en-US/sessions" target="_blank" rel="noopener"&gt;Session Catalog&lt;/A&gt; and start building your agenda&lt;/LI&gt;
&lt;LI&gt;Bookmark the &lt;A href="https://build.microsoft.com/en-US/sessions?search=redis&amp;amp;sortBy=relevance" target="_blank" rel="noopener"&gt;Azure Managed Redis Lightning Talk (LTG41)&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Attend the &lt;A href="https://build.microsoft.com/en-US/sessions/KEY01?source=sessions" target="_blank" rel="noopener"&gt;Microsoft Build opening keynote&lt;/A&gt; to hear from CEO Satya Nadella and Microsoft leaders on how Microsoft is creating new opportunities for developers across its platforms in the era of AI&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Stay tuned for the On-Demand Session Catalog going live on Build Day 1&lt;/STRONG&gt;, where you can explore Azure Data &amp;amp; AI sessions focused on AI agents, data platforms, and intelligent applications&lt;/LI&gt;
&lt;LI&gt;Visit the Expert Meetup area to connect with Microsoft engineers and product teams&lt;/LI&gt;
&lt;LI&gt;Follow along with &lt;A href="https://techcommunity.microsoft.com/category/azuredatabases/blog/azure-managed-redis" target="_blank" rel="noopener"&gt;Azure Managed Redis on Microsoft Tech Community&lt;/A&gt;, as well as Microsoft social channels (&lt;A href="https://www.linkedin.com/company/microsoft/posts/?feedView=all" target="_blank" rel="noopener"&gt;LinkedIn&lt;/A&gt;, &lt;A href="https://x.com/Microsoft" target="_blank" rel="noopener"&gt;X&lt;/A&gt;) for additional key announcements and real-time updates&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;We look forward to meeting you there!&lt;/P&gt;</description>
      <pubDate>Fri, 29 May 2026 19:49:14 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-managed-redis/know-before-you-go-azure-managed-redis-at-microsoft-build-2026/ba-p/4520874</guid>
      <dc:creator>Matthew_Burrows</dc:creator>
      <dc:date>2026-05-29T19:49:14Z</dc:date>
    </item>
    <item>
      <title>Ultimate Guide to POSETTE: An Event for Postgres, 2026 edition</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ultimate-guide-to-posette-an-event-for-postgres-2026-edition/ba-p/4520246</link>
      <description>&lt;P style="margin-bottom: 1.5em;"&gt;&lt;A href="https://posetteconf.com/2026/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/"&gt;POSETTE: An Event for Postgres 2026&lt;/A&gt; is back for its 5th year: free, virtual, and unapologetically all about Postgres. No travel budget required and no jet lag involved. Just your laptop, a decent internet connection, and curiosity.&lt;/P&gt;
&lt;P&gt;This year the &lt;A href="https://posetteconf.com/2026/schedule/" target="_blank" rel="noopener"&gt;POSETTE 2026 schedule&lt;/A&gt; has 4 livestreams (16-18 June) with 44 talks at ~25 minutes each—covering everything from query performance and partitioning to Postgres 19 features, extensions, and use cases. Which is awesome but also a bit of work to figure out which talks are for you. Hence this ultimate guide post. Every talk will land on YouTube afterward (un-gated, of course) so if you miss anything you care about, you can watch it later.&lt;/P&gt;
&lt;P&gt;But if you can catch a livestream in June, do it. That’s when the “virtual hallway track” happens on Discord—where you can ask the &lt;A href="https://posetteconf.com/2026/speakers/" target="_blank" rel="noopener"&gt;POSETTE speakers&lt;/A&gt; questions and compare notes with other attendees. Meeting other attendees who have the same weird Postgres problems you do can be reassuring somehow. And yes, there will be swag.&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;This guide is your cheat sheet: I’ve categorized and tagged all 44 talks so you don’t have to read 44 abstracts back-to-back. In this post you'll get:&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-by-the-numbers" target="_blank" rel="noopener" data-href="#by-the-numbers" data-lia-auto-title="A “by the numbers” summary" data-lia-auto-title-active="0"&gt;“By the numbers” summary&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-map" target="_blank" rel="noopener" data-lia-auto-title="Map of the 44 talks" data-lia-auto-title-active="0"&gt;Map of the 44 talks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-keynotes" target="_blank" rel="noopener" data-href="#keynotes" data-lia-auto-title="2 Keynote sessions" data-lia-auto-title-active="0"&gt;2 Keynote sessions&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-postgres-core" target="_blank" rel="noopener" data-href="#postgres-core" data-lia-auto-title="23 Postgres core talks" data-lia-auto-title-active="0"&gt;23 Postgres core talks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-postgres-ecosystem" target="_blank" rel="noopener" data-href="#postgres-ecosystem" data-lia-auto-title="11 Postgres ecosystem talks" data-lia-auto-title-active="0"&gt;11 Postgres ecosystem talks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-azure" target="_blank" rel="noopener" data-href="#azure" data-lia-auto-title="8 Azure Database talks" data-lia-auto-title-active="0"&gt;8 Azure Database talks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-discord" target="_blank" rel="noopener" data-href="#discord" data-lia-auto-title="Why participate on the virtual hallway track on Discord" data-lia-auto-title-active="0"&gt;Why participate on the virtual hallway track on Discord&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-speakers" target="_blank" rel="noopener" data-href="#speakers" data-lia-auto-title="A big thank you to our amazing speakers" data-lia-auto-title-active="0"&gt;A big thank you to our amazing speakers&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-join-us" target="_blank" rel="noopener" data-href="#join-us" data-lia-auto-title="Join us for POSETTE 2026 &amp;amp; mark your calendars" data-lia-auto-title-active="0"&gt;Join us for POSETTE 2026 &amp;amp; mark your calendars&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-trailer" target="_blank" rel="noopener" data-href="#trailer" data-lia-auto-title="Official POSETTE 2026 Trailer" data-lia-auto-title-active="0"&gt;Official POSETTE 2026 Trailer&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-by-the-numbers" class="lia-anchor"&gt;&lt;/a&gt;“By the numbers” summary for POSETTE 2026&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;Here’s a quick snapshot of what you need to know about POSETTE this year:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 83.2361%; height: 858.8px; border-width: 1px;"&gt;&lt;colgroup&gt;&lt;col style="width: 32.6871%" /&gt;&lt;col style="width: 67.2138%" /&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;3 days&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;16-18 June 2026&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 58.8px;"&gt;&lt;td class="lia-align-right" style="height: 58.8px;"&gt;&lt;STRONG&gt;4 livestreams&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 58.8px;"&gt;In Americas &amp;amp; EMEA time zones&lt;BR /&gt;but of course you can watch from anywhere&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;44 talks&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;All free, all virtual&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 82.8px;"&gt;&lt;td class="lia-align-right" style="height: 82.8px;"&gt;&lt;STRONG&gt;2 invited keynotes&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 82.8px;"&gt;Driving Postgres forward at Microsoft (Livestream 1), and&amp;nbsp;Postgres 19 Hackers Panel: What’s In, What’s Out, &amp;amp; What’s Next (Livestream 2)&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;25 minutes&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;&amp;nbsp;Average length per talk&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;~1100 minutes&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;Total minutes in POSETTE 2026 talks&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 82.8px;"&gt;&lt;td class="lia-align-right" style="height: 82.8px;"&gt;&lt;STRONG&gt;50 speakers&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 82.8px;"&gt;POSETTE 2026 speakers include PostgreSQL hackers and contributors, users, application developers, PG community members, Azure engineers, &amp;amp; Azure customers&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 82.8px;"&gt;&lt;td class="lia-align-right" style="height: 82.8px;"&gt;&lt;STRONG&gt;6 keynote speakers&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 82.8px;"&gt;Affan Dar &amp;amp; Charles Feddersen (Livestream 1); and&amp;nbsp;Álvaro Herrera, Heikki Linnakangas, Melanie Plageman, &amp;amp; Thomas Munro (Livestream 2)&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;19 countries&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;Speakers reside in 19 different countries&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 34.8px;"&gt;&lt;td class="lia-align-right" style="height: 34.8px;"&gt;&lt;STRONG&gt;23 companies&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 34.8px;"&gt;&amp;nbsp;Speakers hail from 23 different companies&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td class="lia-align-right" style="height: 38.8px;"&gt;
&lt;P&gt;&lt;STRONG&gt;17.6% CFP acceptance rate&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;&amp;nbsp;42 talks selected from 238 submisssions&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 58.8px;"&gt;&lt;td class="lia-align-right" style="height: 58.8px;"&gt;
&lt;P&gt;&lt;STRONG&gt;75% general Postgres talks&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 58.8px;"&gt;33 talks are not cloud-specific at all, they’re about the Postgres technology &amp;amp; ecosystem&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 58.8px;"&gt;&lt;td class="lia-align-right" style="height: 58.8px;"&gt;
&lt;P&gt;&lt;STRONG&gt;25% Azure-related talks&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 58.8px;"&gt;11 of 44 talks feature Azure Database for PostgreSQL or Azure HorizonDB&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 58.8px;"&gt;&lt;td class="lia-align-right" style="height: 58.8px;"&gt;&lt;STRONG&gt;1 organizing company&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 58.8px;"&gt;Organized by the Postgres team at Microsoft, in partnership with AMD&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 92.8px;"&gt;&lt;td class="lia-align-right" style="height: 92.8px;"&gt;&lt;STRONG&gt;17 languages&amp;nbsp;&lt;/STRONG&gt;&lt;/td&gt;&lt;td style="height: 92.8px;"&gt;Published talk videos will have captions available in 17 languages, including English, Czech, Dutch, French, German, Hindi, Italian, Japanese, Korean, Polish, Portuguese, Russian, Spanish, Turkish, Ukrainian, and Chinese Simplified &amp;amp; Chinese Traditional&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;H2 class="lia-linked-item" style="margin-bottom: 1.5em;"&gt;&lt;a id="community--1-map" class="lia-anchor"&gt;&lt;/a&gt;Map of the 44 talks&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;To help you quickly navigate all 44 talks, here’s a map of the high-level categories and detailed topics.&lt;/P&gt;
&lt;img&gt;&lt;STRONG&gt;Figure 1&lt;/STRONG&gt;: A map of the POSETTE 2026 talks—high-level categories and detailed tags to help you find what you care about&lt;/img&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-keynotes" class="lia-anchor"&gt;&lt;/a&gt;2 Keynote sessions&lt;/H2&gt;
&lt;P&gt;Affan Dar and Charles Feddersen lead the PostgreSQL engineering and product teams at Microsoft, In this keynote, they’ll walk through how Microsoft is contributing to Postgres, both upstream in the open source project and in the cloud database service they build on top of it.&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/driving-postgres-forward-at-microsoft/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/driving-postgres-forward-at-microsoft/"&gt;Driving Postgres forward at Microsoft&lt;/A&gt;, by Affan Dar &amp;amp; Charles Feddersen &lt;SMALL style="color: #767676;"&gt;(Azure Database for PostgreSQL, Azure HorizonDB, VS Code, Dev tools, community, Postgres hacking, open source, PosetteConf, livestream-1)&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Want to understand how Postgres features get decided? This keynote panel with 4 PostgreSQL committers &amp;amp; hackers will peel back the curtain. You’ll hear what made it into Postgres 19, what didn’t (and why), and get a sneak peek into a few of the things in the oven for Postgres 20.&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgres-19-hackers-panel-what-s-in-what-s-out-what-s-next/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgres-19-hackers-panel-what-s-in-what-s-out-what-s-next/"&gt;Postgres 19 Hackers Panel: What’s In, What’s Out, &amp;amp; What’s Next&lt;/A&gt;, by Álvaro Herrera, Heikki Linnakangas, Melanie Plageman, &amp;amp; Thomas Munro &lt;SMALL style="color: #767676;"&gt;(Postgres 19, Postgres hacking, panel, open source, collaboration, multithreading, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-postgres-core" class="lia-anchor"&gt;&lt;/a&gt;23 Postgres core talks&lt;/H2&gt;
&lt;H3&gt;Data Modeling&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/json-in-postgresql-evil-data-type-or-just-needs-to-be-tamed/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/json-in-postgresql-evil-data-type-or-just-needs-to-be-tamed/"&gt;JSON in PostgreSQL - evil data type or just needs to be tamed?&lt;/A&gt;, by Boriss Mejias &lt;SMALL style="color: #767676;"&gt;(JSON, performance, data modeling, livestream-1)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-design-patterns/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-design-patterns/"&gt;PostgreSQL Design Patterns&lt;/A&gt;, by Chris Ellis &lt;SMALL style="color: #767676;"&gt;(data modeling, SQL, PG use cases, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Graph Data&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/exploring-property-graphs-with-sql-pgq-in-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/exploring-property-graphs-with-sql-pgq-in-postgresql/"&gt;Exploring property graphs with SQL/PGQ in PostgreSQL&lt;/A&gt;, by Ashutosh Bapat &lt;SMALL style="color: #767676;"&gt;(SQL/PGQ, graph data, data modeling, Postgres 19, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;LISTEN/NOTIFY&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/listen-carefully-how-notify-can-trip-up-your-database/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/listen-carefully-how-notify-can-trip-up-your-database/"&gt;LISTEN Carefully: How NOTIFY Can Trip Up Your Database&lt;/A&gt;, by Jimmy Angelakos &lt;SMALL style="color: #767676;"&gt;(LISTEN/NOTIFY, PG use cases, triggers, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Performance&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/maintaining-large-tables-in-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/maintaining-large-tables-in-postgresql/"&gt;Maintaining Large Tables in PostgreSQL&lt;/A&gt;, by Sarat Balijepalli &lt;SMALL style="color: #767676;"&gt;(WAL, performance, scaling Postgres, vacuum, autovacuum, statistics, partitioning, monitoring, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/my-postgres-partitioning-cookbook/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/my-postgres-partitioning-cookbook/"&gt;My Postgres partitioning cookbook&lt;/A&gt;, by Derk van Veen &lt;SMALL style="color: #767676;"&gt;(partitioning, PG use cases, data modeling, performance, livestream-4)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-17-vs-18-side-by-side-performance-wins-in-real-world-queries/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-17-vs-18-side-by-side-performance-wins-in-real-world-queries/"&gt;PostgreSQL 17 vs 18: Side‑by‑Side Performance Wins in Real‑World Queries&lt;/A&gt;, by Divya Bhargov &lt;SMALL style="color: #767676;"&gt;(performance, PG use cases, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/vacuuming-enhancements-in-postgresql-18-faster-smarter-more-predictable/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/vacuuming-enhancements-in-postgresql-18-faster-smarter-more-predictable/"&gt;Vacuuming Enhancements in PostgreSQL 18: Faster, Smarter, More Predictable&lt;/A&gt;, by Shashikant Shakya &lt;SMALL style="color: #767676;"&gt;(vacuum, async IO, monitoring, performance, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;PG Internals&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/linux-and-postgresql-in-the-multiverse-of-connections/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/linux-and-postgresql-in-the-multiverse-of-connections/"&gt;Linux and PostgreSQL in the Multiverse of Connections&lt;/A&gt;, by Josef Machytka &lt;SMALL style="color: #767676;"&gt;(Linux, PG internals, connection pooling, livestream-2)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/pg_stats-how-postgres-internal-stats-work/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/pg_stats-how-postgres-internal-stats-work/"&gt;pg_stats: How Postgres Internal Stats Work&lt;/A&gt;, by Richard Yen &lt;SMALL style="color: #767676;"&gt;(statistics, pg_stats, PG internals, query planner, livestream-2)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgres-isn-t-slow-your-storage-is/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgres-isn-t-slow-your-storage-is/"&gt;Postgres isn’t slow, your storage is&lt;/A&gt;, by Sai Srirampur &lt;SMALL style="color: #767676;"&gt;(storage, IO, performance, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-queues-done-right-with-pgq/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-queues-done-right-with-pgq/"&gt;PostgreSQL queues done right with PgQ&lt;/A&gt;, by Alexander Kukushkin &lt;SMALL style="color: #767676;"&gt;(queues, PG internals, extensions, livestream-2)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/random_page_cost-in-postgres-why-the-default-is-4-0-and-should-you-lower-it/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/random_page_cost-in-postgres-why-the-default-is-4-0-and-should-you-lower-it/"&gt;random_page_cost in Postgres - why the default is 4.0 and should you lower it?&lt;/A&gt;, by Tomas Vondra &lt;SMALL style="color: #767676;"&gt;(PG internals, IO, performance, livestream-1)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/the-wonderful-world-of-wal/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/the-wonderful-world-of-wal/"&gt;The Wonderful World of WAL&lt;/A&gt;, by Bruce Momjian &lt;SMALL style="color: #767676;"&gt;(WAL, PG internals, replication, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/what-s-new-with-constraints-in-postgres-18/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/what-s-new-with-constraints-in-postgres-18/"&gt;What's new with constraints in Postgres 18&lt;/A&gt;, by Gülçin Yıldırım Jelínek &lt;SMALL style="color: #767676;"&gt;(constraints, data modeling, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Postgres Hacking&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/fuzzing-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/fuzzing-postgresql/"&gt;Fuzzing PostgreSQL&lt;/A&gt;, by Adam Wolk &lt;SMALL style="color: #767676;"&gt;(PG internals, testing, Dev tools, libpq, security, livestream-1)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/journey-of-developing-a-performance-optimization-feature-in-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/journey-of-developing-a-performance-optimization-feature-in-postgresql/"&gt;Journey of developing a performance optimization feature in PostgreSQL&lt;/A&gt;, by Rahila Syed &lt;SMALL style="color: #767676;"&gt;(Postgres hacking, PG internals, performance, WAL, replication, livestream-4)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/the-hitchhiker-s-guide-to-postgresql-hacking-don-t-panic-just-start-small/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/the-hitchhiker-s-guide-to-postgresql-hacking-don-t-panic-just-start-small/"&gt;The Hitchhiker’s Guide to PostgreSQL Hacking: Don’t Panic, Just Start Small&lt;/A&gt;, by Xuneng Zhou &lt;SMALL style="color: #767676;"&gt;(Postgres hacking, PG internals, community, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Replication&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/past-present-and-future-logical-decoding-and-replication-in-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/past-present-and-future-logical-decoding-and-replication-in-postgresql/"&gt;Past, Present, and Future: Logical Decoding and Replication in PostgreSQL&lt;/A&gt;, by Hari Kiran &lt;SMALL style="color: #767676;"&gt;(replication, logical decoding, PG internals, livestream-4)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/where-does-my-insert-go-a-logical-replication-story/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/where-does-my-insert-go-a-logical-replication-story/"&gt;Where Does My INSERT Go? A Logical Replication Story&lt;/A&gt;, by Hamid Akhtar &lt;SMALL style="color: #767676;"&gt;(replication, PG internals, WAL, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Security&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/from-dev-to-prod-securing-postgres-the-right-way/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/from-dev-to-prod-securing-postgres-the-right-way/"&gt;From Dev to Prod: Securing Postgres the Right Way&lt;/A&gt;, by Sakshi Nasha &lt;SMALL style="color: #767676;"&gt;(security, roles, PG use cases, extensions, monitoring, livestream-4)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/from-trust-to-tokens-a-short-history-of-postgresql-authentication/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/from-trust-to-tokens-a-short-history-of-postgresql-authentication/"&gt;From trust to Tokens: A Short History of PostgreSQL Authentication&lt;/A&gt;, by Murat Tuncer &lt;SMALL style="color: #767676;"&gt;(authentication, security, livestream-2)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-vs-sql-server-security-model-differences/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-vs-sql-server-security-model-differences/"&gt;PostgreSQL vs. SQL Server: Security Model Differences&lt;/A&gt;, by Taiob Ali &lt;SMALL style="color: #767676;"&gt;(security, authentication, SQL Server, roles, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-postgres-ecosystem" class="lia-anchor"&gt;&lt;/a&gt;11 Postgres ecosystem talks&lt;/H2&gt;
&lt;H3&gt;Analytics&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/pg_lake-postgres-as-a-lakehouse/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/pg_lake-postgres-as-a-lakehouse/"&gt;pg_lake: Postgres as a lakehouse&lt;/A&gt;, by Marco Slot &lt;SMALL style="color: #767676;"&gt;(pg_lake, extensions, OLAP, data warehouse, Iceberg, DuckDB, analytics, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Apache AGE&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/querying-visualizing-graphs-in-postgres-with-apache-age/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/querying-visualizing-graphs-in-postgres-with-apache-age/"&gt;Querying &amp;amp; Visualizing Graphs in Postgres with Apache AGE&lt;/A&gt;, by Christian Miles &lt;SMALL style="color: #767676;"&gt;(Apache AGE, graph data, data visualization, SQL/PGQ, Azure HorizonDB, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Autotuning&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/building-safety-tooling-for-risk-free-ai-tuning-of-postgres-fast-cars-need-fast-brakes/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/building-safety-tooling-for-risk-free-ai-tuning-of-postgres-fast-cars-need-fast-brakes/"&gt;Building safety tooling for risk-free AI tuning of Postgres: Fast cars need fast brakes&lt;/A&gt;, by Mohsin Ejaz &lt;SMALL style="color: #767676;"&gt;(autotuning, AI, performance, monitoring, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Change Data Capture&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/building-event-driven-systems-with-postgresql-logical-replication-and-drasi/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/building-event-driven-systems-with-postgresql-logical-replication-and-drasi/"&gt;Building Event-Driven Systems with PostgreSQL Logical Replication and Drasi&lt;/A&gt;, by Diaa Radwan &lt;SMALL style="color: #767676;"&gt;(Drasi, replication, WAL, CDC, livestream-3)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Citus&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/move-less-move-faster-speeding-up-citus-cluster-scaling/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/move-less-move-faster-speeding-up-citus-cluster-scaling/"&gt;Move Less, Move Faster: Speeding Up Citus Cluster Scaling&lt;/A&gt;, by Muhammad Usama &lt;SMALL style="color: #767676;"&gt;(Citus, extensions, performance, scaling Postgres, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Dev Tools&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/an-mcp-for-your-postgres-db/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/an-mcp-for-your-postgres-db/"&gt;An MCP for your Postgres DB&lt;/A&gt;, by Pamela Fox &lt;SMALL style="color: #767676;"&gt;(MCP, AI, Python, Dev tools, livestream-1)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/pgcov-bringing-real-test-coverage-to-postgresql-code/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/pgcov-bringing-real-test-coverage-to-postgresql-code/"&gt;pgcov: Bringing Real Test Coverage to PostgreSQL Code&lt;/A&gt;, by Pavlo Golub &lt;SMALL style="color: #767676;"&gt;(testing, Postgres hacking, Dev tools, extensions, CI/CD, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-tooling-across-ai-editors-and-agents/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-tooling-across-ai-editors-and-agents/"&gt;PostgreSQL Tooling Across AI Editors and Agents&lt;/A&gt;, by Matt McFarland &lt;SMALL style="color: #767676;"&gt;(Dev tools, VS Code, Cursor, AI, data visualization, Apache AGE, graph data, Azure, MCP, Copilot, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Django&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/postgresql-generated-columns-by-example/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/postgresql-generated-columns-by-example/"&gt;PostgreSQL Generated Columns by Example&lt;/A&gt;, by Paolo Melchiorre &lt;SMALL style="color: #767676;"&gt;(app dev, Django, generated columns, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Kubernetes&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/quorum-based-consistency-for-cluster-changes-with-cloudnativepg-operator/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/quorum-based-consistency-for-cluster-changes-with-cloudnativepg-operator/"&gt;Quorum-Based Consistency for Cluster Changes with CloudNativePG Operator&lt;/A&gt;, by Jeremy Schneider &amp;amp; Leonardo Cecchi &lt;SMALL style="color: #767676;"&gt;(CloudNativePG, Kubernetes, PG use cases, livestream-3)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Performance&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/modelling-postgres-performance-degradation-on-burstable-cloud-instances/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/modelling-postgres-performance-degradation-on-burstable-cloud-instances/"&gt;Modelling Postgres Performance Degradation on Burstable Cloud Instances&lt;/A&gt;, by Chun Lin Goh &lt;SMALL style="color: #767676;"&gt;(performance, burstable, compute, QA, livestream-4)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-azure" class="lia-anchor"&gt;&lt;/a&gt;8 Azure Database for PostgreSQL &amp;amp; Azure HorizonDB talks&lt;/H2&gt;
&lt;H3&gt;AI-related talks&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/from-queries-to-agents-the-next-era-of-data-retrieval-on-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/from-queries-to-agents-the-next-era-of-data-retrieval-on-postgresql/"&gt;From Queries to Agents: The Next Era of Data Retrieval on PostgreSQL&lt;/A&gt;, by Abe Omorogbe &lt;SMALL style="color: #767676;"&gt;(AI, MCP, Azure Database for PostgreSQL, graph data, Apache AGE, Azure HorizonDB, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/production-rag-at-scale-with-azure-database-for-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/production-rag-at-scale-with-azure-database-for-postgresql/"&gt;Production RAG at Scale with Azure Database for PostgreSQL&lt;/A&gt;, by Julia Schröder Langhaeuser &amp;amp; Paula Santamaría &lt;SMALL style="color: #767676;"&gt;(Azure Database for PostgreSQL, AI, RAG, PG use cases, livestream-3)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;AMD&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/choose-the-right-azure-infrastructure-to-improve-postgres-performance-by-over-60/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/choose-the-right-azure-infrastructure-to-improve-postgres-performance-by-over-60/"&gt;Choose the Right Azure Infrastructure to Improve Postgres Performance by Over 60%&lt;/A&gt;, by Andrew Ruffin &lt;SMALL style="color: #767676;"&gt;(AMD, performance, Azure, compute, Azure Database for PostgreSQL, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Azure HorizonDB&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/why-we-built-azure-horizondb-for-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/why-we-built-azure-horizondb-for-postgresql/"&gt;Why we built Azure HorizonDB for PostgreSQL&lt;/A&gt;, by Dingding Lu &lt;SMALL style="color: #767676;"&gt;(Azure HorizonDB, scaling Postgres, livestream-3)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Flexible Server&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/pg_duckdb-in-action-accelerating-analytics-on-azure-database-for-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/pg_duckdb-in-action-accelerating-analytics-on-azure-database-for-postgresql/"&gt;pg_duckdb in Action: Accelerating Analytics on Azure Database for PostgreSQL&lt;/A&gt;, by Nitin Jadhav &lt;SMALL style="color: #767676;"&gt;(DuckDB, Azure Database for PostgreSQL, extensions, OLAP, analytics, performance, livestream-4)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/the-rise-of-postgresql-as-the-everything-database/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/the-rise-of-postgresql-as-the-everything-database/"&gt;The Rise of PostgreSQL as the Everything Database&lt;/A&gt;, by Varun Dhawan &lt;SMALL style="color: #767676;"&gt;(Postgres history, extensions, graph data, Apache AGE, Azure Database for PostgreSQL, DuckDB, Citus, livestream-3)&lt;BR /&gt;&lt;BR /&gt;&lt;/SMALL&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/what-i-ve-learned-teaching-postgres-to-200-field-engineers-at-microsoft/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/what-i-ve-learned-teaching-postgres-to-200-field-engineers-at-microsoft/"&gt;What I’ve Learned Teaching Postgres to 200+ field engineers at Microsoft&lt;/A&gt;, by Paula Berenguel &lt;SMALL style="color: #767676;"&gt;(training, Azure, Postgres skilling, livestream-1)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Oracle to Postgres&lt;/H3&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;A href="https://posetteconf.com/2026/talks/migrating-vldbs-from-oracle-to-azure-database-for-postgresql/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/talks/migrating-vldbs-from-oracle-to-azure-database-for-postgresql/"&gt;Migrating VLDBs from Oracle to Azure Database for PostgreSQL&lt;/A&gt;, by Adithya Kumaranchath &lt;SMALL style="color: #767676;"&gt;(migration, Azure Database for PostgreSQL, Oracle to Postgres, livestream-2)&lt;/SMALL&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-discord" class="lia-anchor"&gt;&lt;/a&gt;Why participate in the virtual hallway track on Discord&lt;/H2&gt;
&lt;P&gt;If you’ve checked out the schedule and plan to watch some of the talks, you might still be wondering: why join live—and why bother with the virtual hallway track on Discord?&lt;BR /&gt;&lt;BR /&gt;Here’s how a few of last year’s attendees described the experience:&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;“Very impressed by all the speakers and content I am absolutely shattered as there was so much great content in all the talks over the past 3 days but I have probably learnt more in these sessions than I could have in months of reading up.”&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;“Want to let y’all know how much I got from this onine conference, the speakers were excellent, well-prepared and well-presented. The hosts were informative, engaging, &amp;amp; amusing. The discord hallway channel made me feel connected. I learned a lot and found some new inspiration. I’ll be back next year!”&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;“I have no idea how I’m going to summarise all the interesting stuff for coworkers.”&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The common thread: the live, shared experience—being able to ask questions, compare notes, and learn alongside other people in real time.&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;&lt;STRONG&gt;How to join the virtual hallway track&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;Head to the &lt;A href="https://aka.ms/open-source-discord" target="_blank" rel="noopener" data-href="https://aka.ms/open-source-discord"&gt;#posetteconf channel on Discord&lt;/A&gt; (on the Microsoft Open Source Discord)&lt;/LI&gt;
&lt;LI&gt;That’s where speakers and attendees hang out during the livestreams—it’s where you can ask questions, share reactions, and just say hi&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-speakers" class="lia-anchor"&gt;&lt;/a&gt;Big thank you to our amazing speakers&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;Every great event starts with great talks—and great talks start with great speakers. Want to learn more about the people behind these talks?&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;Visit the &lt;A href="https://posetteconf.com/2026/speakers/" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/speakers/"&gt;POSETTE 2026 Speaker page&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Click a speaker’s bio to see their written interview (if available)&lt;/LI&gt;
&lt;LI&gt;If a speaker has been a guest on the &lt;A href="https://talkingpostgres.com/" target="_blank" rel="noopener" data-href="https://talkingpostgres.com/"&gt;Talking Postgres podcast&lt;/A&gt; in the past, then you’ll find a link to their episode there, too&lt;/LI&gt;
&lt;/UL&gt;
&lt;img&gt;Figure 2: Bio pics for all speakers in POSETTE: An Event for Postgres 2026, along with our gratitude&lt;/img&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-join-us" class="lia-anchor"&gt;&lt;/a&gt;Join us for POSETTE 2026! Mark your calendars&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;I hope you join us for POSETTE 2026. Consider yourself officially invited. As part of the talk selection team, I’m definitely biased—but I truly believe these speakers and talks are worth your time. I’ll be hosting&amp;nbsp;&lt;STRONG&gt;Livestream 1&lt;/STRONG&gt; and you’ll find me in the #posetteconf Discord chat. I hope to see you there.&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;And please: &lt;STRONG&gt;tell your Postgres friends&lt;/STRONG&gt;, so they don’t miss out!&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;🗓️ &lt;STRONG&gt;Add the livestreams to your calendar&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;STRONG&gt;Livestream 1&lt;/STRONG&gt;: Tue 16 June, 8am–2pm PDT (UTC-7)&lt;BR /&gt;&lt;A href="https://developer.microsoft.com/reactor/events/26853/" target="_blank" rel="noopener" data-href="https://developer.microsoft.com/reactor/events/26853/"&gt;[ register for updates ]&lt;/A&gt; and/or &lt;A href="https://www.addevent.com/event/Sf26983045" target="_blank" rel="noopener" data-href="https://www.addevent.com/event/Sf26983045"&gt;[ add to calendar ]&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Livestream 2&lt;/STRONG&gt;: Wed 17 June, 8am–2pm CEST (UTC+2)&lt;BR /&gt;&lt;A href="https://developer.microsoft.com/reactor/events/26854/" target="_blank" rel="noopener" data-href="https://developer.microsoft.com/reactor/events/26854/"&gt;[ register for updates ]&lt;/A&gt; and/or &lt;A href="https://www.addevent.com/event/TX26983054" target="_blank" rel="noopener" data-href="https://www.addevent.com/event/TX26983054"&gt;[ add to calendar ]&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Livestream 3&lt;/STRONG&gt;: Wed 17 June, 8am–2pm PDT (UTC-7)&lt;BR /&gt;&lt;A href="https://developer.microsoft.com/reactor/events/26855/" target="_blank" rel="noopener" data-href="https://developer.microsoft.com/reactor/events/26855/"&gt;[ register for updates ]&lt;/A&gt; and/or &lt;A href="https://www.addevent.com/event/yH26983066" target="_blank" rel="noopener" data-href="https://www.addevent.com/event/yH26983066"&gt;[ add to calendar ]&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Livestream 4&lt;/STRONG&gt;: Thu 18 June, 8am–2pm CEST (UTC+2)&lt;BR /&gt;&lt;A href="https://developer.microsoft.com/reactor/events/26856/" target="_blank" rel="noopener" data-href="https://developer.microsoft.com/reactor/events/26856/"&gt;[ register for updates ]&lt;/A&gt; and/or &lt;A href="https://www.addevent.com/event/rd26983070" target="_blank" rel="noopener" data-href="https://www.addevent.com/event/rd26983070"&gt;[ add to calendar ]&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;&lt;STRONG&gt;Watch last year’s POSETTE 2025 talks in advance&lt;/STRONG&gt;: And if you want to get ready, you can watch talks from the &lt;A href="https://aka.ms/posette-playlist-2025" target="_blank" rel="noopener" data-href="https://aka.ms/posette-playlist-2025"&gt;POSETTE 2025 playlist on YouTube&lt;/A&gt; anytime, anywhere. Lots of solid, useful, and evergreen Postgres talks in there.&lt;/P&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-trailer" class="lia-anchor"&gt;&lt;/a&gt;“Official Trailer” for POSETTE 2026 is on YouTube&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;To help more developers, community members, and Postgres users discover POSETTE 2026, our team created this short video trailer. Take a peek and share it with friends as an invitation of sorts.&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;We’re trying to make sure that people don’t miss their opportunity to be part of the livestreams and ask questions on the discord during the conference (as well as watch the talks on YouTube after the event is over.)&lt;/P&gt;
&lt;UL style="margin-bottom: 1.5em;"&gt;
&lt;LI&gt;&lt;STRONG&gt;Watch and share the trailer&lt;/STRONG&gt;: &lt;A href="https://youtu.be/AX4Axl52uBQ" target="_blank" rel="noopener" data-href="https://youtu.be/AX4Axl52uBQ"&gt;Official Trailer for POSETTE: An Event for Postgres 2026&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class="lia-embeded-content" contenteditable="false"&gt;&lt;IFRAME src="https://www.youtube-nocookie.com/embed/AX4Axl52uBQ?si=LBj7K4e3rsiAw5_H" width="560" height="315" title="YouTube video player" allowfullscreen="allowfullscreen" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" frameborder="0" sandbox="allow-scripts allow-same-origin allow-forms"&gt;&lt;/IFRAME&gt;&lt;/DIV&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Acknowledgements &amp;amp; Gratitude&lt;/H2&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;I’ve already thanked the 50 amazing speakers above. In addition, thanks go to Silvano Coriani, Cornelia Biacsics, Aaron Wislang, and My Nguyen for reviewing parts of this post before publication.&lt;/P&gt;
&lt;P style="margin-bottom: 1.5em;"&gt;I also want to thank the team at AMD for their partnership and support of POSETTE this year! And of course, big thank you to the &lt;A href="https://posetteconf.com/2026/about/#organizing-team" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/about/#organizing-team"&gt;POSETTE 2026 organizing team&lt;/A&gt; and &lt;A href="https://posetteconf.com/2026/about/#talk-selection-team" target="_blank" rel="noopener" data-href="https://posetteconf.com/2026/about/#talk-selection-team"&gt;POSETTE talk selection team&lt;/A&gt;—without you, there would be no POSETTE!&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Figure 3: Visual invitation to join the virtual hallway track for POSETTE 2026 on the Microsoft Open Source Discord, so you can chat with the speakers &amp;amp; others in the Postgres community&lt;/P&gt;
&lt;/img&gt;</description>
      <pubDate>Mon, 18 May 2026 08:20:26 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ultimate-guide-to-posette-an-event-for-postgres-2026-edition/ba-p/4520246</guid>
      <dc:creator>clairegiordano</dc:creator>
      <dc:date>2026-05-18T08:20:26Z</dc:date>
    </item>
    <item>
      <title>Azure ADF boolean parameter changes from true to True and false to False</title>
      <link>https://techcommunity.microsoft.com/t5/azure-data-factory/azure-adf-boolean-parameter-changes-from-true-to-true-and-false/m-p/4519898#M964</link>
      <description>&lt;P&gt;I just created a new trigger in Azure ADF.&amp;nbsp;&lt;BR /&gt;I seems the boolean parameter in the trigger is converted from lowercase to be capitalised.&amp;nbsp;&lt;BR /&gt;Is anybody experiencing the same thing?&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 15 May 2026 01:15:17 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-data-factory/azure-adf-boolean-parameter-changes-from-true-to-true-and-false/m-p/4519898#M964</guid>
      <dc:creator>jgollner</dc:creator>
      <dc:date>2026-05-15T01:15:17Z</dc:date>
    </item>
    <item>
      <title>Automatic Connectivity Tests for Azure SQL Managed Instance</title>
      <link>https://techcommunity.microsoft.com/t5/azure-sql-blog/automatic-connectivity-tests-for-azure-sql-managed-instance/ba-p/4519795</link>
      <description>&lt;P&gt;To further enhance connectivity monitoring and improve service reliability, we’re introducing automatic internal connectivity tests for all Azure SQL Managed Instances. These tests are fully automated and require no action from you. Beginning May 2026, the tests will be continuously performed at regular intervals on all managed instances. By proactively monitoring internal network connections, we’re able to quickly identify potential issues and maintain stable end-to-end connectivity.&lt;/P&gt;
&lt;P&gt;These tests are performed from a pair of internal IP addresses from the subnet range that hosts the managed instance, so they do not require any external inbound or outbound connectivity. Please note that additional IP addresses will be reserved for these tests and that tests may leave traces in your observability logs.&lt;/P&gt;
&lt;P&gt;Automatic tests diagnose issues in internal service and network availability. This results in accelerated issue discovery and shorter time to mitigate incidents that involve degraded connectivity of managed instances’ internal networking components. This suite of connectivity tests examines internal network connections at several levels, boosting the supportability and visibility into the service’s internal state and offering you peace of mind regarding your managed instances.&lt;/P&gt;
&lt;P&gt;Do note that your audit and security systems, if configured to track certain types of events emitted by SQL Server, may record failed login attempts. Those are normal and expected byproducts of the end-to-end connectivity test suite. If you would prefer to not have those events register in your SQL Server audit logs, SQL error logs, or captured Extended Events, we provide you with their event signatures so you can set up event filters or configure your SIEM system to ignore them: &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/connectivity-testing-overview?view=azuresql#observe-failed-logins-caused-by-end-to-end-tests" target="_blank"&gt;Observing failed logins caused by end-to-end tests&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;You can read more about the automated connectivity tests at &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/azure-sql/managed-instance/connectivity-testing-overview?view=azuresql" target="_blank"&gt;Automatic internal connectivity tests for Azure SQL Managed Instance&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Thu, 14 May 2026 15:56:24 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-sql-blog/automatic-connectivity-tests-for-azure-sql-managed-instance/ba-p/4519795</guid>
      <dc:creator>ZoranRilak</dc:creator>
      <dc:date>2026-05-14T15:56:24Z</dc:date>
    </item>
    <item>
      <title>April 2026 Recap: Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/april-2026-recap-azure-database-for-postgresql/ba-p/4519772</link>
      <description>&lt;P&gt;April brought several updates for &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/" target="_blank" rel="noopener"&gt;Azure Database for PostgreSQL&lt;/A&gt;, focused on improving developer productivity, strengthening security and connectivity, and helping customers scale and optimize their PostgreSQL workloads. From new Entra ID token refresh libraries across .NET, JavaScript, and Python to simplify authentication, to guidance on migrating from VNet to Private Endpoint capable configurations, we continue to make it easier to build and manage secure applications. We also introduced enhancements to the PostgreSQL VS Code extension and published deep dives on query performance, data modeling, and real-world scaling patterns.&lt;/P&gt;
&lt;P&gt;We also published a blog on how &lt;A href="https://opensource.microsoft.com/blog/2026/04/30/postgresql-enters-its-ai-era-run-postgresql-like-a-pro-in-the-era-of-ai-and-rapid-growth/" target="_blank" rel="noopener"&gt;PostgreSQL enters its AI era&lt;/A&gt;, which explores ways with which developers can adapt PostgreSQL to meet the needs of AI-driven and rapidly growing applications, with practical guidance on running and scaling PostgreSQL more effectively in these evolving workloads.&lt;/P&gt;
&lt;H2&gt;POSETTE 2026&lt;/H2&gt;
&lt;P&gt;Before we dive deeper into the feature updates, &lt;A href="https://posetteconf.com/2026/about/" target="_blank" rel="noopener"&gt;POSETTE: An Event for Postgres&amp;nbsp;2026&lt;/A&gt; is just around the corner, PostgreSQL’s free, virtual conference bringing together the global community. Taking place from June 16–18, the event will feature four livestream tracks with a strong lineup of content, including 44 sessions, 2 keynotes, and 50 speakers. It’s a great opportunity to hear from PostgreSQL experts, learn about the latest trends, and discover real-world best practices across a wide range of topics.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://developer.microsoft.com/en-us/reactor/series/s-1645/" target="_blank" rel="noopener"&gt;Register today&lt;/A&gt; for updates and be part of three days of learning, insights, and community-driven discussions across a wide range of PostgreSQL topics.&lt;/P&gt;
&lt;H1&gt;Features&lt;/H1&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-entra" target="_self" rel="noopener"&gt;Entra-ID token refresh libraries for .NET, JavaScript, and Python: Preview&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-vnet" target="_self" rel="noopener"&gt;Migrating from VNet to Private Endpoint: Preview&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-vscode" target="_self" rel="noopener"&gt;New enhancements in the PostgreSQL VS Code Extension&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-blog1" target="_self" rel="noopener"&gt;Improving Query Performance and Modeling in PostgreSQL&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-blog2" target="_self" rel="noopener"&gt;Scaling PostgreSQL for Real-World Application Workloads&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Learning Bytes: &lt;A class="lia-internal-link" href="#community--1-prevent" target="_blank" rel="noopener" data-lia-auto-title="Preventing accidental server deletion" data-lia-auto-title-active="0"&gt;Preventing accidental server deletion&lt;/A&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H2 id="entra"&gt;Entra-ID Token refresh libraries: .NET, JavaScript and Python&lt;/H2&gt;
&lt;P&gt;We’ve introduced Entra ID token refresh libraries for &lt;A href="https://www.nuget.org/packages/Microsoft.Azure.PostgreSQL.Auth/1.0.0-beta.1#readme-body-tab" target="_blank" rel="noopener"&gt;.NET&lt;/A&gt;, &lt;A href="https://www.nuget.org/packages/Microsoft.Azure.PostgreSQL.Auth/1.0.0-beta.1#readme-body-tab" target="_blank" rel="noopener"&gt;JavaScript&lt;/A&gt;, and &lt;A href="https://pypi.org/project/azure-postgresql-auth/" target="_blank" rel="noopener"&gt;Python&lt;/A&gt; to simplify how applications authenticate with Azure Database for PostgreSQL using Entra ID. When using Entra ID–based authentication, access tokens are short-lived and need to be refreshed periodically. This often requires additional logic in the application to handle expiration, retries, and reconnection scenarios. These new libraries take care of that complexity by &lt;STRONG&gt;automatically refreshing tokens behind the scenes&lt;/STRONG&gt;, so applications can maintain &lt;STRONG&gt;uninterrupted database connections&lt;/STRONG&gt; without custom token management.&lt;/P&gt;
&lt;P&gt;With built-in support for token renewal, these libraries help:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Reduce the need for manual token refresh logic in your application code&lt;/LI&gt;
&lt;LI&gt;Improve reliability for long-running or connection-pooled workloads&lt;/LI&gt;
&lt;LI&gt;Simplify adoption of Entra ID authentication across different language stacks&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Whether you're building new applications or migrating existing ones to use Entra ID, these libraries make it easier to integrate secure, passwordless authentication while keeping connection handling straightforward.&lt;/P&gt;
&lt;H2 id="vnet"&gt;Migrating from VNet to Private Endpoint&lt;/H2&gt;
&lt;P&gt;Azure Database for PostgreSQL flexible server can now be migrated from a &lt;STRONG&gt;VNet‑integrated&lt;/STRONG&gt; deployment to a network configuration that supports &lt;STRONG&gt;Private Endpoint&lt;/STRONG&gt; connectivity. Servers originally deployed inside a VNet may require greater flexibility in networking management. Private Endpoints provide a simpler and more &lt;STRONG&gt;scalable model&lt;/STRONG&gt;. Following migration, private access to the server continues over Azure’s backbone network, dependency on delegated subnets is reduced, and database networking can be better aligned with evolving architectural or organizational standards.&lt;/P&gt;
&lt;P&gt;The migration can be initiated through &lt;STRONG&gt;Azure CLI, API, or SDK&lt;/STRONG&gt; and is designed to be straightforward. Although the operation involves a period of downtime, it enables adoption of Private Endpoint connectivity without recreating the server or manually moving data. After migration, Private Endpoints or firewall rules can be configured based on the desired access model, and infrastructure-as-code templates can be updated accordingly.&lt;/P&gt;
&lt;P&gt;Read more here: &lt;A href="https://learn.microsoft.com/azure/postgresql/network/how-to-migrate-vnet-private-endpoint-capable-server?tabs=portal-migrate" target="_blank" rel="noopener"&gt;Migrate from VNet to a Private Endpoint Capable Network Configuration | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;H2 id="vscode"&gt;New enhancements in the PostgreSQL VS Code Extension&lt;/H2&gt;
&lt;P&gt;The latest release (v1.21) of the PostgreSQL VS Code extension delivers enhancements to query authoring and analysis workflows, improved cross-extension interoperability, reliability improvements across Object Explorer and connection management, and a set of targeted bug fixes.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Schema-Aware Query Creation:&lt;/STRONG&gt; You can now open a new query directly from a schema in Object Explorer, automatically setting the appropriate search_path so unqualified object names resolve correctly without additional setup.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Query Plan Visualization Enhancements:&lt;/STRONG&gt; The query plan visualizer now uses PostgreSQL-specific node icons across all views, making it easier to identify scan, join, and aggregate operations during performance analysis.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Improved Multi-Extension Compatibility:&lt;/STRONG&gt; The extension now coordinates editor ownership with the MSSQL extension when both are installed, reducing duplicate UI actions and avoiding conflicts in query execution workflows.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Object Explorer Reliability Improvements&lt;/STRONG&gt;: The Object Explorer has been refactored for more consistent refresh, expansion, and reconnection behavior, especially in long-running sessions and databases with many schemas.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Enhanced IntelliSense Behavior:&lt;/STRONG&gt; IntelliSense now respects the configured search_path, improving the relevance of suggestions and helping you work more efficiently across schemas.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Bug Fixes:&lt;/STRONG&gt; This release includes fixes across object scripting (including partitioned tables), connection profile handling, Docker container creation, and initial extension setup for improved reliability and stability.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 id="blog1"&gt;Improving Query Performance and Modeling in PostgreSQL&lt;/H2&gt;
&lt;P&gt;This month, we also shared a set of technical blogs highlighting advanced PostgreSQL scenarios and practical guidance for real-world workloads:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Guide on workload observability with Query store&lt;/STRONG&gt;:&amp;nbsp;This &lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/end-to-end-workload-observability-with-query-store-for-primary-and-replicas/4517110" target="_blank" rel="noopener"&gt;blog&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; dives into how Query Store can be used to gain end-to-end visibility into query performance across both primary and replica nodes. It highlights the importance of understanding query behavior in distributed setups and how bottlenecks can surface differently across nodes. The post also shares practical guidance on using these insights to troubleshoot issues and optimize workload performance effectively.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Guide on Common Table Expressions(CTEs) with Data Skew&lt;/STRONG&gt;: This deep dive unpacks a complex query planning scenario in PostgreSQL v17, where data skew can lead to unexpected and suboptimal execution plans involving CTEs. It explains why the optimizer may choose inefficient plans and how this impacts real-world workloads. The&amp;nbsp;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/when-postgresql-v17-chooses-the-wrong-plan-a-deep-dive-into-ctes-with-data-skew/4515705" target="_blank" rel="noopener"&gt;blog&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; also outlines strategies to diagnose and mitigate these issues, helping users better predict and tune query performance.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Guide on PostgreSQL as a Graph Database:&lt;/STRONG&gt; This&amp;nbsp;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/postgresql-as-your-graph-database-in-the-ai-era/4516323" target="_blank" rel="noopener"&gt;blog&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; explains how PostgreSQL can be leveraged to model and query graph-like relationships, making it highly relevant for AI-driven applications. It demonstrates how relational capabilities can be extended to support graph workloads without introducing additional systems. The post also highlights practical patterns and use cases that enable developers to build more connected, intelligent applications using PostgreSQL as a unified data platform.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 id="blog2"&gt;Scaling PostgreSQL for Real-World Application Workloads&lt;/H2&gt;
&lt;P&gt;Alongside performance tuning and data modeling topics, we also explored how PostgreSQL behaves under real-world application patterns especially in scenarios involving high concurrency, background job processing, and connection-heavy workloads. These blogs focus on common architectural choices developers make and the trade-offs to consider when scaling reliably.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Guide on using Postgres as a Job Queue&lt;/STRONG&gt;: This&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/adforpostgresql/potential-consequences-of-using-postgres-as-a-job-queue/4514332" target="_blank" rel="noopener" data-lia-auto-title="blog" data-lia-auto-title-active="0"&gt;blog&lt;/A&gt; takes a deeper look at the implications of using PostgreSQL as a job queue, a pattern commonly adopted for simplicity and tighter integration. It walks through how queue-like workloads can introduce contention due to frequent updates, row locking, and long-running transactions. The post highlights how these patterns can impact throughput, vacuum efficiency, and overall database health as scale increases. It also discusses when this approach is appropriate, and when teams should consider dedicated queuing systems to avoid performance bottlenecks.&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Guide on Connection Scaling with Elastic Clusters: &lt;/STRONG&gt;This&amp;nbsp;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/adforpostgresql/connection-scaling-in-elastic-clusters/4509624" target="_blank" rel="noopener" data-lia-auto-title="blog " data-lia-auto-title-active="0"&gt;blog &lt;/A&gt;dives into the challenges of handling large volumes of concurrent connections, which is a common bottleneck for modern, microservices-based applications. It explains how Elastic Clusters help distribute connections and workload across multiple nodes, improving scalability and resilience under heavy load. The post also touches on connection management patterns, including pooling strategies, and how they work in conjunction with Elastic Clusters to prevent resource exhaustion and ensure consistent performance at scale.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Azure Postgres Learning Bytes 🎓&lt;/H1&gt;
&lt;H5 id="prevent"&gt;Preventing accidental server deletion&lt;/H5&gt;
&lt;P&gt;In production environments, accidental deletions can lead to significant downtime and data loss. To safeguard critical resources like Azure Database for PostgreSQL servers, Azure provides &lt;STRONG&gt;resource locks&lt;/STRONG&gt; that add an extra layer of protection beyond standard role-based access control (RBAC). A commonly used option is the &lt;STRONG&gt;CanNotDelete (Delete Lock)&lt;/STRONG&gt;, which ensures that a resource cannot be deleted even by users with elevated permissions until the lock is explicitly removed.&lt;/P&gt;
&lt;P&gt;You can apply a delete lock easily using the Azure CLI by targeting the specific resource:&lt;/P&gt;
&lt;LI-CODE lang="shell"&gt;az lock create --name PreventDelete --lock-type CanNotDelete --resource-group &amp;lt;rg-name&amp;gt; --resource-type Microsoft.DBforPostgreSQL/flexibleServers --resource-name &amp;lt;resource-name&amp;gt;&amp;lt;/resource-name&amp;gt;&amp;lt;/rg-name&amp;gt;&lt;/LI-CODE&gt;
&lt;P&gt;Once applied, any delete operation on the resource will be blocked, helping prevent accidental or unintended deletions during maintenance, deployments, or testing. Locks can be applied at different levels subscription, resource group, or individual resources allowing flexibility based on your protection needs.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;For more details and &lt;STRONG&gt;step-by-step guidance&lt;/STRONG&gt;, read our blog on &lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/adforpostgresql/prevent-accidental-deletion-of-an-instance-in-azure-postgres/4447969" data-lia-auto-title="Preventing accidental deletion of an Azure PostgreSQL Instance" data-lia-auto-title-active="0" target="_blank"&gt;Preventing accidental deletion of an Azure PostgreSQL Instance&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Thu, 14 May 2026 17:27:45 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/april-2026-recap-azure-database-for-postgresql/ba-p/4519772</guid>
      <dc:creator>gauri-kasar</dc:creator>
      <dc:date>2026-05-14T17:27:45Z</dc:date>
    </item>
    <item>
      <title>Unexpected PITR Charges from restorableDroppedDatabases After BC → Hyperscale Migration</title>
      <link>https://techcommunity.microsoft.com/t5/azure-database-support-blog/unexpected-pitr-charges-from-restorabledroppeddatabases-after-bc/ba-p/4519768</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Why This Behavior Is by Design&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When migrating an Azure SQL Database from &lt;STRONG&gt;Business Critical (BC)&lt;/STRONG&gt; to &lt;STRONG&gt;Hyperscale&lt;/STRONG&gt; using a &lt;STRONG&gt;manual cutover&lt;/STRONG&gt;, some customers notice &lt;STRONG&gt;unexpected Point-in-Time Restore (PITR) backup storage charges&lt;/STRONG&gt; appearing under the following resource:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;/Microsoft.Sql/servers/&amp;lt;server&amp;gt;/restorableDroppedDatabases/&amp;lt;database&amp;gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;At first glance, this can be confusing—especially when:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;No &lt;STRONG&gt;customer-initiated drop or delete&lt;/STRONG&gt; was performed&lt;/LI&gt;
&lt;LI&gt;The database is &lt;STRONG&gt;online and healthy post-migration&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Test migrations may not have shown similar charges&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This post explains &lt;STRONG&gt;why this happens&lt;/STRONG&gt;, &lt;STRONG&gt;why it is expected by design&lt;/STRONG&gt;, and &lt;STRONG&gt;how these charges naturally expire&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;The Observed Scenario&lt;/H2&gt;
&lt;P&gt;After a &lt;STRONG&gt;BC → Hyperscale manual cutover&lt;/STRONG&gt;, customers may see PITR charges tied to:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;restorableDroppedDatabases/&amp;lt;database-name&amp;gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Despite the database being active and available in Hyperscale, these charges start appearing&amp;nbsp;&lt;STRONG&gt;immediately after the migration cutover&lt;/STRONG&gt; and gradually decrease over time.&lt;/P&gt;
&lt;H2&gt;Why Does the Database Appear as “Dropped”?&lt;/H2&gt;
&lt;P&gt;During a &lt;STRONG&gt;manual cutover migration&lt;/STRONG&gt;, Azure SQL performs an &lt;STRONG&gt;internal platform-driven workflow&lt;/STRONG&gt; to complete the transition between architectures.&lt;/P&gt;
&lt;P&gt;From a control-plane perspective:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;source Business Critical logical database is internally dropped&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;This drop is &lt;STRONG&gt;not initiated by the customer&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;It is a &lt;STRONG&gt;required system step&lt;/STRONG&gt; to complete the Hyperscale migration&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Telemetry confirms that the migration workflow transitions through states such as:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Internal drop of the source physical and logical database&lt;/LI&gt;
&lt;LI&gt;Cleanup of metadata and completion of the migration&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This entire sequence completes within seconds and is fully platform managed.&lt;/P&gt;
&lt;H2&gt;Why Are Backup Charges Generated?&lt;/H2&gt;
&lt;P&gt;Although the &lt;STRONG&gt;source BC database is internally dropped&lt;/STRONG&gt;, its &lt;STRONG&gt;pre-migration PITR backups are still retained&lt;/STRONG&gt; according to the configured backup retention period.&lt;/P&gt;
&lt;P&gt;Here’s the key point:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Backups taken before upgrading to Hyperscale are retained and billed using the dropped-database backup billing model.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Because the source database is now considered&amp;nbsp;&lt;STRONG&gt;dropped (from the BC perspective)&lt;/STRONG&gt;:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;1× database-size discount no longer applies&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The &lt;STRONG&gt;full data file size&lt;/STRONG&gt; is added to the billable backup size&lt;/LI&gt;
&lt;LI&gt;Charges appear under restorableDroppedDatabases&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This behavior is explicitly documented as&amp;nbsp;&lt;STRONG&gt;expected&lt;/STRONG&gt; in internal Azure SQL billing guidance.&lt;/P&gt;
&lt;H2&gt;Why Do Charges Decrease Over Time?&lt;/H2&gt;
&lt;P&gt;These charges are &lt;STRONG&gt;not permanent&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;They:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Decrease daily&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Continue only while the &lt;STRONG&gt;pre-migration PITR backups are retained&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Automatically stop once the retention window expires&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In practical terms:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Charges stop when: days_since_migration &amp;gt; configured_backup_retention_days&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;No cleanup action is required from the customer—the platform handles this automatically.&lt;/P&gt;
&lt;H2&gt;Why Didn’t Test Migrations Show Similar Charges?&lt;/H2&gt;
&lt;P&gt;In many reported cases, &lt;STRONG&gt;test or smaller databases&lt;/STRONG&gt; migrated using the same method did &lt;STRONG&gt;not&lt;/STRONG&gt; generate noticeable charges.&lt;/P&gt;
&lt;P&gt;This can be explained by two documented optimizations:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Backup size threshold&lt;/STRONG&gt; – very small backup footprints are not charged&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Low activity optimization&lt;/STRONG&gt; – inactive or low-change databases generate fewer snapshots&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;As a result, smaller or lightly used test databases may fall &lt;STRONG&gt;below the billing threshold&lt;/STRONG&gt;, while larger production databases do not.&lt;/P&gt;
&lt;H2&gt;Is This a Billing Error or Credit Scenario?&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;No.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Although the operation is platform-driven:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The behavior is &lt;STRONG&gt;by design&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;The charges are for &lt;STRONG&gt;temporary retention of valid PITR backups&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;They naturally expire based on retention&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Therefore, this scenario is &lt;STRONG&gt;not considered a billing defect&lt;/STRONG&gt; and &lt;STRONG&gt;does not typically warrant credits&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;How Can Customers Reduce Charges Faster?&lt;/H2&gt;
&lt;P&gt;If needed, customers can:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Reduce the PITR backup retention period&lt;/STRONG&gt; (minimum is 1 day)&lt;/LI&gt;
&lt;LI&gt;Wait up to &lt;STRONG&gt;24 hours&lt;/STRONG&gt; for billing to reflect the change&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;This shortens how long the pre-migration backups are retained and billed.&lt;/P&gt;
&lt;H2&gt;FAQ – restorableDroppedDatabases Charges After BC → Hyperscale Migration&lt;/H2&gt;
&lt;H3&gt;&lt;STRONG&gt;Q1: Why am I seeing PITR charges for restorableDroppedDatabases when my database is still online?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; During a &lt;STRONG&gt;Business Critical → Hyperscale manual cutover&lt;/STRONG&gt;, Azure SQL &lt;STRONG&gt;internally drops the source BC database&lt;/STRONG&gt; as part of the migration workflow. While the Hyperscale database is active and healthy, the &lt;STRONG&gt;pre‑migration BC backups are retained&lt;/STRONG&gt; and billed under restorableDroppedDatabases.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q2: Did the customer initiate a drop or delete operation?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. This drop is &lt;STRONG&gt;platform‑driven&lt;/STRONG&gt; and required to complete the migration. It is not initiated by the customer.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q3: What exactly is being billed?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; The charges are for &lt;STRONG&gt;Point‑in‑Time Restore (PITR) backups taken before the migration&lt;/STRONG&gt;. These backups are retained according to the configured backup retention period and are billed using the &lt;STRONG&gt;dropped database billing model&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q4: Why does the cost appear higher than expected?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Once a database is considered “dropped” (from the BC perspective), the &lt;STRONG&gt;1× database-size discount no longer applies&lt;/STRONG&gt;, and the &lt;STRONG&gt;full data file size&lt;/STRONG&gt; is included in the billable backup size.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q5: Will these charges continue indefinitely?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. The charges &lt;STRONG&gt;decrease daily&lt;/STRONG&gt; and &lt;STRONG&gt;automatically stop&lt;/STRONG&gt; once the pre‑migration backups expire based on the configured PITR retention period.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q6: Why didn’t this happen with smaller or test databases?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Smaller or low‑activity databases may fall &lt;STRONG&gt;below the backup billing threshold&lt;/STRONG&gt;, or benefit from &lt;STRONG&gt;low‑activity snapshot optimizations&lt;/STRONG&gt;, resulting in no visible charges.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q7: Is this a billing bug or credit-worthy scenario?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; No. This behavior is &lt;STRONG&gt;by design and expected&lt;/STRONG&gt;. The charges reflect valid backup retention and do not typically qualify for credits.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Q8: Can the customer reduce these charges sooner?&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;A:&lt;/STRONG&gt; Yes. The customer can &lt;STRONG&gt;reduce the PITR backup retention period&lt;/STRONG&gt; (minimum 1 day). Billing changes usually reflect within &lt;STRONG&gt;up to 24 hours&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Key Takeaways&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;The behavior is&amp;nbsp;&lt;STRONG&gt;expected and by design&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Charges come from&amp;nbsp;&lt;STRONG&gt;pre-migration BC backups&lt;/STRONG&gt;, not the active Hyperscale database&lt;/LI&gt;
&lt;LI&gt;The database was&amp;nbsp;&lt;STRONG&gt;internally dropped as part of migration&lt;/STRONG&gt;, not by the customer&lt;/LI&gt;
&lt;LI&gt;Charges&amp;nbsp;&lt;STRONG&gt;decrease daily and stop automatically&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;No action is required unless the customer wants to reduce retention early&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Final Note&lt;/H2&gt;
&lt;P&gt;As of the time of writing, &lt;STRONG&gt;this behavior is not clearly described in public customer-facing documentation&lt;/STRONG&gt;, which explains why it often appears unexpected. Awareness of this mechanism can help set correct expectations when planning BC → Hyperscale manual cutover migrations.&lt;/P&gt;</description>
      <pubDate>Thu, 14 May 2026 14:01:54 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-database-support-blog/unexpected-pitr-charges-from-restorabledroppeddatabases-after-bc/ba-p/4519768</guid>
      <dc:creator>Mohamed_Baioumy_MSFT</dc:creator>
      <dc:date>2026-05-14T14:01:54Z</dc:date>
    </item>
    <item>
      <title>Zero downtime migration from Oracle to Azure DB for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-data-migration-blog/zero-downtime-migration-from-oracle-to-azure-db-for-postgresql/ba-p/4518563</link>
      <description>&lt;P&gt;&lt;EM&gt;Co-authored by:&lt;/EM&gt;&lt;BR /&gt;&lt;EM&gt;Maxim Lukiyanov, Principal PM Manager, Postgres on Azure, Microsoft&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Edward Bell, Senior Director, Global Technical Alliances &amp;amp; Solutions, Striim&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Matthew Burrows, Director, Databases Migration and Modernizations, Microsoft&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For organizations modernizing mission-critical applications, moving Oracle workloads to Microsoft Azure is a pivotal step toward realizing the benefits of a fully managed, cloud-native data architecture. Azure Database for PostgreSQL offers built-in high availability, elastic scale, enterprise security, and integration across Azure’s analytics and AI ecosystem—all without the operational overhead of managing legacy infrastructure.&lt;/P&gt;
&lt;P&gt;The challenge many teams face is how to migrate years of operational data from Oracle into Azure Database for PostgreSQL without introducing downtime, risk, or data drift.&lt;/P&gt;
&lt;P&gt;Microsoft and Striim solve this challenge together. Striim’s log-based Change Data Capture (CDC) continuously streams every Oracle transaction into Azure Database for PostgreSQL in real time to deliver zero-data-loss migration, continuous validation, and minimal impact on live applications.&lt;/P&gt;
&lt;P&gt;As part of the &lt;A href="https://techcommunity.microsoft.com/blog/microsoftdatamigration/removing-barriers-to-migrating-databases-to-azure-with-striim%E2%80%99s-unlimited-databa/4470150" target="_blank" rel="noopener"&gt;Microsoft Unlimited Database Migration Program,&lt;/A&gt; Striim is optimized to help organizations accelerate and de-risk their journey to Azure by combining enterprise-grade CDC technology, architectural best practices, and hands-on partner expertise. This joint solution empowers enterprises to modernize on Azure faster, with confidence, while paving the way for AI-ready architectures and long-term innovation.&lt;/P&gt;
&lt;P&gt;This tutorial walks through the architecture, deployment steps, and best practices for Oracle to Azure Database for PostgreSQL migrations using Striim.&lt;/P&gt;
&lt;H2&gt;Why Use Striim for Continuous Migration&lt;/H2&gt;
&lt;P&gt;The strategic partnership between Microsoft and Striim enables continuous data replication from existing databases into Azure in real time, enabling online migrations with zero downtime. Through this Unlimited Database Migration Program, customers gain unlimited Striim licenses to migrate as many databases as they need at no additional cost.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Program highlights include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Zero-downtime, zero-data-loss migrations across SQL Server, Oracle, MySQL, PostgreSQL, Azure SQL and more.&lt;/LI&gt;
&lt;LI&gt;Support for heterogeneous, mission-critical workloads across relational and non-relational systems.&lt;/LI&gt;
&lt;LI&gt;Real-time, AI-ready data pipelines, preparing workloads for analytics and ML once migrated.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;With Striim, data moves continuously via log-based CDC, reading directly from Oracle transaction logs and replicating every insert, update, and delete to Azure in real time. This minimizes impact on production systems while maintaining full data consistency during migration.&lt;/P&gt;
&lt;H2&gt;Architecture Overview&lt;/H2&gt;
&lt;P&gt;The jointly recommended architecture consists of:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Source:&lt;/STRONG&gt; an existing Oracle instance (on-premises or hosted in another environment).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Processing Layer:&lt;/STRONG&gt; Striim, deployed in Azure for low-latency, secure data movement.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Target: &lt;/STRONG&gt;Azure Database for PostgreSQL (Flexible Server)&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Connectivity is established over standard Oracle (1521) and PostgreSQL (5432) ports, but can also utilize ports configured by the customers. Azure customers can use Private Link, VNets, and other native Azure networking controls to secure traffic throughout the migration.&lt;/P&gt;
&lt;H2&gt;Step 1: Preparing the Oracle Source&lt;/H2&gt;
&lt;P&gt;Before replication can begin, configure Oracle so that redo logs are accessible and a CDC user can be used by Striim.&lt;/P&gt;
&lt;P&gt;Striim supports multiple CDC methods for Oracle:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Oracle Reader (LogMiner):&lt;/STRONG&gt; Uses Oracle’s LogMiner API to read from redo logs. This is the default method.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;OJet:&lt;/STRONG&gt; A high-performance CDC method, typically used for Oracle 21c or very high-volume workloads that generate large amounts of redo logs.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;GoldenGate trail files:&lt;/STRONG&gt; If Oracle GoldenGate is already present, Striim can read from existing GoldenGate trail files rather than attaching another CDC process directly to the source database.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;All options are log-based, ensuring CDC overhead is typically in the low single-digit percentage range.&lt;/P&gt;
&lt;P&gt;Once chosen, ensure Striim can connect to Oracle over the JDBC listener port (default 1521). If Oracle is on-premises, this typically involves VPN/ExpressRoute or an SSH tunnel/jump host from Striim to the Oracle network before you can create a CDC user in Striim.&lt;/P&gt;
&lt;H3&gt;Creating a CDC user (example)&lt;/H3&gt;
&lt;P&gt;As an Oracle user, create a dedicated account for Striim and grant the required privileges for redo log access (exact grants may vary by version and CDC method). Please reference &lt;A href="https://www.striim.com/docs/en/oracle-database-cdc.html" target="_blank" rel="noopener"&gt;Striim’s Oracle CDC docs&lt;/A&gt; for the latest instructions:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;CREATE USER striim_user IDENTIFIED BY "StrongPassword!";&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;GRANT CONNECT, RESOURCE TO striim_user;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;-- Example privileges for redo/log views (adjust per security and Striim docs)&lt;/P&gt;
&lt;P&gt;GRANT SELECT ANY TRANSACTION TO striim_user;&lt;/P&gt;
&lt;P&gt;GRANT SELECT ON V_$LOG TO striim_user;&lt;/P&gt;
&lt;P&gt;GRANT SELECT ON V_$LOGFILE TO striim_user;&lt;/P&gt;
&lt;P&gt;GRANT SELECT ON V_$ARCHIVED_LOG TO striim_user;&lt;/P&gt;
&lt;P&gt;GRANT SELECT ON V_$DATABASE TO striim_user;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Once the user is created and networking is in place, Striim can be configured to connect to Oracle using a JDBC URL such as:&lt;/P&gt;
&lt;P&gt;jdbc:oracle:thin:@//&amp;lt;oracle-host&amp;gt;:1521/&amp;lt;service_name&amp;gt;&lt;/P&gt;
&lt;H2&gt;Step 2: Preparing Azure Database for PostgreSQL&lt;/H2&gt;
&lt;P&gt;On the target side, you must provision Azure Database for PostgreSQL and ensure schema, networking, and permissions are in place before starting data movement.&lt;/P&gt;
&lt;H3&gt;Schema creation&lt;/H3&gt;
&lt;P&gt;Prior to starting the data movement pipelines, create tables in Azure Database for PostgreSQL corresponding to those in the Oracle source. This can be done with:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Striim’s Schema Conversion Utility (CLI):&lt;/STRONG&gt; Generates SQL DDL for the target system based on Oracle metadata.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Striim’s wizard-based schema creation:&lt;/STRONG&gt; Creates target tables directly from the Striim UI during pipeline configuration.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;External tools:&lt;/STRONG&gt; You can also use existing schema migration utilities or custom DDL as required.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Permissions&lt;/H3&gt;
&lt;P&gt;Create an Azure DB for PostgreSQL user for Striim with write privileges on the target tables. For example:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;CREATE USER striim_user WITH PASSWORD 'strongpassword';&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;GRANT INSERT, UPDATE, DELETE, SELECT ON ALL TABLES IN SCHEMA public TO striim_user;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;ALTER DEFAULT PRIVILEGES IN SCHEMA public&lt;/P&gt;
&lt;P&gt;GRANT INSERT, UPDATE, DELETE, SELECT ON TABLES TO striim_user;&lt;/P&gt;
&lt;P&gt;Striim will use this user when running Database Writer components against Azure Database for PostgreSQL.&lt;/P&gt;
&lt;H2&gt;Step 3: Building the migration pipeline&lt;/H2&gt;
&lt;P&gt;A complete Oracle to Azure Database for PostgreSQL migration typically includes three coordinated stages:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Schema Migration – Create equivalent tables and objects in Azure Database for PostgreSQL.&lt;/LI&gt;
&lt;LI&gt;Initial Load – Bulk-load historical data from Oracle into Azure.&lt;/LI&gt;
&lt;LI&gt;Change Data Capture (CDC) – Continuously stream real-time transactions, keeping source and target in-sync until production cutover.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3&gt;Initial load &amp;amp; continuous stream&lt;/H3&gt;
&lt;P&gt;Once the schema is in place using one of the methods above, you can configure Striim to first bulk-load historical data, then switch to continuous CDC.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;During the initial load, Striim uses a Database Reader component to extract full tables from Oracle, and a Database Writer component to load them into Azure Database for PostgreSQL. The Striim applications can be built through a drag-and-drop interface, a wizard, or through a text-based interface, shown below.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The Database Writer uses a user-defined batch policy to control how data is written. By default (e.g., EventCount:1000, Interval:60s), Striim will write to PostgreSQL when either 1,000 events are accumulated or 60 seconds have passed, whichever happens first.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A conceptual example of an initial-load configuration using TQL might look like:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;CREATE SOURCE OracleInitialLoadReader USING DatabaseReader (&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Username:'striim_user',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Password:'strongpassword',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConnectionURL:'jdbc:oracle:thin:@//oracle-host:1521/ORCL',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Tables:'HR.EMPLOYEES'&lt;/P&gt;
&lt;P&gt;);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;CREATE TARGET PostgreSQLInitialLoadWriter USING DatabaseWriter (&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Username:'striim_user',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Password:'strongpassword',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConnectionURL:'jdbc:PostgreSQL://pg-host:5432/mydb',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mode:'Insert',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BatchPolicy:'EventCount:10000,Interval:30s'&lt;/P&gt;
&lt;P&gt;)&lt;/P&gt;
&lt;P&gt;INPUT FROM OracleInitialLoadReader;&lt;/P&gt;
&lt;H3&gt;Continuous CDC stream&lt;/H3&gt;
&lt;P&gt;After the initial load completes, Striim switches to a CDC pipeline that applies new Oracle transactions in real time until cutover. The CDC pipeline uses an Oracle CDC reader (Oracle Reader, OJet, or GoldenGate trail reader) and a Database Writer targeting Azure Database for PostgreSQL.&lt;/P&gt;
&lt;P&gt;A CDC example in TQL could look like:&lt;/P&gt;
&lt;P&gt;CREATE SOURCE OracleCDCReader USING OracleReader (&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Username:'striim_user',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Password:'strongpassword',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConnectionURL:'jdbc:oracle:thin:@//oracle-host:1521/ORCL',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Tables:'HR.EMPLOYEES'&lt;/P&gt;
&lt;P&gt;);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;CREATE TARGET PostgreSQLCDCWriter USING DatabaseWriter (&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Username:'striim_user',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Password:'strongpassword',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ConnectionURL:'jdbc:PostgreSQL://pg-host:5432/mydb',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mode:'UpdateOrInsert',&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BatchPolicy:'EventCount:1000,Interval:60s'&lt;/P&gt;
&lt;P&gt;)&lt;/P&gt;
&lt;P&gt;INPUT FROM OracleCDCReader;&lt;/P&gt;
&lt;P&gt;To ensure zero data loss, follow the sequencing guidelines in Striim’s documentation for switching from initial load to continuous replication.&lt;/P&gt;
&lt;H2&gt;Cutover&lt;/H2&gt;
&lt;P&gt;When the Azure Database for PostgreSQL environment is fully synchronized, and you are ready to move applications off Oracle:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Pause writes to Oracle. Temporarily stop application writes to the source.&lt;/LI&gt;
&lt;LI&gt;Validate record counts. Compare row counts (and optionally checksums or spot checks) between Oracle and Azure Database for PostgreSQL. Striim has recently released a new tool called Validata to automatically do this. Please &lt;A href="https://www.striim.com/contact-us/?tracker=validata" target="_blank" rel="noopener"&gt;reach out&lt;/A&gt; to learn more.&lt;/LI&gt;
&lt;LI&gt;Redirect application traffic to Azure Database for PostgreSQL. Update connection strings so applications now point at the Azure PostgreSQL instance.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Because Striim’s CDC keeps the source and target continuously in sync, the cutover window is typically very short, minimizing or eliminating downtime for end users.&lt;/P&gt;
&lt;H2&gt;Adding Transformations and Smart Data Pipelines&lt;/H2&gt;
&lt;P&gt;Beyond one-to-one replication, Striim allows you to enrich, transform, and validate data in flight using continuous SQL queries or custom Java processors. For example, you can append metadata for auditing:&lt;/P&gt;
&lt;P&gt;SELECT *, CURRENT_TIMESTAMP() AS event_time, OpType() AS operation FROM SQLServerStream;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These Smart Data Pipelines enable in-stream transformations (e.g., deduplication, validation, or enrichment) without separate ETL jobs, streamlining modernization into a single continuous flow.&lt;/P&gt;
&lt;H2&gt;Performance Expectations&lt;/H2&gt;
&lt;P&gt;In joint Striim–Microsoft testing:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1 TB historical load typically completed in 4–6 hours, which can be further performance-tuned to decrease initial load time.&lt;/LI&gt;
&lt;LI&gt;CDC replication latency averages sub-second for inserts, updates, and deletes.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Performance depends on schema complexity, hardware, and network configuration. For optimal results:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Deploy Striim in the same Azure region as the target.&lt;/LI&gt;
&lt;LI&gt;Use private networking.&lt;/LI&gt;
&lt;LI&gt;Allocate adequate CPU and memory to handle peak CDC throughput.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Support and Enablement&lt;/H2&gt;
&lt;P&gt;The Microsoft Unlimited Database Migration Program is designed specifically to provide customers direct access to Striim’s field expertise throughout the migration process.&lt;/P&gt;
&lt;P&gt;From end-to-end, you can expect:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Onboarding and ongoing support, including installation kits and walkthroughs.&lt;/LI&gt;
&lt;LI&gt;Higher-tier service packages are available as well.&lt;/LI&gt;
&lt;LI&gt;Direct escalation paths to Striim for issue resolution and continuous assistance during migration and replication.&lt;/LI&gt;
&lt;LI&gt;Professional services and funding flexibility, such as ECIF coverage for partner engagements, cutover or weekend go-live standby, and pre-approved service blocks to simplify SOW approvals.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Together, these resources ensure migrations from Oracle to Azure DB for PostgreSQL are fully supported from initial enablement through post-cutover operations, backed by Microsoft and Striim’s combined teams.&lt;/P&gt;
&lt;P&gt;Whether your goal is one-time migration or continuous hybrid replication, Striim’s CDC engine, combined with Azure’s PostgreSQL Database, ensures every transaction lands with integrity. Start your modernization journey today by connecting with &lt;A href="http://striim.com" target="_blank" rel="noopener"&gt;Striim&lt;/A&gt; directly through your Microsoft representative.&lt;/P&gt;</description>
      <pubDate>Wed, 13 May 2026 16:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-data-migration-blog/zero-downtime-migration-from-oracle-to-azure-db-for-postgresql/ba-p/4518563</guid>
      <dc:creator>Matthew_Burrows</dc:creator>
      <dc:date>2026-05-13T16:00:00Z</dc:date>
    </item>
    <item>
      <title>Azure Cache for Redis to Azure Managed Redis: A Practical Guide with AI-Assisted Migration Planning</title>
      <link>https://techcommunity.microsoft.com/t5/azure-managed-redis/azure-cache-for-redis-to-azure-managed-redis-a-practical-guide/ba-p/4517596</link>
      <description>&lt;P&gt;Author: Purna Mehta, Product Manager, Redis Inc and Shruti Pathak, Product Manager, Microsoft&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Today we’re introducing two capabilities for migrating from Azure Cache for Redis (ACR) to Azure Managed Redis (AMR): an AI-assisted planning skill and a native migration workflow in the Azure portal. Used together, these tools provide a structured path from initial assessment to a fully cleaned-up Azure Managed Redis deployment.&lt;/P&gt;
&lt;P&gt;This post walks through each phase of the migration, what to expect at each step, and how the agent and portal work together to reduce complexity and risk.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;Why Migrate to Azure Managed Redis?&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;Azure Managed Redis is Microsoft’s next-generation managed Redis offering for enterprise workloads on Azure. It delivers higher throughput and lower latency than Azure Cache for Redis, along with flexible SKU tiers, enhanced clustering, active geo-replication, and advanced persistence options.&lt;/P&gt;
&lt;P&gt;Azure Managed Redis supports Redis-based AI workloads on Azure, including integrations for vector search and intelligent caching. If you’re building AI-powered applications on Azure, Azure Managed Redis is the recommended platform for Redis-based scenarios.&lt;/P&gt;
&lt;P&gt;We recognize that migrating a production cache requires care. That is why we built an end-to-end experience that begins with AI-assisted planning and ends with a guided portal migration.&lt;/P&gt;
&lt;P&gt;There is also a practical reason to start planning now: Azure Cache for Redis is being retired, and Azure Managed Redis is the path forward for Redis workloads on Azure. Migrating early gives you time to validate dependencies, update configurations, and make the transition on your own schedule instead of under deadline pressure. Just as importantly, the Azure Cache for Redis hostname will eventually expire, so cleaning up references to the old hostname is an important part of completing the migration cleanly. For details, see &lt;A href="https://azure.microsoft.com/en-us/updates?id=499577" target="_blank" rel="noopener"&gt;the retirement announcement&lt;/A&gt; and &lt;A href="https://techcommunity.microsoft.com/blog/azure-managed-redis/azure-cache-for-redis-retirement-what-to-know-and-how-to-prepare/4458721" target="_blank" rel="noopener"&gt;this blog post&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The rest of this post outlines the planning and execution phases for migrating from Azure Cache for Redis to Azure Managed Redis with the Redis migration tooling.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;Phase 1: Migration Planning&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;Before touching any infrastructure, you need a clear view of what you are migrating, what the target should look like, and which risks to address. The new A&lt;A href="https://github.com/AzureManagedRedis/amr-migration-skill" target="_blank" rel="noopener"&gt;zure Cache for Redis migration agent skill&lt;/A&gt; helps with that. You can also refer to the migration documentation &lt;A href="https://learn.microsoft.com/azure/redis/migrate/migrate-basic-standard-premium-overview" target="_blank" rel="noopener"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;The migration agent skill can be added to any AI agent and invoked from AI-powered chat assistants such as GitHub Copilot and Claude. With read access to your Azure subscription, the skill can inspect your existing Azure Cache for Redis instances and help you:&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Compare and contrast Azure Cache for Redis and Azure Managed Redis&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Guide through selecting the appropriate Azure Managed Redis SKUs&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Help convert IaC templates&lt;/P&gt;
&lt;P&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Help with planning and execution of migration along with troubleshooting common issues&lt;/P&gt;
&lt;P&gt;You interact with it conversationally, asking questions and refining the plan iteratively until you are confident in the approach.&lt;/P&gt;
&lt;P&gt;In a typical planning session, the skill analyzes your source cache configuration in detail, including SKU and tier, memory size, eviction policy, persistence settings, clustering topology, TLS configuration, and any geo-replication setup. It then maps those properties to available Azure Managed Redis tiers and recommends the most appropriate target configuration for your workload. The skill can also fetch real-time cache usage metrics and recommend SKU optimizations.&lt;/P&gt;
&lt;P&gt;Beyond the SKU recommendation, the skill identifies potential compatibility issues and configuration gaps you need to address before migrating. This might include client library version requirements, changes to supported Redis commands, differences in eviction policy behavior between tiers, or networking considerations if your cache is deployed in a VNet. Surfacing these issues early, before you have provisioned anything, gives you time to address them without pressure.&lt;/P&gt;
&lt;P&gt;The skill can also help you choose a migration strategy. If downtime tolerance is low, it walks you through online migration options and what to expect during cutover. If your workload can tolerate a maintenance window, it can outline a simpler offline path. You can also ask follow-up questions about cost, rollback, or how to validate the new instance before switching traffic.&lt;/P&gt;
&lt;P&gt;At the end of the planning session, ask the agent for a structured migration checklist. It should summarize the recommended target configuration, pre-migration action items, and the step-by-step plan for Phases 2 and 3. This gives your team a shared reference for execution.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 87.3148%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;EM&gt;Note: The AI-assisted migration planner is intended to support planning, not replace expert judgment. For highly critical workloads, we recommend working closely with a Solutions Architect or migration specialist to validate your plan before proceeding.&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;STRONG&gt;Phase 2: Provision the Target Azure Managed Redis Cache&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;With a clear migration plan from Phase 1, you are ready to create your Azure Managed Redis target instance. This step is straightforward, but one constraint matters: the target AMR cache must be in the same subscription and region as the source ACR cache. This is a requirement of the portal migration workflow in Phase 3, which links the two instances together to perform the migration.&lt;/P&gt;
&lt;P&gt;In the Azure portal, create a new Azure Managed Redis resource in the same subscription and region as your source cache. Apply the tier and SKU recommended in Phase 1, whether that is Balanced for general-purpose workloads, Memory Optimized for memory-intensive scenarios, or Compute Optimized for throughput-heavy applications. Configure the instance as outlined in your migration checklist, including Redis Users for Entra ID authentication, private endpoints, eviction policy, persistence, clustering, and TLS. The migration agent skill can also help update your IaC templates by converting them from Azure Cache for Redis to Azure Managed Redis.&lt;/P&gt;
&lt;P&gt;Once the instance is provisioned and running, note the resource name. You will select it by name when you start migration in Phase 3. At this point the AMR instance is empty, which lets you validate the configuration, test connectivity from your application environment, and confirm everything looks correct before migration.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 95.2778%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;EM&gt;Note: Redis Migration tooling works by switching the DNS endpoint from your source Azure Cache for Redis instance to the target Azure Managed Redis instance. No data is transferred as part of this process.&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;STRONG&gt;Phase 3: Initiate Migration from the Azure Portal&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;&lt;EM&gt;Note: Before using the Redis migration tooling, please review the&amp;nbsp;&lt;/EM&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/redis/migrate/migrate-basic-standard-premium-options#limitations" target="_blank" rel="noopener"&gt;&lt;EM&gt;limitations of the tooling&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt; and &lt;/EM&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/redis/migrate/migrate-basic-standard-premium-options" target="_blank" rel="noopener"&gt;&lt;EM&gt;other migration options&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;To use the Redis Migration tooling, navigate to your source Azure Cache for Redis instance in the Azure Portal and select Migrate in the command bar.&lt;/P&gt;
&lt;P&gt;Choose a target Azure Managed Redis instance from the dropdown, which lists only AMR instances in the same subscription and region as your source cache.&lt;/P&gt;
&lt;P&gt;Review the migration summary comparing source and target configurations. An automated compatibility check surfaces warnings or errors with guidance for resolving them. You can acknowledge warnings to proceed, but errors must be addressed first. &lt;STRONG&gt;We strongly recommend running the migration during a maintenance window or low-traffic period.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Your resource state will update to “Migrating” while the migration is in process. After migration completes, the Azure Cache for Redis hostname redirects requests to the Azure Managed Redis instance, allowing applications to continue using the existing source connection string temporarily.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 97.1296%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;EM&gt;Note: Keep your source ACR cache running and do not delete it. If you encounter problems after the migration, you can initiate a rollback to the original ACR cache and resume normal operation while you investigate. The source cache remains available and unchanged throughout the migration process. Once you are confident the new instance is stable and performing as expected, you can retry Phase 3 and then proceed to Phase 4 to clean up the source cache.&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;STRONG&gt;Phase 4: Ensure success and delete old Azure Cache for Redis instance &lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;After migration, monitor application health to confirm everything is working as expected. If issues arise, you can roll back the migration. Once you have verified success, you can delete the source Azure Cache for Redis instance. &lt;EM&gt;The Azure Cache for Redis instance is now decoupled from its hostname and can be deleted safely.&lt;/EM&gt; The hostname will continue to point to the new Azure Managed Redis instance.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;Phase 5: Update applications to use the Azure Managed Redis hostname&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;After you confirm the migrated Azure Managed Redis instance is running as expected, update your applications to use the Azure Managed Redis connection string instead of the old Azure Cache for Redis connection string. This step is required because the old Azure Cache for Redis hostname will be purged automatically. Because traffic is already flowing to the migrated instance, this update should have minimal impact.&lt;/P&gt;
&lt;P&gt;It is easy to postpone this step, but doing it promptly keeps your subscription clean, avoids unnecessary cost, and removes ambiguity about which cache instance is active.&lt;/P&gt;
&lt;P&gt;The main cleanup task is purging the source Azure Cache for Redis hostname. Before you do, confirm that no applications or services still reference the old connection string, including Key Vault secrets, environment variables, monitoring dashboards, and background jobs. Take a few minutes to search broadly, since any missed reference will fail after the old hostname is purged.&lt;/P&gt;
&lt;P&gt;Once all references have been updated, use the ‘unlink’ API to purge the source Azure Cache for Redis hostname. If the Azure Cache for Redis instance has associated resources such as private endpoints, or diagnostic settings, review whether they should be removed or reconfigured for the new AMR instance. Finally, update any internal documentation, runbooks, and architecture diagrams that still reference the old cache. At that point, the migration is complete.&lt;/P&gt;
&lt;H2&gt;&lt;STRONG&gt;Getting Started&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P&gt;Both the migration planning agent skill and the portal migration workflow are available today. Here is how to get started:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The migration agent skill is available &lt;A href="https://github.com/AzureManagedRedis/amr-migration-skill" target="_blank" rel="noopener"&gt;here&lt;/A&gt; and includes setup instructions.&lt;/LI&gt;
&lt;LI&gt;To provision your Azure Managed Redis target, find instructions &lt;A href="https://learn.microsoft.com/en-us/azure/redis/quickstart-create-managed-redis" target="_blank" rel="noopener"&gt;here&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;To start migration, go to your source Azure Cache for Redis cache in the Azure portal and select "Migrate to Azure Managed Redis" from the command bar. More details about the migration tooling are available &lt;A href="https://learn.microsoft.com/azure/redis/migrate/migrate-basic-standard-premium-with-tooling" target="_blank" rel="noopener"&gt;here&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;We recommend starting every migration with a session with the planning agent, even when the migration seems straightforward. It consistently surfaces configuration details and compatibility issues that are easy to miss and can cause problems later. A few minutes of planning up front is well worth the time.&lt;/P&gt;
&lt;P&gt;Reach us at &lt;A href="mailto:AzureManagedRedis@microsoft.com" target="_blank" rel="noopener"&gt;AzureManagedRedis@microsoft.com&lt;/A&gt; or through your account team with questions, suggestions, or stories from your migration journey.&lt;/P&gt;</description>
      <pubDate>Tue, 12 May 2026 16:30:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/azure-managed-redis/azure-cache-for-redis-to-azure-managed-redis-a-practical-guide/ba-p/4517596</guid>
      <dc:creator>Shruti_Pathak</dc:creator>
      <dc:date>2026-05-12T16:30:00Z</dc:date>
    </item>
  </channel>
</rss>

