<?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>Microsoft Blog for PostgreSQL articles</title>
    <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/bg-p/ADforPostgreSQL</link>
    <description>Microsoft Blog for PostgreSQL articles</description>
    <pubDate>Mon, 10 Aug 2026 06:52:04 GMT</pubDate>
    <dc:creator>ADforPostgreSQL</dc:creator>
    <dc:date>2026-08-10T06:52:04Z</dc:date>
    <item>
      <title>Get started faster in the PostgreSQL extension for VS Code</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/get-started-faster-in-the-postgresql-extension-for-vs-code/ba-p/4543578</link>
      <description>&lt;P&gt;The PostgreSQL extension for Visual Studio Code now includes a Get Started landing page that helps you discover key features, access helpful resources, and become productive faster after connecting to a server.&lt;/P&gt;
&lt;P&gt;The image below shows the Get Started landing page, highlighting quick-action cards, learning resources, and featured updates available after you connect to a server.&lt;/P&gt;
&lt;img /&gt;
&lt;H5&gt;Quick Actions&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Each entry point applies to the database you have selected, so whatever you click picks up from the connection you just made.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H5&gt;&lt;SPAN data-contrast="auto"&gt;Explore additional resources to navigate to PostgreSQL documentation&lt;/SPAN&gt;&lt;/H5&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;img /&gt;&lt;/DIV&gt;
&lt;H4&gt;&lt;SPAN data-contrast="auto"&gt;View at your Convenience&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;The landing page is shown only after a new server connection is added. Users who do not wish to see this page can disable it by clearing the&amp;nbsp;&lt;STRONG&gt;"&lt;/STRONG&gt;&lt;EM&gt;Show this page after adding a new connection&lt;/EM&gt;&lt;STRONG&gt;"&lt;/STRONG&gt; option at the bottom of the landing page.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;Open the landing page anytime:&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;Right-click any server in the connections tree and choose &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Get Started.&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;:0,&amp;quot;335551620&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;&lt;SPAN data-contrast="auto"&gt;Try it out&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Head over to &lt;A class="lia-external-url" href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql" target="_blank" rel="noopener"&gt;PostgreSQL for Visual Studio Code&lt;/A&gt; and spin up a new server connection, or right-click a server you already have and choose Get Started.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Your feedback helps us improve. If you have ideas, suggestions, or resources you’d like to see included, reach out to&amp;nbsp;&lt;STRONG&gt;AskAzurePostgreSQL@microsoft.com&lt;/STRONG&gt; and help shape the experience for the PostgreSQL community.&lt;/P&gt;</description>
      <pubDate>Fri, 07 Aug 2026 18:50:43 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/get-started-faster-in-the-postgresql-extension-for-vs-code/ba-p/4543578</guid>
      <dc:creator>jane-yoon</dc:creator>
      <dc:date>2026-08-07T18:50:43Z</dc:date>
    </item>
    <item>
      <title>AI-assisted Oracle-to-PostgreSQL schema conversion in Visual Studio Code</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ai-assisted-oracle-to-postgresql-schema-conversion-in-visual/ba-p/4542203</link>
      <description>&lt;P&gt;&lt;STRONG&gt;By AI Omar Rajawat, Pranay Lohia, Gautam Juneja, Vikas Nimmagadda, Anil Dogra, Aditya Duvuri&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We’re seeing significant interest in migrating database workloads from Oracle to Azure Database for PostgreSQL. Historically, schema conversion has been one of the most technically challenging and expensive steps in that journey, demanding specialist knowledge of both engines and stretching migration timelines before a single row of data moves. Recent advances in AI-assisted schema conversion are changing that, turning what used to be a long, manual effort into a faster, more accessible, and lower-cost proposition. This post looks at what that shift means in practice for teams moving to Azure Database for PostgreSQL flexible server.&lt;/P&gt;
&lt;P&gt;Oracle schema conversion is where the complexity of translating schema and code objects to PostgreSQL becomes visible. Packages, procedures, triggers, custom types, and dependencies built up over years must be mapped to PostgreSQL-compatible definitions while preserving the relationships that make the schema work.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Generally available since May 2026, the feature is built into the PostgreSQL extension for Visual Studio Code, published by Microsoft. It helps teams convert Oracle schema and code objects — tables, views, constraints, packages, procedures, functions, and triggers — into PostgreSQL-compatible definitions for Azure Database for PostgreSQL flexible server, with no separate conversion utility to install and no disconnected workflow to manage.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;It brings schema discovery, conversion, compile validation, and review into one project-based experience. Teams can connect to Oracle, select schemas, and configure a Microsoft Foundry connection in the same project. The extension then translates Oracle-specific constructs, compiles and syntax-checks converted DDL into scratch schemas on Azure Database for PostgreSQL flexible server and surfaces unresolved items as review tasks that teams can work through with GitHub Copilot agent mode.&lt;/P&gt;
&lt;H2&gt;Why schema conversion deserves a better workflow&lt;/H2&gt;
&lt;P&gt;Traditional conversion tools can produce a useful first pass, but the long tail of the process is rarely solved by generating replacement DDL alone. Teams still need clear answers to practical questions: What converted successfully? What needs attention? Which Oracle constructs require a PostgreSQL design decision? Which items should be reviewed first?&lt;/P&gt;
&lt;P&gt;We designed the schema conversion experience around those questions. The goal is not to hide complexity behind a single score. It is to help teams make steady progress while keeping the work visible and reviewable.&lt;/P&gt;
&lt;H2&gt;What the schema conversion experience provides&lt;/H2&gt;
&lt;P&gt;The experience guides teams through a schema conversion project rather than a collection of separate scripts. It discovers the selected Oracle schemas and converts both the relational model and the code that runs on it: tables, indexes, sequences, primary key, unique, check and foreign key constraints, views and materialized views, synonyms, and Oracle object types — along with the PL/SQL that is usually the hardest part of the migration. Packages and package bodies, package-level state, standalone procedures and functions, and triggers are translated into PostgreSQL functions, procedures, and trigger functions.&lt;/P&gt;
&lt;P&gt;Oracle-specific constructs are mapped to PostgreSQL equivalents rather than dropped or stubbed out. REF CURSOR and SYS_REFCURSOR become PostgreSQL refcursor; CLOB and BLOB columns become text and bytea ; and NUMBER and VARCHAR2 are mapped by precision and length to their closest PostgreSQL types. Oracle date functions such as ADD_MONTHS, LAST_DAY, MONTHS_BETWEEN, and TRUNC are resolved through the orafce extension, which the project detects and flags for you before deployment. Every converted definition is compiled against scratch schemas on Azure Database for PostgreSQL flexible server, so the deployment script you end up with is an organized, dependency-ordered set of PostgreSQL SQL artifacts that has already been proven to build.&lt;/P&gt;
&lt;P&gt;Objects that still require human judgment are surfaced as review tasks. Teams can inspect the source and converted definitions side by side, work through the remaining items, and use GitHub Copilot agent mode for guided assistance — keeping automation and human review in the same workflow.&lt;/P&gt;
&lt;H2&gt;How it works: the system architecture&lt;/H2&gt;
&lt;P&gt;Under the hood, the conversion engine follows one principle — &lt;STRONG&gt;the language model is a single, bounded stage; it never has the first or the last word.&lt;/STRONG&gt; Deterministic steps decide what the model sees and what it is allowed to produce.&lt;/P&gt;
&lt;img /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Deterministic in.&lt;/STRONG&gt; Rule-based extraction reads the Oracle DDL and metadata, then a dependency-graph decomposition splits the estate into bounded, dependency-ordered chunks — so every object is converted in the context that keeps it correct.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Bounded conversion.&lt;/STRONG&gt; A tiered model strategy through the Microsoft Foundry connection translates each chunk with structured, contract-wrapped input and output. Even very large PL/SQL packages are split and converted member by member, so nothing is trusted as a monolith.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deterministic out.&lt;/STRONG&gt; Converted objects pass through review, then compile-and-verify against scratch schemas on Azure Database for PostgreSQL flexible server, and finally dependency-ordered deploy assembly. Unresolved items become review tasks, and every object carries a per-object audit trail.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;A continuous-improvement loop closes the system: the engineering team maintains a versioned regression suite of supported conversion patterns, and an executable benchmark tracks regressions as the pipeline evolves.&lt;/P&gt;
&lt;H2&gt;Proven in production&lt;/H2&gt;
&lt;P&gt;The approach has been exercised on real enterprise estate. Across representative production runs totaling &lt;STRONG&gt;more than 60,000 schema objects;&lt;/STRONG&gt; conversion reached roughly &lt;STRONG&gt;98% overall&lt;/STRONG&gt; — with several schemas converting at a full &lt;STRONG&gt;100%&lt;/STRONG&gt;. The hardest tail, PL/SQL package members, now compiles at &lt;STRONG&gt;96%&lt;/STRONG&gt; across more than 20,000 members thanks to targeted coverage and a resilient compile stage.&lt;/P&gt;
&lt;P&gt;Conversion outcome and review status are separate measures. Objects that convert and compile cleanly are safe to deploy as they are; the rest are deliberately routed into a prioritized review queue rather than silently accepted. In a representative single-schema run, no object ended in a hard conversion failure, and a cleanly generated object can still involve a PostgreSQL design decision. That is the workflow operating as intended: automation absorbs the volume, and review tasks to keep the remaining judgment calls visible, ordered, and auditable.&lt;/P&gt;
&lt;H2&gt;Measured, not asserted: the SchemaBench eval&lt;/H2&gt;
&lt;P&gt;Quality is verified by &lt;STRONG&gt;running&lt;/STRONG&gt; it. &lt;STRONG&gt;SchemaBench&lt;/STRONG&gt;, the evaluation framework, deploys each converted schema to a live PostgreSQL database and probes real behavior — whether constraints still fire and whether objects still resolve — rather than comparing DDL text. It scores seven weighted dimensions: semantic fidelity, structure, constraints, completeness, performance, target idioms, and maintainability, behind hard gates. On the e-commerce benchmark, the strongest model scored &lt;STRONG&gt;96.1&lt;/STRONG&gt; overall with &lt;STRONG&gt;100% semantic fidelity&lt;/STRONG&gt; and a &lt;STRONG&gt;~98% behavioral-probe pass rate&lt;/STRONG&gt;. Every failure a migration hits becomes a permanent regression test the next run has to pass.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Learn more: &lt;/STRONG&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/migrate/oracle-conversions-schema/schema-conversions-overview" target="_blank" rel="noopener"&gt;Oracle to Azure Database for PostgreSQL schema conversion overview&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 07 Aug 2026 15:27:13 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ai-assisted-oracle-to-postgresql-schema-conversion-in-visual/ba-p/4542203</guid>
      <dc:creator>adityaduvuri</dc:creator>
      <dc:date>2026-08-07T15:27:13Z</dc:date>
    </item>
    <item>
      <title>Faster, Safer Version Upgrades for Databases with Large Objects</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/faster-safer-version-upgrades-for-databases-with-large-objects/ba-p/4543623</link>
      <description>&lt;MAIN style="max-width: 920px; margin: 0 auto; padding: 36px 28px 56px 28px; font-family: 'Segoe UI', Arial, sans-serif;"&gt;
&lt;P style="font-family: 'Segoe UI', Arial, sans-serif; color: #605e5c; font-size: 18px; line-height: 1.4; margin: 0 0 10px 0;"&gt;By Varun Dhawan, Ilan Benschikovski, and Alexander Kukushkin - Azure PostgreSQL, Microsoft&lt;/P&gt;
&lt;H1 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 42px; line-height: 1.12; margin: 0 0 18px 0; font-weight: bold; letter-spacing: -0.3px;"&gt;Faster, Safer Upgrades for Databases with Large Objects&lt;/H1&gt;
&lt;DIV style="border: 3px solid #0078D4; background: #F7FBFF; padding: 14px 16px; margin: 20px 0 34px 0; font-family: 'Segoe UI', Arial, sans-serif;"&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.5; margin: 0;"&gt;&lt;STRONG&gt;TL;DR:&lt;/STRONG&gt; We improved &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;major version upgrades&lt;/A&gt; for PostgreSQL databases with very high large-object counts. For upgrades targeting PostgreSQL 15 and later, large-object metadata is now handled more efficiently, reducing memory/temp-space pressure and helping previously risky upgrades complete more reliably.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Why this matters&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;Some PostgreSQL workloads store documents, images, PDFs, scanned files, or attachments as large objects (LOBs). In normal operations this is fine. But during a major version upgrade, very high LOB counts could make the schema dump step slow, memory-heavy, or fail.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;This improvement is about making that upgrade path safer and more predictable for Azure Database for PostgreSQL flexible server customers.&lt;/P&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;What changed?&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;During a major version upgrade, PostgreSQL uses &lt;A class="lia-external-url" href="https://www.postgresql.org/docs/current/pgupgrade.html" target="_blank" rel="noopener"&gt;&lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 14px; color: #0969da;"&gt;pg_upgrade&lt;/CODE&gt;&lt;/A&gt;, which internally runs &lt;A class="lia-external-url" href="https://www.postgresql.org/docs/current/app-pgdump.html" target="_blank" rel="noopener"&gt;&lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 14px; color: #0969da;"&gt;pg_dump&lt;/CODE&gt;&lt;/A&gt; to move schema and metadata into the new version.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;For databases with millions of large objects, the older upgrade path handled &lt;A class="lia-external-url" href="https://www.postgresql.org/docs/current/lo-intro.html" target="_blank" rel="noopener"&gt;large-object metadata&lt;/A&gt; one object at a time. That created high memory and temporary-space pressure during the schema dump phase.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;&lt;STRONG&gt;This fix changes the upgrade path.&lt;/STRONG&gt; Instead of processing large-object metadata one object at a time, PostgreSQL now transfers that metadata in bulk. The actual large-object data is not changed; only the upgrade metadata handling is improved.&lt;/P&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Why this is different&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;This improvement builds on upstream PostgreSQL work that makes large-object metadata handling more efficient during upgrades. We brought that benefit into Azure Database for PostgreSQL flexible server for supported PostgreSQL 15+ upgrade targets, so customers with large-object-heavy workloads can benefit without waiting for a future PostgreSQL major version.&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 22px; margin: 28px 0 8px 0;"&gt;Before vs after&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;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Area&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Before&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;After&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Metadata handling&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;One operation per large object&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Bulk metadata transfer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Memory/temp pressure&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Grew heavily with LOB count&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Much flatter and more predictable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;High LOB counts&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Risk of OOM or temp-space failure&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Completes more reliably for PostgreSQL 15+ targets&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Customer workaround&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 13px;"&gt;vacuumlo&lt;/CODE&gt; + scale-up often needed&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Less reliance on LOB-specific workarounds for PostgreSQL 15+ targets&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;DIV style="border: 3px solid #8DBEE8; background: #FFFFFF; padding: 10px 12px; margin: 10px 0 30px 0;"&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.5; margin: 0;"&gt;&lt;STRONG&gt;In plain English:&lt;/STRONG&gt; the upgrade no longer has to carry paperwork for every large object one by one. It moves the metadata in bulk, which makes the upgrade faster, safer, and less likely to fail at very high LOB counts.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;The numbers&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 10px 0;"&gt;We tested upgrades from PostgreSQL 13 with large-object counts ranging from 10M to 500M. The older path is represented by PostgreSQL 13 → 14. The improved path is represented by PostgreSQL 13 → 15.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.5; margin: 0 0 18px 0;"&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; These figures come from a multi-database test where large objects were spread across 100 databases. Because &lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 14px;"&gt;pg_dump&lt;/CODE&gt; runs per database, single-database workloads with the same total large-object count may see different runtimes.&lt;/P&gt;
&lt;P&gt;Cap&lt;/P&gt;
&lt;img&gt;Illustration: Bar chart comparing major version upgrade runtime for the older and improved large-object paths. At 10 million large objects, runtime drops from 48 to 16 minutes; at 20 million, from 62 to 18 minutes; and at 30 million, from 161 to 21 minutes.&lt;/img&gt;&lt;img&gt;Illustration: Bar chart showing upgrade speedup at increasing large-object counts. The improved path is 3× faster at 10 million large objects, 3.4× faster at 20 million, and 7.6× faster at 30 million.&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 22px; margin: 26px 0 8px 0;"&gt;Outcome summary&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;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Large objects&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Older path&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Improved path&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;What changed&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;10M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;48 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;16 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;3x faster&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;20M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;1h 02m&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;18 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;3.4x faster&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;30M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;2h 41m&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;21 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;7.6x faster&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;50M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #a4262c;"&gt;Failed at higher scale&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;26-30 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;Now completes&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;100M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #a4262c;"&gt;Failed&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;54 min&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;Now completes&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;500M&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #a4262c;"&gt;Failed&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;4h 01m&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;&lt;STRONG style="color: #107c10;"&gt;Now completes&lt;/STRONG&gt;&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 class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.5; margin: 0 0 26px 0;"&gt;&lt;STRONG&gt;Key takeaway:&lt;/STRONG&gt; this is not just faster. At higher LOB counts, the improvement changes the outcome from upgrade fails to upgrade completes.&lt;/P&gt;
&lt;img&gt;Illustration: Line chart showing runtime for the improved upgrade path from 10 million to 500 million large objects. Runtime increases from 16 minutes at 10 million to 54 minutes at 100 million and 4 hours 1 minute at 500 million, with all tested upgrades completing successfully.&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Who benefits from this?&lt;/H2&gt;
&lt;P style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 16px 0;"&gt;You should care if your database stores large binary content using PostgreSQL large objects.&lt;/P&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;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Workload pattern&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Why it matters&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Document management&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;PDFs, contracts, scans, and archived files&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Attachment-heavy apps&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Files stored inside PostgreSQL instead of external storage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Legacy apps using &lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 13px;"&gt;lo&lt;/CODE&gt; APIs&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;LOBs may have accumulated for years&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Image/archive systems&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Millions of binary objects can build up quietly&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Previous upgrade failures&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Failures during schema dump may map to this scenario&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;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Copy/paste: check your large-object count&lt;/H2&gt;
&lt;P style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.55; margin: 0 0 12px 0;"&gt;Run these checks in each database you plan to upgrade.&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 21px; margin: 22px 0 8px 0;"&gt;1. Count large objects in the current database&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Count PostgreSQL large objects in the current database
SELECT
  current_database() AS database_name,
  count(*) AS large_object_count
FROM pg_largeobject_metadata;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 21px; margin: 22px 0 8px 0;"&gt;2. Check large-object storage footprint&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Estimate large-object data and metadata size
SELECT
  pg_size_pretty(pg_total_relation_size('pg_largeobject'::regclass)) AS large_object_data_size,
  pg_size_pretty(pg_total_relation_size('pg_largeobject_metadata'::regclass)) AS large_object_metadata_size;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 21px; margin: 22px 0 8px 0;"&gt;3. Understand ownership and ACL shape&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Inspect large-object metadata shape
SELECT
  count(*) AS total_large_objects,
  count(lomacl) AS large_objects_with_custom_acl,
  count(DISTINCT lomowner) AS distinct_large_object_owners
FROM pg_largeobject_metadata;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 style="font-family: 'Segoe UI', Arial, sans-serif; color: #0078d4; font-size: 21px; margin: 22px 0 8px 0;"&gt;4. Find top large-object owners&lt;/H3&gt;
&lt;LI-CODE lang="sql"&gt;-- Top large-object owners
SELECT
  lomowner::regrole AS owner,
  count(*) AS large_object_count
FROM pg_largeobject_metadata
GROUP BY lomowner
ORDER BY large_object_count DESC
LIMIT 10;&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;What should I do before my next major version upgrade?&lt;/H2&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;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;If your situation is...&lt;/th&gt;&lt;th class="lia-border-color-custom-c8ddf2 lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Recommended action&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Target is PostgreSQL 15 or later&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Target &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-supported-versions" target="_blank" rel="noopener"&gt;PostgreSQL 15 or later&lt;/A&gt; to benefit from improved large-object metadata handling.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Target is PostgreSQL 14 or earlier&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Prefer PostgreSQL 15+ where possible; very high LOB counts may still hit older-path limitations.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Very large or unusual database&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Restore a copy and rehearse the upgrade before production.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Suspected orphan LOBs&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Consider &lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 13px;"&gt;vacuumlo&lt;/CODE&gt; only after testing. It can delete valid LOBs if your app uses custom references.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Any major version upgrade&lt;/td&gt;&lt;td class="lia-border-color-custom-c8ddf2 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 9px 10px;"&gt;Keep healthy free space and leverage &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;pre-upgrade validation checks&lt;/A&gt; to validate extension/schema compatibility first.&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;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Bottom line&lt;/H2&gt;
&lt;DIV style="border: 3px solid #107C10; background: #F8FFF8; padding: 13px 15px; margin: 10px 0 32px 0; font-family: 'Segoe UI', Arial, sans-serif;"&gt;
&lt;P class="lia-align-justify" style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 18px; line-height: 1.5; margin: 0;"&gt;If large objects were making your PostgreSQL upgrade risky, this improvement makes the upgrade path safer and more predictable. For large-object-heavy databases, upgrades targeting PostgreSQL 15 and later now show faster runtime, lower memory/temp-space pressure, and successful validation up to 500M large objects.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2 style="font-family: 'Segoe UI', Arial, sans-serif; color: #005a9e; font-size: 28px; line-height: 1.25; margin: 34px 0 10px 0; font-weight: bold;"&gt;Learn more&lt;/H2&gt;
&lt;UL style="font-family: 'Segoe UI', Arial, sans-serif; color: #1f1f1f; font-size: 16px; line-height: 1.65; margin: 0 0 20px 22px; padding: 0;"&gt;
&lt;LI&gt;&lt;A style="color: #0078d4; text-decoration: underline;" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;Major version upgrades in Azure Database for PostgreSQL flexible server&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A style="color: #0078d4; text-decoration: underline;" href="https://learn.microsoft.com/azure/postgresql/flexible-server/how-to-perform-major-version-upgrade" target="_blank" rel="noopener"&gt;How to perform a major version upgrade&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A style="color: #0078d4; text-decoration: underline;" href="https://www.postgresql.org/docs/current/vacuumlo.html" target="_blank" rel="noopener"&gt;PostgreSQL &lt;CODE style="font-family: Consolas, 'Courier New', monospace; font-size: 14px;"&gt;vacuumlo&lt;/CODE&gt; documentation&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/MAIN&gt;</description>
      <pubDate>Wed, 05 Aug 2026 00:50:15 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/faster-safer-version-upgrades-for-databases-with-large-objects/ba-p/4543623</guid>
      <dc:creator>varun-dhawan</dc:creator>
      <dc:date>2026-08-05T00:50:15Z</dc:date>
    </item>
    <item>
      <title>Top 10 Performance Optimization Techniques for Azure Database for PostgreSQL Flexible Server</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/top-10-performance-optimization-techniques-for-azure-database/ba-p/4542522</link>
      <description>&lt;H6 aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Introduction&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;/STRONG&gt;&lt;/H6&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Performance optimization is one of the most&amp;nbsp;common challenges&amp;nbsp;faced by organizations running business-critical workloads on Azure Database for PostgreSQL&amp;nbsp;flexible&amp;nbsp;server.&amp;nbsp;As your workloads&amp;nbsp;grow&amp;nbsp;it’s&amp;nbsp;common to&amp;nbsp;encounter&amp;nbsp;high CPU&amp;nbsp;utilization, storage bottlenecks,&amp;nbsp;autovacuum&amp;nbsp;issues, excessive temporary file generation, and connection saturation.&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;The good news is that Azure PostgreSQL&amp;nbsp;flexible server&amp;nbsp;provides&amp;nbsp;several built-in capabilities to help&amp;nbsp;optimize&amp;nbsp;performance, improve scalability, and reduce operational overhead. This article explores ten practical techniques that can significantly improve database performance and reliability.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H6&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;1. Choose the Right Compute SKU&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Performance starts with selecting the appropriate&amp;nbsp;compute&amp;nbsp;tier.&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="auto"&gt;Azure PostgreSQL&amp;nbsp;flexible server&amp;nbsp;offers:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table class="lia-background-color-16 lia-border-color-21 lia-border-style-solid" border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Pricing tier&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Target workloads&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Burstable&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Designed for workloads that&amp;nbsp;don't&amp;nbsp;require full CPU performance continuously. Best suited for proof-of-concept environments, and development builds.&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;Not recommended for production workloads.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;General Purpose&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Provides a balance between CPU and memory with scalable I/O throughput, making it suitable for most production workloads. Examples include servers for hosting web&amp;nbsp;applications,&amp;nbsp;mobile apps&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;and enterprise applications.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Memory Optimized&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td class="lia-border-color-21"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Suitable for high-performance database workloads that require in-memory performance for&amp;nbsp;larger buffer cache sets,&amp;nbsp;and higher concurrency. Examples include servers for processing real-time data and high-performance transactional or analytical apps.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&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;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about Compute Tiers&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/compute-storage/concepts-compute" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;H6 class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;2.Enable and Use Query Store&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Query Store is one of the most powerful performance tools available.&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="auto"&gt;Query Store automatically captures the following and keeps them available for review:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Query execution statistics&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Runtime metrics&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Wait event information&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Historical execution trends&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="auto"&gt;It organizes the data into time windows, so you can spot database usage patterns. Data for all users, databases, and queries is stored in a database named&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;azure_sys&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;in the Azure Database for PostgreSQL instance&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="none"&gt;It’s&amp;nbsp;generally recommended&amp;nbsp;to&amp;nbsp;monitor&amp;nbsp;query&amp;nbsp;store&amp;nbsp;from Azure tools, KQL,&amp;nbsp;etc.&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about&amp;nbsp;Query store&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-query-store" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;You can also view some&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-query-store-scenarios" target="_blank" rel="noopener"&gt;useful scenario for query store&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;and some &lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-query-store-best-practices" target="_blank" rel="noopener"&gt;Best Practices for Query store&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;3.Leverage Built-In &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;PgBouncer &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Connection Pooling&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;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL uses a process-per-connection model, which means every connection consumes memory and CPU resources.&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="auto"&gt;Azure PostgreSQL flexible server provides built-in PgBouncer support for eligible SKUs . PgBouncer&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; allows multiple application sessions to reuse open backend connections and significantly reduces overhead.&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Benefits include:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Lower memory consumption&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Faster connection handling&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Improved application scalability&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Reduced CPU overhead&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="auto"&gt;Learn more about&amp;nbsp;PgBouncer&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/connectivity/concepts-pgbouncer" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;4.Use Azure Troubleshooting Guides&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;One underutilized feature is the built-in troubleshooting experience available directly in the Azure portal.&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="auto"&gt;Guides are available for:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;CPU troubleshooting&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Memory troubleshooting&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;IOPS analysis&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Temporary files&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Autovacuum&amp;nbsp;monitoring&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Autovacuum&amp;nbsp;blockers&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="auto"&gt;These tools provide actionable recommendations and visualizations without requiring external monitoring solutions.&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about Troubleshooting Guides&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-troubleshooting-guides" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;5. Monitor and Tune &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Autovacuum&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;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Autovacuum is critical for maintaining PostgreSQL performance.&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="auto"&gt;Without proper vacuuming:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Dead tuples accumulate&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Table bloat increases&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Statistics are not refreshed regularly&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Query performance degrades&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Transaction ID wraparound risks&amp;nbsp;emerge&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="auto"&gt;Use Azure's built-in&amp;nbsp;Autovacuum&amp;nbsp;Monitoring&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-troubleshooting-guides" target="_blank" rel="noopener"&gt;TroubleshootingGuides&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;to&amp;nbsp;identify:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Vacuum lag&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Blocked&amp;nbsp;autovacuums&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Table bloat&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Inefficient cleanup operations&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="auto"&gt;Azure now also offers adaptive tuning capabilities to&amp;nbsp;optimize&amp;nbsp;maintenance behavior.&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about&amp;nbsp;Autovacuum&amp;nbsp;tuning&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-autovacuum-tuning" target="_blank" rel="noopener"&gt;here&lt;/A&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-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;STRONG&gt;6&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;Optimize &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Storage and IOPS Planning&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;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Many performance incidents originate from insufficient storage planning rather than inefficient SQL.&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="auto"&gt;In Azure PostgreSQL&amp;nbsp;flexible server:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Storage and baseline IOPS are closely related. Learn more&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/compute-storage/concepts-storage" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Larger storage allocations provide higher baseline IOPS.&amp;nbsp;&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Auto-grow prevents storage-related outages&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Note: &lt;EM&gt;Storage can&amp;nbsp;only&amp;nbsp;be&amp;nbsp;scaled&amp;nbsp;up and&amp;nbsp;will always&amp;nbsp;be&amp;nbsp;double&amp;nbsp;in size.&lt;/EM&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt; &lt;BR /&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;EM style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="none"&gt;SSDv2 auto-grow will allow customized growth settings in future&amp;nbsp;release.&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;For write-heavy workloads,&amp;nbsp;monitoring&amp;nbsp;storage&amp;nbsp;utilization&amp;nbsp;and IOPS is essential.&amp;nbsp;&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="auto"&gt;Best practice:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Enable Storage Auto-Grow&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Monitor Read/Write IOPS regularly&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Scale storage proactively&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;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;7.Investigate Temporary File Generation&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Large sorts and hash operations that exceed available memory spill to disk and generate temporary files.&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="auto"&gt;Symptoms include:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Sudden&amp;nbsp;Latency Spikes&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Increased IOPS&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Slower query execution&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="auto"&gt;Azure&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-troubleshooting-guides" target="_blank" rel="noopener"&gt;TroubleshootingGuides&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;provide&amp;nbsp;dedicated temporary-file analysis capabilities that help identify offending queries.&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Frequent temp file generation often&amp;nbsp;indicates:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Missing indexes&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Undersized&amp;nbsp;work_mem&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Large sorting operations&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;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;8.Use Intelligent Tuning&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Azure PostgreSQL&amp;nbsp;flexible server&amp;nbsp;includes Intelligent Tuning capabilities.&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="auto"&gt;The service continuously&amp;nbsp;observes&amp;nbsp;workload behavior and automatically optimizes parameters related to write operations.&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="auto"&gt;Examples of tuning include:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;checkpoint_completion_target&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;max_wal_size&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;min_wal_size&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;bgwriter&amp;nbsp;settings&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="auto"&gt;This reduces administrative effort while helping&amp;nbsp;maintain&amp;nbsp;consistent performance.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about Intelligent Tuning&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-intelligent-tuning" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&amp;nbsp;&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;&lt;SPAN data-ccp-parastyle="heading 1"&gt;9.Optimize &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Checkpoints and Write Workloads&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;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Checkpoint spikes&amp;nbsp;frequently&amp;nbsp;appear in escalations involving high IOPS and latency.&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="auto"&gt;Aggressive checkpoint activity can:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Generate excessive disk writes&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Increase latency&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Consume IOPS capacity&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="auto"&gt;Monitoring checkpoint behavior and ensuring WAL parameters are properly configured can significantly improve write-intensive workloads.&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-intelligent-tuning" target="_blank" rel="noopener"&gt;Azure intelligent tuning&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; can&amp;nbsp;assist&amp;nbsp;in this area as well.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-parastyle="heading 1"&gt;10.M&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-parastyle="heading 1"&gt;etric Monitoring&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Optimization should always be data-driven.&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="auto"&gt;You should track the following:&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 aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;CPU&amp;nbsp;utilization&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Memory pressure&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Active&amp;nbsp;Connections&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Oldest&amp;nbsp;Query&amp;nbsp;&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;IOPS consumption&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="auto"&gt;Combining Azure Metrics, Query Store, and&amp;nbsp;PostgreSQL statistic&amp;nbsp;views&amp;nbsp;allows teams to distinguish between normal workload spikes and true performance degradation.&amp;nbsp;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL statistics views provide valuable workload insights. For example, pg_stat_activity can be used to identify long-running or blocking queries, pg_stat_user_tables helps track dead tuples, vacuum activity, and statistics refreshes, while pg_stat_statements (if enabled) help identify the most resource-intensive queries by execution time and frequency.&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Learn more about Metric&amp;nbsp;&lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-monitoring" target="_blank" rel="noopener"&gt;here&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H6 aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Conclusion&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;P aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Performance optimization in Azure Database for PostgreSQL &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;f&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;lexible server&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;&amp;nbsp;is not&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;just&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;about changing a few parameters and hoping for better results. It requires a structured approach that combines workload understanding, proactive monitoring, proper sizing, query optimization, and platform-native capabilities.&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;/P&gt;
&lt;P aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;By&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;leveraging&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;&amp;nbsp;Query Store,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;PgBouncer&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;, Intelligent Tuning,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Autovacuum&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;M&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;onitoring, Azure Metrics, and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;T&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;roubleshooting&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;G&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;uides, you can significantly improve database efficiency while reducing operational effort.&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;/P&gt;
&lt;H6 aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;References&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&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;BR /&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/compute-storage/concepts-compute" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Compute Options - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt; &lt;BR /&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-query-store" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Query Store in Azure Database for PostgreSQL Flexible Server - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt; &lt;BR /&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/connectivity/concepts-pgbouncer" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;PgBouncer in Azure Database for PostgreSQL Flexible Server - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt; &lt;BR /&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-autovacuum-tuning" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Autovacuum Tuning - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;BR /&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/monitor/concepts-intelligent-tuning" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Intelligent Tuning in Azure Database for PostgreSQL Flexible Server - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&amp;nbsp;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/H6&gt;</description>
      <pubDate>Mon, 03 Aug 2026 21:21:23 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/top-10-performance-optimization-techniques-for-azure-database/ba-p/4542522</guid>
      <dc:creator>anugya-sinha</dc:creator>
      <dc:date>2026-08-03T21:21:23Z</dc:date>
    </item>
    <item>
      <title>AI-Powered Retrieval in PostgreSQL with Azure HorizonDB</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ai-powered-retrieval-in-postgresql-with-azure-horizondb/ba-p/4540160</link>
      <description>&lt;P&gt;Developers need flexible, efficient item searches by description. Using a Wikipedia movie dataset, I started with full-text search, then created embeddings for descriptions, and performed semantic searches. Queries combined text or similarity searches with filters. Common questions arose: How to update embeddings as data changes? How to avoid reprocessing all data? How to make AI calls more efficient? I prefer to keep business logic in the app and data manipulation in SQL, but triggers and stored procedures complicate this.&lt;/P&gt;
&lt;P&gt;This post explores keeping retrieval workflows inside the database, using data, indexes, filters, and rules already in place. Instead of external workers, I want SQL abstractions to handle operations like generating and maintaining embeddings as part of the data model. I begin with relational data, using BM25&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/full-text-search" target="_blank"&gt;text search&lt;/A&gt;, generating embeddings with&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-model-management" target="_blank"&gt;AI Model Management&lt;/A&gt;&amp;nbsp;(AIMM) and&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-functions" target="_blank"&gt;AI Functions&lt;/A&gt;, storing them with&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-search-pgvector" target="_blank"&gt;pgvector&lt;/A&gt;, indexing them with&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-index-diskann" target="_blank"&gt;DiskANN&lt;/A&gt;, and integrating AI into PostgreSQL. Then I define an&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank"&gt;AI pipeline&lt;/A&gt;&amp;nbsp;to maintain consistency without extra procedural code.&lt;/P&gt;
&lt;P&gt;The goal is to keep AI processing close to data with declarative SQL. I used a Kaggle movies dataset with 30,000 entries over 11 years, importing a subset for simplicity. Each file has title, description, director, country, year, and ID.&lt;/P&gt;
&lt;H2&gt;HorizonDB and AI extensions&lt;/H2&gt;
&lt;P&gt;I've run this on&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/overview" target="_blank"&gt;HorizonDB&lt;/A&gt;&amp;nbsp;preview, where I enabled pg_textsearch, pg_vector, DiskANN, and azure_ai extensions:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select name, current_setting(name)
           from pg_settings 
           where name in ('server_version', 'azure.extensions')
;
           
       name       |                current_setting
------------------+-----------------------------------------------
 azure.extensions | pg_diskann,vector,pg_textsearch,azure_ai
 server_version   | 17.9 (Azure HorizonDB (81895d42565)(release))
 
(2 rows)

&lt;/LI-CODE&gt;
&lt;P&gt;I downloaded and unzipped the dataset files in the current directory:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;

\! curl -L -o movies-dataset-2016-2026.zip https://www.kaggle.com/api/v1/datasets/download/lakshyaupadhyaya/wikipedia-movies-dataset-2016-2026

\! unzip -o movies-dataset-2016-2026.zip

\! rm movies-dataset-2016-2026.zip

&lt;/LI-CODE&gt;
&lt;P&gt;I created a table where I can load this data and add embeddings later:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;

postgres=&amp;gt; drop table if exists wikipedia_movies
;

DROP TABLE

postgres=&amp;gt; create table wikipedia_movies (
  year int,
  id bigint,
  title text,
  description text,
  directed_by text,
  written_by text,
  produced_by text,
  starring text,
  cinematography text,
  edited_by text,
  release_date text,
  country text,
  language text,
  primary key (year, id)
);

CREATE TABLE

postgres=&amp;gt; create index on wikipedia_movies (country)
;

CREATE INDEX

&lt;/LI-CODE&gt;
&lt;P&gt;I loaded data from 2026 using a one-liner that prepends the year from the filename.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; \copy wikipedia_movies from program 'awk ''FNR&amp;gt;1{print substr(FILENAME,1,4)","$0}'' {2026..2026}.csv' with (format csv)

COPY 852

&lt;/LI-CODE&gt;
&lt;P&gt;Some rows have a NULL description. I updated them with the title so every row has something meaningful to embed or search, and make sure the description cannot be null:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; update wikipedia_movies
           set description = format('Title: %s', title)
           where description is null
;

UPDATE 22

postgres=&amp;gt; alter table wikipedia_movies
           alter column description set not null
;

ALTER TABLE

&lt;/LI-CODE&gt;
&lt;P&gt;So far, there's nothing AI-specific here. It's simply PostgreSQL functioning as it always does: storing structured data, enforcing keys, and allowing me to load, clean, and query using SQL.&lt;/P&gt;
&lt;H2&gt;Try full-text search first&lt;/H2&gt;
&lt;P&gt;Before generating embeddings for similarity search, I started with lexical search. Azure Database for PostgreSQL supports &lt;CODE&gt;pg_textsearch&lt;/CODE&gt;, which provides BM25-based full-text search and scoring.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; create extension if not exists pg_textsearch;

CREATE EXTENSION

postgres=&amp;gt; create index wikipedia_movies_description_idx
           on wikipedia_movies
           using bm25 (description)
           with (text_config = 'english')
;

NOTICE:  BM25 index build started for relation wikipedia_movies_description_idx
NOTICE:  Using text search configuration: english
NOTICE:  Using index options: k1=1.20, b=0.75
NOTICE:  BM25 index build completed: 852 documents, avg_length=35.95
CREATE INDEX

&lt;/LI-CODE&gt;
&lt;P&gt;Then I can search the descriptions:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select 
            description &amp;lt;@&amp;gt; 'Spanish tragicomedy autofiction from 2026' as score,
            title,
            description
            from wikipedia_movies
            where country = 'Spain' and year = '2026'
            order by score limit 2
;
            
       score        |      title       |                                                                                                                                                   description                                          
--------------------+------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 -17.06686845421791 | Bitter Christmas | Bitter Christmas (Spanish: Amarga Navidad) is a 2026 Spanish tragicomedy film written and directed by Pedro Almodóvar. It stars Bárbara Lennie and Leonardo Sbaraglia alongside Aitana Sánchez-Gijón, Victoria Luengo, Patrick Criado, Milena Smit, and Quim Gutiérrez. It incorporates elements of autofiction.
 -5.273793399333954 | Aida, the Movie  | Aida, the Movie (Spanish: Aída y vuelta) is a 2026 Spanish comedy film directed by Paco León serving as a meta-sequel to the sitcom Aída.
(2 rows)

Time: 31.024 ms

&lt;/LI-CODE&gt;
&lt;P&gt;This is the appropriate initial step. When the query includes terms found in the text, BM25 provides search and scoring capabilities. It is transparent, efficient, and easy to combine with relational filters. Nevertheless, lexical search has its limitations. It works best when the query vocabulary matches the data. But what if the user searches by concept rather than exact words? Or if the query is in French while the descriptions are in English? In such situations, embeddings help capture the semantic meaning of the description rather than its words. They do not replace BM25 but serve as an additional signal for retrieval.&lt;/P&gt;
&lt;H2&gt;AI Model Management&lt;/H2&gt;
&lt;P&gt;AI Model Management (AIMM) includes pre-provisioned models, so manual registration is not required, and I've just enabled the managed model:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Once successfully enabled, I can see three registered models, which are used by default by the AI functions:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select alias, model_name, status from model_registry.model_list_all();

       alias       |       model_name        |   status
-------------------+-------------------------+------------
 default-chat      | gpt-5.4                 | registered
 default-embedding | text-embedding-3-small  | registered
 default-reranker  | Cohere-rerank-v4.0-fast | registered
(3 rows)

postgres=&amp;gt;

&lt;/LI-CODE&gt;
&lt;P&gt;Without AIMM, you would need to bring your own model, or deploy an OpenAI model in Azure AI Foundry, and register it:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; create extension if not exists azure_ai
;

CREATE EXTENSION

postgres=&amp;gt; select model_registry.model_add('default-embedding',...)
;

                               model_add
------------------------------------------------------------------------
 Model 'default-embedding' (text-embedding-3-small) added successfully.
(1 row)

Time: 40.762 ms

&lt;/LI-CODE&gt;
&lt;H2&gt;Generate embeddings manually&lt;/H2&gt;
&lt;P&gt;I created a vector column and generated embeddings directly from the movie descriptions.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; create extension if not exists azure_ai
;

CREATE EXTENSION

postgres=&amp;gt; create extension if not exists vector;

CREATE EXTENSION

postgres=&amp;gt; alter table wikipedia_movies add column embedding vector(1536),
           alter column embedding set storage external -- (it's the default)
;

ALTER TABLE

postgres=&amp;gt; update wikipedia_movies
           set embedding = azure_openai.create_embeddings(
               input =&amp;gt; description,
               dimensions =&amp;gt; 1536
              )::vector(1536)
;

INFO:  Using user-assigned managed identity authentication method.

UPDATE 852
Time: 200905.958 ms (03:20.906)

&lt;/LI-CODE&gt;
&lt;P&gt;This approach invokes the embedding service separately for each row. These calls are visible if you &lt;CODE&gt;set client_min_messages to 'log'&lt;/CODE&gt;. Making external service calls asynchronously for each row is not optimal. Performance could be improved by batching the requests into a more complex query:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; with numbered as (
            select year, id, description,
            (row_number() over() - 1) / 100 as batch_num
            from wikipedia_movies
           ),
           batched AS (
            select array_agg(year) as years,
             array_agg(id) as ids,
             array_agg(description) as texts,
             batch_num
            from numbered
            group by batch_num
          ),
          embedded AS (
           select unnest(years) as year,
            unnest(ids) as id,
            azure_openai.create_embeddings(
             input =&amp;gt; texts,
             dimensions =&amp;gt; 1536
            ) as emb
           from batched
          )
          update wikipedia_movies t
          set  embedding = e.emb::vector(1536) from embedded e
          where  t.year = e.year and t.id = e.id
;

UPDATE 852
Time: 10892.871 ms (00:10.893)

&lt;/LI-CODE&gt;
&lt;P&gt;This is precisely where an abstraction is needed to simplify and optimize embedding generation. I will add that later.&lt;/P&gt;
&lt;P&gt;After setting the vectors in the table, I can proceed to add a DiskANN index.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; CREATE EXTENSION IF NOT EXISTS pg_diskann
;

CREATE EXTENSION

postgres=&amp;gt; CREATE INDEX wikipedia_movies_embedding_idx
           ON wikipedia_movies
           USING diskann (embedding vector_cosine_ops)
;

CREATE INDEX
Time: 5369.375 ms (00:05.369)

&lt;/LI-CODE&gt;
&lt;P&gt;This allows me to perform a semantic query in French on English descriptions while continuing to filter using standard SQL:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select azure_openai.create_embeddings(
             input =&amp;gt; 'une comédie amère sur le thème de l''auto-fiction'
            )::vector(1536) &amp;lt;=&amp;gt; embedding as score,
            title, description
            from wikipedia_movies
            where country = 'Spain' and year = '2026'
            order by score limit 2
;

       score       |      title       |                                                                                                                                                    description                                                                                                                  
-------------------+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 0.692949073279717 | Bitter Christmas | Bitter Christmas (Spanish: Amarga Navidad) is a 2026 Spanish tragicomedy film written and directed by Pedro Almodóvar. It stars Bárbara Lennie and Leonardo Sbaraglia alongside Aitana Sánchez-Gijón, Victoria Luengo, Patrick Criado, Milena Smit, and Quim Gutiérrez. It incorporates elements of autofiction.
 0.757078099513101 | Cool Books       | Cool Books (Spanish: Casi todo bien)[1] is a 2026 Spanish comedy-drama film directed by Andrés Salmoyraghi and Rafael López Saubidet and written by López Saubidet and Ricardo Uhagón Vivas. It stars Marcel Borràs and Silma López alongside Lorenzo Ferro, Julián Villagrán, Secun de la Rosa, and Adelfa Calvo.
(2 rows)

Time: 269.598 ms

&lt;/LI-CODE&gt;
&lt;P&gt;The query goes beyond simple token matching: it searches based on the description's meaning across different languages, while PostgreSQL continues to enforce relational filters on the year and country.&lt;/P&gt;
&lt;P&gt;The execution plan shows a filtered scan through the DiskANN index:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Limit (actual time=1.622..1.642 rows=2 loops=1)
   -&amp;gt;  Custom Scan (DiskANNFilteredScan) (actual time=1.620..1.639 rows=2 loops=1)
         Strategy: Filter(BitmapHeapScan) -&amp;gt; Vector
         Rows Retrieved: 2 count
         TIDs Collected: 31 count
 Planning Time: 250.003 ms
 Execution Time: 1.789 ms
(7 rows)

Time: 283.231 ms

&lt;/LI-CODE&gt;
&lt;P&gt;This approach is efficient: the "country" predicate leverages the b-tree index for pre-filtering, narrowing the search to 31 rows identified by their TID—tuple identifiers stored in the b-tree leaf nodes. The Approximate Nearest Neighbors search then considers only this pre-filtered list when navigating the vector index, finding the best candidates, and subsequently retrieving the top two. Although I could have used pgvector's HNSW index instead of DiskANN, it lacks pre-filtering capabilities.&lt;/P&gt;
&lt;P&gt;I now face a maintenance issue: the embeddings remain correct only until the next insert or update of the description. In SQL, I expect indexes to be maintained synchronously by the database rather than by the application, but embedding generation is a step in between.&lt;/P&gt;
&lt;H2&gt;Embedding becomes a pipeline&lt;/H2&gt;
&lt;P&gt;For a one-time load, manually running the UPDATE is sufficient. However, for regular applications, this approach isn't practical. I don't want to remember to run an embedding update whenever new movies arrive, nor do I want an extra worker polling the table, additional queues, retry loops, or extra status tables that can cause data to get out of sync. Instead, I prefer the embedding workflow to be directly linked to the data, with AI pipelines in the AI Functions. A pipeline consists of a source, steps, a trigger, and a sink. In this case, the source is the movie table, the step is embedding generation, the trigger is an &lt;CODE&gt;on_change&lt;/CODE&gt; event, and the sink is the same table with the embeddings stored as a column within each row’s description.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; SELECT ai.create_pipeline(
            name =&amp;gt; 'movie_embeddings',
            source =&amp;gt; ai.table_source('wikipedia_movies'),
            steps =&amp;gt; ARRAY[
              ai.embed(
                model =&amp;gt; 'default-embedding',
                input =&amp;gt; 'description',
                dimensions =&amp;gt; 1536
              )
            ],
            trigger =&amp;gt; 'on_change',
            sink =&amp;gt; ai.table_sink(
              'wikipedia_movies',
              on_conflict =&amp;gt; ARRAY['year', 'id'],
              on_conflict_action =&amp;gt; 'DO UPDATE SET embedding = EXCLUDED.embedding'
           )
);

NOTICE:  trigger "_ai_pipeline_movie_embeddings_trigger" for relation "public.wikipedia_movies" does not exist, skipping

                 create_pipeline
--------------------------------------------------
 Pipeline 'movie_embeddings' created successfully
(1 row)

&lt;/LI-CODE&gt;
&lt;P&gt;The AI pipeline is configured to insert embeddings into a sink table, with an on-conflict clause that updates the existing row rather than inserts a new one when the key already exists. When the sink table is the source table, this always leads to an insert conflict because the row already exists when the pipeline runs, making it an update. The pipeline creates an internal batch from the source, generates embeddings, and writes them back with ON CONFLICT DO UPDATE. The trigger verifies whether the pipeline is already running in the same transaction to prevent an infinite recursion when it writes back to the same table.&lt;/P&gt;
&lt;P&gt;I can validate my pipeline by updating all embeddings for each description using the AI model and requesting a backfill:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select ai.backfill('movie_embeddings')
;

NOTICE:  table "_ai_batch_d03946bdb634_chunks" does not exist, skipping

                         backfill
-----------------------------------------------------------
 Pipeline 'movie_embeddings' completed: 852 rows processed
(1 row)

Time: 10653.393 ms (00:10.65)

&lt;/LI-CODE&gt;
&lt;P&gt;This was as quick as my batching query because the default batch size is 100.&lt;/P&gt;
&lt;H2&gt;Under the hood: triggers and batches&lt;/H2&gt;
&lt;P&gt;I like to understand what is executed behind the abstraction. The call to &lt;CODE&gt;ai.create_pipeline()&lt;/CODE&gt; has created an internal trigger on my table:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; \d wikipedia_movies

                Table "public.wikipedia_movies"

      Column      |    Type      | Collation | Nullable | Default
------------------+--------------+-----------+----------+---------
 year             | integer      |           | not null |
 id               | bigint       |           | not null |
 title            | text         |           |          |
 description      | text         |           |          |
 directed_by      | text         |           |          |
 written_by       | text         |           |          |
 produced_by      | text         |           |          |
 starring         | text         |           |          |
 cinematography   | text         |           |          |
 edited_by        | text         |           |          |
 release_date     | text         |           |          |
 country          | text         |           |          |
 language         | text         |           |          |
 embedding        | vector(1536) |           |          |

Indexes:

    "wikipedia_movies_pkey" PRIMARY KEY, btree (year, id)
    "wikipedia_movies_country_idx" btree (country)
    "wikipedia_movies_description_idx" bm25 (description) WITH (text_config=english)
    "wikipedia_movies_embedding_idx" diskann (embedding vector_cosine_ops)

Triggers:

    _ai_pipeline_movie_embeddings_trigger AFTER INSERT OR UPDATE ON wikipedia_movies FOR EACH STATEMENT EXECUTE FUNCTION ai._pipeline_trigger_movie_embeddings()

postgres=&amp;gt; \sf ai._pipeline_trigger_movie_embeddings

CREATE OR REPLACE FUNCTION ai._pipeline_trigger_movie_embeddings()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$ 
 DECLARE running BOOLEAN; 
 BEGIN
  SELECT EXISTS(SELECT 1 FROM ai.pipeline_runs WHERE pipeline_name = 'movie_embeddings' AND status = 'running') INTO running; 
  IF NOT running THEN PERFORM ai.run('movie_embeddings'); END IF; 
  RETURN NULL; 
 END;
$function$

&lt;/LI-CODE&gt;
&lt;P&gt;This trigger function is called after each INSERT or UPDATE statement, not after individual rows, and runs the pipeline if it's not already active. The FOR EACH STATEMENT option ensures it triggers once per DML statement rather than per row, enabling batching. By default, it behaves like my previous &lt;CODE&gt;ai.backfill()&lt;/CODE&gt;, updating all embeddings regardless of description changes. Interestingly, it calls &lt;CODE&gt;ai.run()&lt;/CODE&gt; instead of &lt;CODE&gt;ai.backfill()&lt;/CODE&gt;, which can operate incrementally if a tracking column exists in the source table.&lt;/P&gt;
&lt;H2&gt;Only process what changed: incremental pipelines&lt;/H2&gt;
&lt;P&gt;Without an &lt;CODE&gt;incremental_column&lt;/CODE&gt; specified in the pipeline, it replicates the source table as its batch table and re-embeds all data each time. Generating embeddings again for the unchanged description is inefficient. To prevent this, I should add a timestamp column to indicate each row's last modification time and configure the pipeline to use it as a watermark:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; -- add the tracking column
            alter table wikipedia_movies
            add column updated_at timestamptz not null default clock_timestamp()
;

postgres=&amp;gt; -- function to set the update_at to now()
           create or replace function update_timestamp()
           returns trigger as $$
             begin new.updated_at = clock_timestamp(); return new; end;
           $$ language plpgsql
;

postgres=&amp;gt; -- trigger to call the function on insert or update
           create trigger wikipedia_movies_updated
           before insert or update on wikipedia_movies
           for each row execute function update_timestamp()
;

&lt;/LI-CODE&gt;
&lt;P&gt;Lots of PostgreSQL examples use&amp;nbsp;&lt;CODE&gt;now()&lt;/CODE&gt;&amp;nbsp;to set the update time, but&amp;nbsp;&lt;CODE&gt;now()&lt;/CODE&gt;&amp;nbsp;returns the time when the transaction began, not the time when the update occurred, so using it for an incremental approach could miss the changes if a concurrent session ran the pipeline between those two in Read Committed isolation. I use&amp;nbsp;&lt;CODE&gt;clock_timestamp()&lt;/CODE&gt;&amp;nbsp;which gets the time after the verification that no concurrent pipeline is running.&lt;/P&gt;
&lt;P&gt;Now I can re-create the pipeline with the incremental column defined:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select ai.drop_pipeline( 'movie_embeddings' );

            drop_pipeline
-------------------------------------
 Pipeline 'movie_embeddings' dropped
(1 row)

postgres=&amp;gt; select ai.create_pipeline(
            name =&amp;gt; 'movie_embeddings',
            source =&amp;gt; ai.table_source(
              'wikipedia_movies',
              incremental_column =&amp;gt; 'updated_at'
            ),
            steps =&amp;gt; ARRAY[
              ai.embed(
                model =&amp;gt; 'default-embedding',
                input =&amp;gt; 'description',
                dimensions =&amp;gt; 1536
              )
            ],
            trigger =&amp;gt; 'on_change',
            sink =&amp;gt; ai.table_sink(
              'wikipedia_movies',
              on_conflict =&amp;gt; ARRAY['year', 'id'],
              on_conflict_action =&amp;gt; 'DO UPDATE SET embedding = EXCLUDED.embedding'
           )
);

NOTICE:  trigger "_ai_pipeline_movie_embeddings_trigger" for relation "public.wikipedia_movies" does not exist, skipping
                 create_pipeline
--------------------------------------------------
 Pipeline 'movie_embeddings' created successfully
(1 row)

&lt;/LI-CODE&gt;
&lt;P&gt;When using &lt;CODE&gt;incremental_column =&amp;gt; 'updated_at'&lt;/CODE&gt;, the batch records the last execution time as a checkpoint, so the next run only processes rows with an &lt;CODE&gt;updated_at&lt;/CODE&gt; value higher than that checkpoint.&lt;/P&gt;
&lt;P&gt;The next run will then process all rows again:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select ai.run('movie_embeddings');

NOTICE:  table "_ai_batch_ef762cbb918f_chunks" does not exist, skipping
                            run
-----------------------------------------------------------
 Pipeline 'movie_embeddings' completed: 852 rows processed
(1 row)

Time: 12231.656 ms (00:12.232)

&lt;/LI-CODE&gt;
&lt;P&gt;However, a new execution will process only incrementally:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select ai.run('movie_embeddings');

                         run
-----------------------------------------------------
 Pipeline 'movie_embeddings': no new rows to process
(1 row)

postgres=&amp;gt; update wikipedia_movies
           set description = description || ' (film Français)'
           where country = 'France'
;

NOTICE:  table "_ai_batch_9769bddf6224_chunks" does not exist, skipping
UPDATE 7
Time: 477.686 ms

postgres=&amp;gt; select ai.run('movie_embeddings');

                         run
-----------------------------------------------------
 Pipeline 'movie_embeddings': no new rows to process
(1 row)

Time: 33.692 ms

&lt;/LI-CODE&gt;
&lt;P&gt;The 7 updated rows have been handled by the trigger, which set the checkpoint timestamp, ensuring that the next run has no further processing to perform.&lt;/P&gt;
&lt;P&gt;I loaded only 2026 movies to save AI model tokens. I insert more movies from previous years and specific countries:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
\copy wikipedia_movies from program 'awk ''FNR&amp;gt;1{print substr(FILENAME,1,4)","$0",,"}'' {2016..2025}.csv' with (format csv) where description is not null and country like '%France%'

COPY 1730
Time: 24935.910 ms (00:24.936)

&lt;/LI-CODE&gt;
&lt;P&gt;The insert has automatically generated 1730 embeddings from the model. The new rows are immediately accessible and can be retrieved using a new query.&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select azure_openai.create_embeddings(
             input =&amp;gt; 'a movie based on a novel from A. Camus'
            )::vector(1536) &amp;lt;=&amp;gt; embedding as score,
            year, title, country
            from wikipedia_movies
            order by score limit 2
;

       score        | year |      title       |     country
--------------------+------+------------------+-----------------
 0.4765376989279472 | 2025 | The Stranger     | France, Belgium
 0.5485678715584099 | 2024 | An Ordinary Case | France
(2 rows)

Time: 448.648 ms

&lt;/LI-CODE&gt;
&lt;P&gt;The result includes the newly inserted movies from previous years. The index remains strongly consistent when the “embedding” column is modified, and the AI pipeline ensures this consistency also applies to changes in the “description” column. It behaves exactly like indexes in SQL: transparent to the application, consistent in the database.&lt;/P&gt;
&lt;H2&gt;More AI functions&lt;/H2&gt;
&lt;P&gt;Generating the embeddings is not the only feature of AI functions. Previously I've updated the description for the movies that didn't have one, simply putting the title in it. However, I can use &lt;CODE&gt;generate()&lt;/CODE&gt; to get a real description:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; \x
Expanded display is on.

postgres=&amp;gt; select azure_ai.generate(format(
            'Write a short description for the movie %s, directed by %s',
            title, directed_by
           )), title
           from wikipedia_movies
           where description like 'Title: %'
           limit 3
;

-[ RECORD 1 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
generate | Billie Eilish – Hit Me Hard and Soft: The Tour (Live in 3D) is a concert film directed by James Cameron and Billie Eilish, capturing the energy and emotion of Eilish’s live tour in immersive 3D. Blending striking visuals with powerful performances, the film brings audiences into the heart of the show and offers a vivid celebration of her music and stage presence.
title    | Billie Eilish – Hit Me Hard and Soft: The Tour (Live in 3D)
-[ RECORD 2 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
generate | Border 2 is an upcoming Indian war drama directed by Anurag Singh. Serving as a sequel to the iconic film Border, it is expected to bring a powerful story of patriotism, courage, and sacrifice, set against the backdrop of military conflict.
title    | Border 2
-[ RECORD 3 ]---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
generate | *February* (2022) is a drama film directed by Kamen Kalev. The story follows a quiet man through different stages of his life, using minimal dialogue and striking imagery to reflect on solitude, routine, and the passage of time.
title    | (February 2022)

&lt;/LI-CODE&gt;
&lt;P&gt;The &lt;CODE&gt;generate()&lt;/CODE&gt; function doesn't simply repeat the title. Using the title and director as context, it generates a richer description that can be stored in the table, indexed with BM25, embedded for semantic search.&lt;/P&gt;
&lt;P&gt;Instead of generating text from structured column, with the &lt;CODE&gt;generate()&lt;/CODE&gt; function, I can do the opposite: create new columns from the description with the &lt;CODE&gt;extract()&lt;/CODE&gt; function:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; select azure_ai.extract(
  description,
  array['genre']
), title
from wikipedia_movies limit 3
;

-[ RECORD 1 ]--------------------------------------
extract | {"genre": "coming-of-age romantic drama"}
title   | 18th Rose
-[ RECORD 2 ]--------------------------------------
extract | {"genre": "drama"}
title   | Animol
-[ RECORD 3 ]--------------------------------------
extract | {"genre": "documentary film"}
title   | The Best Summer

&lt;/LI-CODE&gt;
&lt;P&gt;Like embeddings, extracted attributes or additional columns could be maintained automatically through an AI Pipeline when descriptions change.&lt;/P&gt;
&lt;P&gt;Another function,&amp;nbsp;&lt;CODE&gt;azure_ai.rank()&lt;/CODE&gt;, can use the re-ranker model on the set of candidates (AIMM installed the Cohere Rerank model).&lt;/P&gt;
&lt;H2&gt;Hybrid search in one query&lt;/H2&gt;
&lt;P&gt;Once the table has both a BM25 index and embeddings, there is no need to choose between lexical and semantic retrieval. For many real applications, the best answer is to get candidates from both approaches and combine them to retrieve the best overall score.&lt;/P&gt;
&lt;P&gt;A classic way to combine them is Reciprocal Rank Fusion:&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;
postgres=&amp;gt; with semantic as (
             select year, id,
                  rank() over (
                    order by embedding &amp;lt;=&amp;gt;
                      azure_openai.create_embeddings(
                        input =&amp;gt; 'space opera produced or directed by luc besson',
                        dimensions =&amp;gt; 1536
                      )::vector(1536)
                  ) as r
             from wikipedia_movies
             where year between 2016 and 2026
         ),
         lexical as (
             select year, id,
                    rank() over (
                      order by description &amp;lt;@&amp;gt;
                        'space opera produced or directed by luc besson'
                    ) as r
             from wikipedia_movies 
             where year between 2016 and 2026
         )
         select m.year, m.title
         from wikipedia_movies m
          join semantic s using (year, id)
          -- Join both result sets (full join to keep all)
          full join lexical l using (year, id)
          -- Reciprocal Rank Fusion (RRF):
          order by coalesce(1.0 / (60 + s.r), 0)
                + coalesce(1.0 / (60 + l.r), 0) desc
          limit 5
;
         
NOTICE:  pg_diskann: Filter selectivity too high (1.0000), skipping filtered vector scan

 year |                    title
------+---------------------------------------------
 2017 | Valerian and the City of a Thousand Planets
 2025 | Dracula
 2016 | Ballerina
 2024 | Meanwhile on Earth
 2016 | The Warriors Gate
(5 rows)

Time: 410.727 ms

&lt;/LI-CODE&gt;
&lt;P&gt;The data and filters remain relational, with both BM25 and vector search options available. Ranking is handled through SQL, embeddings are synchronized through a pipeline, and reranking can be delegated to an AI model when additional precision is required. The notable aspect isn't just PostgreSQL's ability to invoke AI models, but that the entire retrieval workflow, from indexing and filtering to ranking and reranking, remains close to the data and can be expressed declaratively in SQL.&lt;/P&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;This example started with a simple retrieval problem: searching movie descriptions, combining lexical and semantic relevance, and keeping embeddings synchronized as data changes. Along the way, it used AI Functions, BM25 full-text search, vector embeddings, DiskANN indexes, and AI Pipelines, all from within PostgreSQL.&lt;/P&gt;
&lt;P&gt;Those capabilities are part of a broader set of multi-model features in HorizonDB, including built-in AI models and functions, graph queries with Apache AGE, and durable workflow execution. What interested me here was not any individual feature, but how they fit together around the data. Search, embeddings, indexing, and synchronization can be expressed in SQL and managed alongside the application data they depend on.&lt;/P&gt;
&lt;P&gt;AI applications still need models, prompts, and business logic in the application layer. But retrieval remains a critical foundation. By combining relational data, keyword search, vector search, and automated embedding pipelines within a single PostgreSQL database, HorizonDB reduces the infrastructure required to keep that foundation accurate, consistent, and up to date.&lt;/P&gt;
&lt;P&gt;If you'd like to try these capabilities yourself, visit the&amp;nbsp;&lt;A href="https://azure-samples.github.io/postgres-hub/" target="_blank"&gt;PostgreSQL Hub&lt;/A&gt;&amp;nbsp;for sample applications, learning paths, and solution accelerators. The&amp;nbsp;&lt;A href="https://github.com/Azure-Samples/postgres-hub/discussions" target="_blank"&gt;PostgreSQL Developer Forum&lt;/A&gt;&amp;nbsp;is also the best place to share feedback, ask questions, and participate in the community.&lt;/P&gt;</description>
      <pubDate>Tue, 28 Jul 2026 18:08:05 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/ai-powered-retrieval-in-postgresql-with-azure-horizondb/ba-p/4540160</guid>
      <dc:creator>FranckPachot</dc:creator>
      <dc:date>2026-07-28T18:08:05Z</dc:date>
    </item>
    <item>
      <title>TLS Certificate Pinning and Best Practices in Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/tls-certificate-pinning-and-best-practices-in-azure-database-for/ba-p/4531390</link>
      <description>&lt;H2 aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;TLS certificate pinning in Azure Database for PostgreSQL&amp;nbsp;&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;Transport Layer Security (TLS)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt; encrypts data in transit between client applications and the server and authenticates the service endpoint in 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 server certificates are issued by well-known trusted public Certificate Authorities (CAs), including Microsoft-issued certificates, and are validated by clients during the TLS handshake. 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;Certificate pinning&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; is a client-side security technique where an application restricts trust to a specific certificate, for example by thumbprint, public key, or CA, rather than relying solely on the default OS or platform trust store. The trust store contains pre-installed root CAs and may also include additional certificates configured by the client. During standard TLS validation, the client will trust any server certificate that chains to one of those root 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 client-side logic&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;The server has no visibility into whether pinning is configured on the client.&lt;/SPAN&gt; &lt;SPAN data-contrast="none"&gt;From the server’s perspective, 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 root CA, intermediate CA, leaf certificate 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 the server can see is TLS handshake failure patterns, TLS protocol, and 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 maintain security and compliance. In Azure Database for PostgreSQL, &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;&lt;STRONG&gt;,&lt;/STRONG&gt; clients bind trust to a specific certificate or CA. As a result, &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;STRONG&gt;any change to the server certificate chain—including CA updates—can cause connection failures&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;STRONG&gt;,&lt;/STRONG&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 &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;PostgreSQL&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 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 required.&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;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 validate 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 appropriate root and intermediate certificate authorities (CAs) required to validate 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;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;For the current TLS certificates visit the &lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/security/security-tls" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure Database for PostgreSQL documentation&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559685&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&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 &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;PostgreSQL client &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;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;sslmode=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 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;sslmode=verify-full&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;Verifies CA and hostname match&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 validate the server certificate chain against trusted 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, such as to a single certificate or limited CA set, 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 remaining resilient to certificate rotations.&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;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 CAs over time. &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;When Azure announces a CA 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;Add newly required root CAs to the client trust store before the rotation begins.&lt;/LI&gt;
&lt;LI&gt;Retain existing trusted root CAs until the transition is fully complete.&lt;/LI&gt;
&lt;LI&gt;Avoid removing older root certificates prematurely.&lt;/LI&gt;
&lt;LI&gt;If specific rotation guidance includes updates related to intermediate CAs, follow the service-specific instructions provided for that rotation.&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 validating the server 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;&lt;SPAN data-ccp-props="{}"&gt;For a deeper dive, see the full article:&amp;nbsp;&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;</description>
      <pubDate>Fri, 24 Jul 2026 20:02:19 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/tls-certificate-pinning-and-best-practices-in-azure-database-for/ba-p/4531390</guid>
      <dc:creator>TameikaL</dc:creator>
      <dc:date>2026-07-24T20:02:19Z</dc:date>
    </item>
    <item>
      <title>Monitoring and using pg_repack in Azure Database for PostgreSQL flexible server</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/monitoring-and-using-pg-repack-in-azure-database-for-postgresql/ba-p/4537320</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;In this post: &lt;/STRONG&gt;we will walk through how to configure and use the pg_repack extension in Azure Database for PostgreSQL flexible server. We will also cover how to run pg_repack on a table, monitor the progress during execution, and validate the results after the repack operation is completed.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;&lt;U&gt;&lt;STRONG&gt;Why Monitor pg_repack During Execution?&lt;/STRONG&gt;&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;While running pg_repack is straightforward, administrators often need visibility into what is happening behind the scenes, especially when working with large tables in production environments.&lt;/P&gt;
&lt;P&gt;Monitoring the operation provides several benefits:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Verify that pg_repack is actively running and has not stalled.&lt;/LI&gt;
&lt;LI&gt;Identify the current phase of the operation, such as table copying, index rebuilding, or final table swap.&lt;/LI&gt;
&lt;LI&gt;Understand resource usage and the impact on the database.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;U&gt;&lt;STRONG&gt;&lt;SPAN class="lia-text-color-21"&gt;Before you start:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Before performing this lab, ensure the following prerequisites are met:&lt;BR /&gt;&lt;STRONG&gt;Azure Resources:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;An active Azure subscription&lt;/LI&gt;
&lt;LI&gt;An Azure Database for PostgreSQL flexible server instance&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Database Requirements:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;A table with a PRIMARY KEY or UNIQUE NOT NULL index (required by pg_repack)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Linux Machine:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;I have used an Ubuntu Linux Virtual Machine&lt;/LI&gt;
&lt;LI&gt;SSH connectivity to the VM using PuTTY&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 class=""&gt;&lt;SPAN class="lia-text-color-21"&gt;&lt;U&gt;&lt;STRONG&gt;Configuring and using pg_repack in Azure Database for PostgreSQL&lt;/STRONG&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;H4 class=""&gt;Step 1: Allow list and create the pg_repack Extension&lt;/H4&gt;
&lt;P&gt;Before using pg_repack, the extension must be allowlisted and created in the target database. Navigate to your Azure Database for PostgreSQL flexible server and add pg_repack to the allow list of extensions. Once the server configuration is updated, connect to the database and create the extension.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 2: Create and connect to a Linux Virtual Machine&lt;/H4&gt;
&lt;P&gt;Since pg_repack is a client-side utility, a Linux virtual machine was created to install and run the pg_repack client against Azure Database for PostgreSQL flexible server.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 3: Connect to the Linux Virtual Machine&lt;/H4&gt;
&lt;P&gt;Before running pg_repack, I connected to the Linux virtual machine that would be used to install and execute the pg_repack client.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the Azure portal, navigate to the Linux Virtual Machine.&lt;/LI&gt;
&lt;LI&gt;Open PuTTY and enter the VM's IP Address.&lt;/LI&gt;
&lt;LI&gt;Select SSH (Port 22) as the connection type and click Open.&lt;/LI&gt;
&lt;LI&gt;Enter the VM username and password when prompted.&lt;/LI&gt;
&lt;LI&gt;After successful authentication, a terminal session is established&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The following output confirms that the connection was successful and that the Ubuntu operating system is ready for further configuration.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 4: Update Package Repositories on the Linux Virtual Machine&lt;/H4&gt;
&lt;P&gt;Before installing the pg_repack client, update the package repositories on the Ubuntu virtual machine to ensure the latest package information is available. Please run the following command and provide the password for the linux virtual machine when prompted.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;sudo apt update&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 5: Download the pg_repack&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt; If you face any version mismatch issue or errors then you can use the below command to resolve&lt;/P&gt;
&lt;P&gt;After preparing the test environment and generating table bloat, the next step was to download the pg_repack source code to the Linux virtual machine.&lt;BR /&gt;The git clone command downloads the pg_repack source code from the official GitHub repository to the Linux virtual machine. This source code is later used to build and install the pg_repack client utility required to perform table reorganization operation. After downloading the repository, the cd pg_repack command changes the current directory to the downloaded project folder.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;git clone &lt;A href="https://github.com/reorg/pg_repack.git" target="_blank" rel="noopener"&gt;https://github.com/reorg/pg_repack.git&lt;/A&gt;&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;cd pg_repack&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 6: Install PostgreSQL Client Packages&lt;/H4&gt;
&lt;P&gt;After updating the package repositories, the next step was to install the PostgreSQL client packages on the Linux virtual machine. The PostgreSQL package installs the PostgreSQL client tools, including psql, which is used to connect to Azure Database for PostgreSQL flexible server.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;sudo apt install postgresql postgresql-contrib&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;P&gt;When the command is executed, Ubuntu displays a summary of the packages that will be installed along with their dependencies. To proceed with the installation, type Y and press Enter.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 7: Connect to Azure Database for PostgreSQL flexible server&lt;/H4&gt;
&lt;P&gt;After installing the PostgreSQL client packages on the Linux virtual machine, the next step is to establish a connection to the Azure Database for PostgreSQL flexible server using the psql client.&amp;nbsp; Please update the following command with your server details and execute it and enter your PostgreSQL server user password to establish the connection. Note: Make sure your Linux machine network is allowed to connect on your Azure Database for PostgreSQL flexible server.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;psql -h &amp;lt;Hostname&amp;gt; -p 5432 -U &amp;lt;username&amp;gt; postgres&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 8: Create a Test Database&lt;/H4&gt;
&lt;P&gt;After successfully connecting to Azure Database for PostgreSQL flexible server, a dedicated database was created to perform the pg_repack lab activities as shown below:&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 9: Connect to the Newly Created Database&lt;/H4&gt;
&lt;P&gt;After creating the repack_lab database, connect to it before proceeding with the pg_repack activities.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;\c repack_lab&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 10: Create a Sample Table for pg_repack Testing&lt;/H4&gt;
&lt;P&gt;After connecting to the repack_lab database, I created a sample table that would be used throughout the lab to test the functionality of pg_repack.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;CREATE TABLE test_table (&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;id SERIAL PRIMARY KEY,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;name TEXT,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;created_at TIMESTAMP DEFAULT NOW()&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;);&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 11: Insert Sample Data into the Test Table&lt;/H4&gt;
&lt;P&gt;After creating the test_table, the next step was to populate it with sample data. This helps simulate a realistic workload and provides enough records to demonstrate how pg_repack works. The following command was used to insert 100,000 rows into the table:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;INSERT INTO test_table(name)&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;SELECT md5(random()::text)&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;FROM generate_series(1,100000);&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 12: Create an Index on the Test Table&lt;/H4&gt;
&lt;P&gt;After populating the test_table with 100,000 records, an index was created as shown below:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;CREATE INDEX idx_test_name&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;ON test_table(name);&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 13: Check the Initial Table Size&lt;/H4&gt;
&lt;P&gt;Before generating table, bloat and running pg_repack, it is useful to capture the current size of the table. This serves as a baseline for comparing storage consumption before and after the repack operation.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;SELECT pg_size_pretty(pg_total_relation_size('test_table'));&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 14: Generate Table Bloat Using UPDATE Operations&lt;/H4&gt;
&lt;P&gt;To demonstrate how pg_repack reorganizes a table and reclaims unused space, the next step was to generate table bloat by repeatedly updating all rows in the table. The following command was executed multiple times:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;UPDATE test_table&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;SET name = md5(random()::text);&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 15: Disable Autovacuum on the Test Table&lt;/H4&gt;
&lt;P&gt;To clearly observe table bloat and demonstrate the effectiveness of pg_repack, autovacuum was temporarily disabled on the test table. This prevents Azure Database for PostgreSQL flexible&lt;SPAN data-teams="true"&gt;&amp;nbsp;server&lt;/SPAN&gt; from automatically cleaning up dead tuples generated by the previous UPDATE and DELETE operations.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;ALTER TABLE test_table&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;SET (autovacuum_enabled = false);&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H4&gt;Step 16: Analyze Live and Dead Tuples Before Running pg_repack&lt;/H4&gt;
&lt;P&gt;After generating table bloat through multiple UPDATE and DELETE operations and disabling autovacuum, the next step was to measure the number of live and dead tuples in the table.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Step 17: Execute pg_repack to Reorganize the Table&lt;/H4&gt;
&lt;P&gt;The pg_repack utility was executed against the test table to reclaim unused space and reorganize the table structure. The pg_repack utility reorganizes tables and indexes online while minimizing locking and application downtime. Unlike VACUUM FULL, pg_repack performs the reorganization in the background and requires only a brief lock during the final table swap operation.&lt;/P&gt;
&lt;P&gt;Command executed:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;pg_repack \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--host=myflexibleserver.postgres.database.azure.com \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--port=5432 \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--username=dbadmin \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--dbname=repack_lab \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--table=test_table \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--jobs=2 \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--no-kill-backend \&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;--no-superuser-check&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;H3&gt;&lt;U&gt;&lt;STRONG&gt;Monitoring pg_repack Execution&lt;/STRONG&gt;&lt;/U&gt;&lt;/H3&gt;
&lt;H5&gt;Once the pg_repack operation was initiated, the next step was to monitor its execution and identify the activities being performed by the utility in the background:&lt;/H5&gt;
&lt;P&gt;To track active pg_repack sessions, the following query was executed:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;PRE&gt;&lt;STRONG&gt;SELECT&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;pid,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;usename,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;application_name,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;state,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;wait_event_type,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;wait_event,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;now() - query_start AS running_for,&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;query&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;FROM pg_stat_activity&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;WHERE application_name ILIKE '%repack%'&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;OR query ILIKE '%repack%'&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;ORDER BY query_start;&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;/BLOCKQUOTE&gt;
&lt;img /&gt;
&lt;P&gt;After starting the pg_repack operation, I monitored the active sessions by querying the pg_stat_activity system view. This helped me understand the current stage of the operation and verify that the process was executing successfully. The query returned multiple sessions created by pg_repack, indicating that the utility was actively processing the table.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Session 1 - Lock Acquisition&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;STRONG&gt;LOCK TABLE public.test_table IN SHARE UPDATE EXCLUSIVE MODE&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;P&gt;This session acquired a SHARE UPDATE EXCLUSIVE lock on the target table. This lock prevents conflicting schema changes while still allowing normal read and write operations during most of the repack process.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Session 2 - Temporary Repack Table Creation&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;STRONG&gt;SELECT 'repack.table_24861'::regclass::oid&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;P&gt;At this stage, pg_repack was working with an internal temporary table created to hold the reorganized data. This table acts as a replacement for the original table during the repack operation.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Session 3 - Creating Primary Key Index&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;STRONG&gt;CREATE UNIQUE INDEX index_24869&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;ON repack.table_24861 USING btree(id)&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;P&gt;This session shows pg_repack rebuilding the primary key index on the new table structure.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Session 4 - Creating Secondary Index&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;STRONG&gt;CREATE INDEX index_24873&lt;/STRONG&gt;&lt;BR /&gt;&lt;STRONG&gt;ON repack.table_24861 USING btree(name)&lt;/STRONG&gt;&lt;/PRE&gt;
&lt;P&gt;This indicates that additional indexes are being recreated on the temporary table to match the original table definition.&lt;/P&gt;
&lt;P&gt;Based on the output, the operation had successfully moved past the initialization phase and was actively rebuilding indexes on the temporary table. This is one of the final stages before pg_repack performs the table swap and completes the reorganization process.&lt;/P&gt;
&lt;H4&gt;&lt;U&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/U&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-teams="true"&gt;In summary, monitoring pg_repack execution is essential for ensuring a smooth and efficient table reorganization process. Proper visibility into progress and resource consumption helps administrator complete maintenance tasks confidently while maintaining optimal database performance and availability.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4&gt;&lt;U&gt;&lt;STRONG&gt;References&lt;/STRONG&gt;&lt;/U&gt;&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/troubleshoot/how-to-perform-fullvacuum-pg-repack" target="_blank" rel="noopener"&gt;Optimize by using pg_repack - Azure Database for PostgreSQL | Microsoft Learn&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://www.postgresql.org/docs/current/progress-reporting.html?#CREATE-INDEX-PROGRESS-REPORTING" target="_blank" rel="noopener"&gt;PostgreSQL: Documentation: 18: 27.4. Progress Reporting&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://reorg.github.io/pg_repack/?" target="_blank" rel="noopener"&gt;pg_repack 1.5.3 -- Reorganize tables in PostgreSQL databases with minimal locks&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 20 Jul 2026 14:19:52 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/monitoring-and-using-pg-repack-in-azure-database-for-postgresql/ba-p/4537320</guid>
      <dc:creator>janvithac</dc:creator>
      <dc:date>2026-07-20T14:19:52Z</dc:date>
    </item>
    <item>
      <title>Microsoft Defender CSPM Assessments for Azure Database for PostgreSQL Flexible Server - GA</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/microsoft-defender-cspm-assessments-for-azure-database-for/ba-p/4538336</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;As security and regulatory requirements evolve, proactively monitoring and assessing database security posture becomes just as important as detecting active threats. Maintaining a secure and compliant database environment requires continuous visibility into security gaps and configuration drift from established security baselines.&amp;nbsp;&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;We're excited to announce the general availability of &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft Defender for Cloud Security Posture Management (Defender CSPM) assessments for Azure Database for PostgreSQL Flexible Server&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;. These &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;built-in assessments continuously evaluate&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; PostgreSQL server configurations&lt;/STRONG&gt; against PostgreSQL-specific security best practices, helping organizations identify vulnerabilities and misconfigurations and prioritize them based on the risk they pose. &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;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The assessments provide &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;actionable recommendations&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; to help customers strengthen their security baseline, prioritize remediation efforts, and support compliance requirements. Findings are surfaced directly in Microsoft Defender for Cloud, enabling security and operations teams to&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;proactively improve the security posture&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; of their PostgreSQL workloads.&amp;nbsp;&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;An initial set of &lt;STRONG&gt;PostgreSQL-focused assessments&lt;/STRONG&gt; is included at launch, covering areas such as network security, auditing controls, and operational resilience. Additional assessment coverage is planned for future releases.&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;If you already have Microsoft Defender CSPM enabled on subscriptions that contain Azure Database for PostgreSQL flexible servers, &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;no additional setup is required&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;. Assessments are automatically available, provided a risk score and integrated into the existing Defender experience, making it easier to continuously monitor security posture and maintain alignment with organizational and industry security standards.&amp;nbsp;&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;You can view assessment recommendations in the &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;Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;ortal&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; on the resource blade of your Azure Database for PostgreSQL flexible server or the main Defender for Cloud experience, and the &lt;/SPAN&gt;&lt;A href="https://security.microsoft.com/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft Defender portal&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&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;Learn more&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/security/security-defender-for-cloud" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft Defender CSPM assessments for Azure Database for PostgreSQL Flexible Server&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/security/security-defender-for-cloud" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/concept-cloud-security-posture-management" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;What is &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft Defender &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Cloud Security Posture Management?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/tutorial-enable-cspm-plan" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Enable Defender CSPM&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/recommendations-reference-data#azure-data-recommendations" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft Defender &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;D&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;ata &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Security R&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;ecommendations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 17 Jul 2026 20:18:23 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/microsoft-defender-cspm-assessments-for-azure-database-for/ba-p/4538336</guid>
      <dc:creator>TameikaL</dc:creator>
      <dc:date>2026-07-17T20:18:23Z</dc:date>
    </item>
    <item>
      <title>June 2026 Recap: Azure Database for PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/june-2026-recap-azure-database-for-postgresql/ba-p/4537519</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="mce-toc"&gt;
&lt;H2&gt;Table of Contents&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk136gg_1" target="_self"&gt;POSETTE 2026&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk169hu_2" target="_self"&gt;Features 💡&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk10pke_3" target="_self"&gt;Chaos Studio Workspaces for Azure Database for PostgreSQL Flexible Server – Public Preview&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk0oh9k_4" target="_self"&gt;Microsoft Defender Security Assessment for Azure Database for PostgreSQL - General Availability&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk0oh9k_5" target="_self"&gt;DROP CAST Support added&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk0oh9k_6" target="_self"&gt;Latest PostgreSQL minor versions: 18.4, 17.10, 16.14, 15.18, 14.23&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk0oh9k_7" target="_self"&gt;Azure PostgreSQL Learning Bytes 🎓&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_1jtk0oh9k_8" target="_self"&gt;Generate a pgBadger report from Server Logs&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;/DIV&gt;
&lt;H1 id="mcetoc_1jtk136gg_1"&gt;POSETTE 2026&lt;/H1&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;We hosted &lt;/SPAN&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 Eve&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;nt &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;for &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Pos&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;tgres 202&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;6&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; in June! This year marked our 5th annual event featuring 50 speakers and a total of 44 talks. PostgreSQL developers, contributors, and community members came together to share insights on topics covering everything from AI-powered applications to deep dives into PostgreSQL internals. If you missed it, you can catch up by watching the &lt;/SPAN&gt;&lt;A href="https://aka.ms/posette-playlist" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;POSETTE livestream sessions&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&amp;nbsp; If this conference sounds interesting to you and want to be part of it next year, don’t forget to &lt;/SPAN&gt;&lt;A href="https://posetteconf.com/subscribe/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;subscribe to POSETTE news&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1 id="mcetoc_1jtk169hu_2"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Features 💡&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H1&gt;
&lt;H2 id="mcetoc_1jtk10pke_3"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Chaos Studio Workspaces for Azure Database for PostgreSQL Flexible Server&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; – Public Preview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Chaos Studio Workspaces now support Azure Database for PostgreSQL Flexible Server in Public Preview. You point a Workspace at a subscription or resource group, and Chaos Studio discovers your Flexible Server instances and recommends a PostgreSQL zone-down failover Scenario. The Scenario requires a Flexible Server with High Availability enabled. Running the Scenario simulates an availability-zone outage, drives an HA failover, and produces a Scenario report of exactly what happened.&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;Read more here: &lt;/SPAN&gt;&lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Faka.ms%2FChaosStudioPostgreSQL&amp;amp;data=05%7C02%7Ckarlaescobar%40microsoft.com%7Cdb47dc12a06f40aee26e08dedbaf16ad%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639189742202238447%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=NWYKb0VjTh0rs%2F1m2XaZLAURYiXQu8Xxs%2FiPw21MY98%3D&amp;amp;reserved=0" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://aka.ms/ChaosStudioPostgreSQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Try it today: &lt;/SPAN&gt;&lt;A href="https://aka.ms/chaos-portal" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://aka.ms/chaos-portal&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H2 id="mcetoc_1jtk0oh9k_4"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;M&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;icrosoft Defender Security Assessment for Azure Database for PostgreSQL - General Availability&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Microsoft Defender security posture assessments for Azure Database for PostgreSQL Flexible Server are now generally available. Built-in assessments continuously evaluate PostgreSQL configurations against PostgreSQL-specific security best practices, helping identify vulnerabilities and misconfigurations with actionable remediation guidance. Customers can use these assessments to strengthen their security baseline, prioritize remediation efforts, and support compliance requirements.&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;Assessments are automatically available for servers already protected by Microsoft Defender for Cloud Security Posture Management (CSPM), with no additional setup required. An initial set of assessments is available today, with additional coverage planned for future releases to help strengthen the security posture of PostgreSQL workloads.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;Read more here:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Flearn.microsoft.com%2Fen-us%2Fazure%2Fpostgresql%2Fsecurity%2Fsecurity-defender-for-cloud%23microsoft-defender-for-cloud-security-posture-management-cspm-assessments&amp;amp;data=05%7C02%7Ckarlaescobar%40microsoft.com%7Ce2e98817b81c4a6d29a008ded8679ba6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639186136703797249%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=w9L3%2BHcWl%2BDy2cpcjhxo9U4Tm57QmCc152q%2Fl7slXMQ%3D&amp;amp;reserved=0" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft Defender for Cloud - Azure Database for PostgreSQL | Microsoft Learn&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H2 id="mcetoc_1jtk0oh9k_5"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;D&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;ROP&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; CAST &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Su&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;ppo&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;rt added&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Custom casts can be useful when applications need to convert between data types in a way that matches their business logic or migration requirements.&amp;nbsp;&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;Previously, while you could create custom casts, it wasn’t possible to drop them once they were no longer needed. With this update, you can now use the PostgreSQL DROP CAST command to clean up unused or obsolete casts, making it easier to manage schema customizations over time.&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;Example:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;CREATE CAST (bigint AS text) WITH INOUT; 
… 
DROP CAST IF EXISTS (bigint AS text); &lt;/LI-CODE&gt;
&lt;H2 id="mcetoc_1jtk0oh9k_6"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Latest&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; PostgreSQL minor versions: 18.4, 17.10, 16.14, 15.18, 14.23&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Azure Database for PostgreSQL now supports the&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; latest PostgreSQL minor versions: 18.4, 17.10, 16.14, 15.18, and 14.23&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. These updates are applied automatically during planned maintenance windows, helping keep your databases current with the latest PostgreSQL community fixes and reliability improvements, with no manual action required.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This release includes fixes across query correctness, planner behavior, replication, backup and restore tooling, logical replication, foreign data wrapper behavior, and timezone data, improving overall stability and correctness of database operations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For details about the minor release, see the &lt;/SPAN&gt;&lt;A href="https://www.postgresql.org/about/news/postgresql-184-1710-1614-1518-and-1423-released-3297/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;PostgreSQL announcement&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1 id="mcetoc_1jtk0oh9k_7"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Azure PostgreSQL &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Learning Byte&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;s &lt;/SPAN&gt;&lt;/SPAN&gt;🎓&lt;/H1&gt;
&lt;H2 id="mcetoc_1jtk0oh9k_8"&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Generate a &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;gBadger&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 1"&gt;report from &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Ser&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;ver&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 1"&gt;L&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;ogs&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Need a quick workload readout from PostgreSQL logs? Use pgBadger with Azure PostgreSQL &lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/how-to-server-logs-portal" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Server Logs&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;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Fast path:&lt;/SPAN&gt; &lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;Server logs&lt;/STRONG&gt; → &lt;STRONG&gt;Download '&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;.log'&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; files&lt;/STRONG&gt; → &lt;STRONG&gt;Generate pgBadger report&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Before collecting logs, set &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;log_line_prefix&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; in &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Server parameters&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;: &lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;%m user=%u db=%d pid=%p: &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Then enable &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Server logs &amp;gt; Capture logs for download&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, download the &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.log&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; files for the time window you want to analyze, place them in a local folder, and run:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;FOLDER=&amp;lt;logs-folder-name&amp;gt; 
 
pgbadger -f stderr \ 
  --prefix '%m user=%u db=%d pid=%p:' \ 
  ./$FOLDER/*.log \ 
  -o ./$FOLDER/pgbadger-report.html &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Open the generated report:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;start ./$FOLDER/pgbadger-report.html &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This gives you a quick HTML report for query activity, connection patterns, events, lock waits, and workload spikes - without setting up a storage account, BlobFuse mount, or JSON extraction pipeline.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;💡&lt;STRONG&gt;Tip&lt;/STRONG&gt;:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Start with one or two hourly log files first. Confirm the report looks right, then expand the log analysis window.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Learn more:&lt;/SPAN&gt; &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/log-insights-in-minutes-a-simpler-pgbadger-workflow/4531932" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Log Insights in Minutes: A Simpler pgBadger Workflow&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 16 Jul 2026 19:06:43 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/june-2026-recap-azure-database-for-postgresql/ba-p/4537519</guid>
      <dc:creator>karlaescobar</dc:creator>
      <dc:date>2026-07-16T19:06:43Z</dc:date>
    </item>
    <item>
      <title>PostgreSQL on Azure: Two services, one future-proofed ecosystem</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/postgresql-on-azure-two-services-one-future-proofed-ecosystem/ba-p/4536578</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="none"&gt;At Microsoft Build 2026, the Azure Databases team announced the &lt;/SPAN&gt;&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai-era/4524094" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;public preview of&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt; Azure HorizonDB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;, a new powerhouse for PostgreSQL in the cloud. It’s a fully managed, PostgreSQL-compatible cloud database service that delivers sub-millisecond latency, rapid read scale-out, and seamless integration with Microsoft Foundry to empower teams to build secure, compliant and high-performing applications with confidence. At the same event, we also &lt;/SPAN&gt;&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/announcing-new-security-maintenance-and-analytics-features-for-postgresql-at-mic/4524559" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;announced several enhancements to the existing managed PostgreSQL offering&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;, Azure Database for PostgreSQL flexible server, boosting performance, analytics and security, and expanding tooling for migration scenarios.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&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;Where there was one, now &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;there’s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt; two&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;Now our customers have two strong options to choose from. Azure Database for PostgreSQL remains a reliable, cost-effective, fully open-source compatible workhorse for most users’ everyday needs. Azure HorizonDB is the new PostgreSQL-compatible service with an elastic scale-out architecture built on a highly optimized shared storage system that unlocks &lt;/SPAN&gt;&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai-era/4524094" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;3&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;x &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;faster OLTP &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;performance&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; and other cloud-native advantages for the most demanding workloads. &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;With this new service, you might be wondering which service is the best fit. Let’s take a closer look at these options and explore where they align and differ and what you might want to consider when making your choice.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&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;Azure Database for PostgreSQL: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Enterprise ready, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;managed open source&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;Microsoft is one of the largest contributors to the open-source Postgres project and has also invested heavily in PostgreSQL managed services on Azure. Microsoft engineers have authored or co-authored hundreds of code commits and provided extensive reviews, and, to date, have made more than 345 commits and changed more than 64K lines of code for PostgreSQL 19. In the cloud, Azure Database for PostgreSQL is built on the open-source ecosystem, sharing the same extensions and experience that developers and DBAs know and love. Patching, backups, scaling, and monitoring are all simple, one-click operations. If you have an app that already uses a PostgreSQL database, in another cloud or on-premises, migrating to Azure for the added benefits is an easy lift and shift.&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;Inside Azure Database for PostgreSQL&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Azure Database for PostgreSQL is a mature, feature-rich service already battle-tested by thousands of applications and being used by Fortune 500s across sectors.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Enterprise-grade performance: &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;Compute tiers can scale up to 192 vCores with features like read replicas and elastic clusters, which is based on the open-source Citus extension and unique to this class of service, make it easy to right-size workloads and optimize performance by offloading read-heavy traffic or sharding data across nodes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Reliability and security: &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;Backed by Azure’s robust infrastructure, Azure Database for PostgreSQL comes equipped with high availability and zone-redundant options, point-in time restore and security features, including data encryption, network isolation, and Entra ID for enterprise identity.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Frictionless migrations: &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;Migrating existing PostgreSQL workloads to Azure Database for PostgreSQL is very straightforward thanks to built-in migration tooling. We’ve even launched AI-assisted tooling for Oracle to PostgreSQL migrations in VS Code, which leverages GitHub Copilot AI to handle app and schema conversions and pre-migration validations.&amp;nbsp;&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;From incorporating cutting-edge hardware, horizontal scaling and Microsoft Fabric and Microsoft Foundry integrations, to supporting 90+ open-source extensions and counting, we continue to optimize the service to meet the needs of our customers building on open-source Postgres.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&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;Azure HorizonDB: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;Next&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;-gen engine &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;to build &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt;what’s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 1"&gt; next&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;Azure HorizonDB was designed and purpose-built to meet the needs of modern AI-native applications and large-scale enterprise migrations. Shireesh Thota, Azure Databases CVP, describes it as the database of choice for workloads that need &lt;/SPAN&gt;&lt;A href="https://www.infoworld.com/article/4093191/azure-horizondb-microsoft-goes-big-with-postgresql.html" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;“a lot of storage, want really fast latencies and significantly higher IOPS.”&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt; &lt;SPAN data-contrast="none"&gt;The service offers faster throughput than open-source PostgreSQL and rapid compute scale-out to support the performance and availability needs of your most demanding applications.&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;Inside Azure HorizonDB&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Azure HorizonDB is where performance meets possibility, empowering teams to build intelligent apps to scale, modernize, and innovate without compromise.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Cloud-tuned performance: &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;The cloud-native architecture of Azure &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;HorizonDB fully decouples compute and storage, enabling &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;users to scale database resources independently. The service can support deployments up to 3,072 vCores and 128 TB of shared storage for a single workload, and provides a single endpoint for read replicas with transparent load balancing to deliver massive read throughput seamlessly to the application.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Reliability and security: &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;Azure HorizonDB comes standard with features to support production-level, mission-critical enterprise workloads. Built-in multi-availability zone (AZ) replication reduces failover time to less than 5 seconds, and native integration with Microsoft Entra ID and private endpoint networking ensures Azure HorizonDB meets the Azure-standard enterprise-grade security from day one.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Tailored for AI and next-gen apps:&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt; Azure &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;HorizonDB provides an extensive set of AI features for building modern applications. In comparison to similar PostgreSQL services in the cloud, &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;IDC described Azure HorizonDB as having &lt;/SPAN&gt;&lt;A href="https://www.theregister.com/2025/11/19/microsoft_azure_horizondb/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;"fewer moving parts and a straighter path to AI features.”&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; Azure HorizonDB ships with Microsoft’s latest version of DiskANN vector indexing, which includes advanced filtering that delivers up to &lt;/SPAN&gt;&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai-era/4524094" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;3&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;x faster vector search&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt; than traditional &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;pgvector indexes&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;. It also comes with built-in AI Model Management for native integration to Microsoft Foundry models, AI Functions to invoke models from SQL, and AI Pipelines to provide durable orchestration of data modification.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;Developer productivity&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;: Along with building the best Postgres service, Microsoft is committed to delivering the best Postgres developer tools to the entire community. The &lt;/SPAN&gt;&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Microsoft &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;PostgreSQL extension for Visual Studio (VS) Code&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt; makes the coding environment Postgres-aware to help optimize queries, schemas and query performance using AI.&amp;nbsp;&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;Azure HorizonDB is the next-generation of PostgreSQL on Azure for mission-critical, high-throughput, and data-intensive workloads. For everything else, Azure Database for PostgreSQL remains a strong choice.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Making &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;your&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 2"&gt;selection&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Adopting technology should always be driven by a real need. Having two choices is great, but it raises the logical question: “which one is right for me and when?”&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;Choose Azure Database for PostgreSQL when:&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You’re migrating existing Postgres databases as-is. You can migrate seamlessly to Azure Database for PostgreSQL with minimal tweaks or reconfigurations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You require full open-source compatibility, including rapid adoption of new community versions. Azure Database for PostgreSQL now ships major versions on the same day as the community release.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You want to start now and decide later. Azure Database for PostgreSQL is generally available in 60+ regions today. Later, if your project requires greater scale, you can upgrade to Azure HorizonDB, and the migration process will be quick and easy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Choos&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;e Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;HorizonDB when&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;:&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You’re migrating tier-1 workloads to the cloud that already have critical scale, performance, and availability requirements. Up to 128 TB of storage and 3,072 vCores for a single workload makes Azure HorizonDB the ideal destination for these workloads.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You anticipate requirements that go beyond Azure Database for PostgreSQL’s capabilities. Azure HorizonDB expands on the capabilities of Azure Database for PostgreSQL, so you’ll be future proofed for scale and reliability.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;You are focused on building next-gen intelligent apps. Azure HorizonDB is optimized for building new AI applications, enabling developers to ship faster with fewer moving parts.&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;Both services are built on the core Postgres engine, and upgrading to Azure HorizonDB is easy. If your scenario changes, your toolkit can change too. Azure offers the managed service to support you either way.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Choose &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;the cloud with the deepest Postgres &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;expertise&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;:40,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;The PostgreSQL ecosystem on Azure is richer than ever. With both Azure Database for PostgreSQL and Azure HorizonDB, Azure covers the spectrum from steady, everyday workloads to cutting-edge, innovative ones. Whether you’re in a two-person startup or a Fortune 500 enterprise, PostgreSQL on Azure can meet your business’ needs.&amp;nbsp;&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;Now is the perfect time to make a move to Postgres on Azure:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;A href="https://azure.microsoft.com/en-us/products/postgresql/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Learn more about &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure Database for PostgreSQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;A href="https://azure.microsoft.com/en-us/products/horizondb" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Learn more about &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure HorizonDB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 14 Jul 2026 15:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/postgresql-on-azure-two-services-one-future-proofed-ecosystem/ba-p/4536578</guid>
      <dc:creator>charlesfeddersenMS</dc:creator>
      <dc:date>2026-07-14T15:00:00Z</dc:date>
    </item>
    <item>
      <title>From RAG to agents: Build AI pipelines inside Azure HorizonDB</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/from-rag-to-agents-build-ai-pipelines-inside-azure-horizondb/ba-p/4532696</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;By Abe Omorogbe, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Navya&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; Teja Gajula&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-teams="true"&gt;&lt;SPAN data-person-mri="8:orgid:5d314a16-231c-40c3-b2d7-60818259729f" data-is-share-contact="false" data-mention-type="person" aria-label="Mentioned Binnur Gorer"&gt;Binnur Gorer, B Harsha Kashyap,&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN data-person-mri="8:orgid:4f6ccf88-de1e-417e-9971-f4263b13b4d2" data-is-share-contact="false" data-mention-type="person" aria-label="Mentioned Krishnakumar Ravi (KK)"&gt;Krishnakumar Ravi (KK) &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;from &lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Microsoft&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; PostgreSQL AI team&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;If &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you’ve&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; ever shipped a RAG app, this &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;will feel&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;familiar. Your data lives in Postgres. But the pipeline that turns that data into vectors lives somewhere else, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pread&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; across &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;external&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; service&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, queue&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, and retry logic. And &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;when&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; the embedding API &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;hiccups&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; mid-batch? &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;That’s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; a 2 a.m. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;roduction incident&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;. You &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;didn’t&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; set out to build your own embedding service. You just wanted to &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;search&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; your documents.&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;And RAG is only the beginning. The moment AI works on your data: extraction, summarization, reranking, keeping embeddings fresh, or powering agent&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you’re&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; back to stitching together more services, queues, and glue code, all outside the database.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI pipelines in Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; (Preview)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;removes that entir&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;e &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;stack&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Define your workflows steps like chunking, embeding, extracting, and generating in SQL, and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; runs them as &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; pipelines next to your data. No orchestrator. No glue code. Just Postgres.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;In this post &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;we'll&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; cover:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-ai-preprocessing" target="_blank" rel="noopener" data-lia-auto-title="The external-orchestrator issue that every AI on Postgres team eventually hits" data-lia-auto-title-active="0"&gt;The external-orchestrator issue that every AI on Postgres team eventually hits&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-anatomy" target="_blank" rel="noopener" data-lia-auto-title="What AI pipelines are, and the four-part anatomy that makes them click&amp;nbsp;" data-lia-auto-title-active="0"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;What AI pipelines are, and the four-part anatomy that makes them click&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-use-cases" target="_blank" rel="noopener" data-lia-auto-title="Use cases worth trying: semantic search, knowledge extraction, content generation, smarter reranking, and always-fresh embeddings&amp;nbsp;" data-lia-auto-title-active="0"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;U&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;se cases&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;worth &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;trying:&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;semantic search, knowledge extraction, content generation, smarter reranking, and always-fresh embeddings&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-vs-code" target="_blank" rel="noopener" data-lia-auto-title="How to watch your pipelines run as live graphs in VS Code" data-lia-auto-title-active="0"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;How to watch your pipelines run as live graphs in VS Code&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-start-now" target="_blank" rel="noopener" data-lia-auto-title="How to spin up&amp;nbsp;HorizonDB and run your first pipeline today&amp;nbsp;" data-lia-auto-title-active="0"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;How to spin up&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; and run your first pipeline today&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt; &lt;/SPAN&gt;&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 2"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;🚀 Try it on Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI pipelines are built into Microsoft's new PostgreSQL cloud service&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;no&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; extra infrastructure to stand up. Write&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char" data-ccp-charstyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;a31b87fc-7929-525d-a968-aa0f568a0536|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Consolas&amp;quot;,469777842,&amp;quot;&amp;quot;,469777843,&amp;quot;&amp;quot;,469777844,&amp;quot;Consolas&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Consolas&amp;quot;,268442635,&amp;quot;22&amp;quot;,469775450,&amp;quot;Verbatim Char&amp;quot;,201340122,&amp;quot;1&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;VerbatimChar&amp;quot;,335572020,&amp;quot;1&amp;quot;,469778324,&amp;quot;Body Text Char&amp;quot;]}"&gt;ai.create_pipeline&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;(...)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, call&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.run&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;(...)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, and it runs.&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Get started in HorizonDB →&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;a id="community--1-ai-preprocessing" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 2"&gt;AI preprocessing runs outside the database, far from your&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;&amp;nbsp;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;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph" data-ccp-parastyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;276295ed-5df2-5456-988c-5fdbab071054|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Aptos&amp;quot;,469777842,&amp;quot;&amp;quot;,469777843,&amp;quot;&amp;quot;,469777844,&amp;quot;Aptos&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Aptos&amp;quot;,268442635,&amp;quot;24&amp;quot;,335559739,&amp;quot;180&amp;quot;,335559738,&amp;quot;180&amp;quot;,469775450,&amp;quot;First Paragraph&amp;quot;,201340122,&amp;quot;2&amp;quot;,134234082,&amp;quot;true&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;FirstParagraph&amp;quot;,335572020,&amp;quot;1&amp;quot;,469775498,&amp;quot;Body Text&amp;quot;,469778324,&amp;quot;Body Text&amp;quot;]}"&gt;The standard way to get data into a vector store looks reasonable on a whiteboard: a service reads source rows, calls an embedding API, and writes chunks back to Postgres. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;However, some interesting &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;issues&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; often &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;occur&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; in&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;production.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1002" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;The embedding API &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;fails &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;mid-&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;batch,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;there's&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;no shared checkpoint&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;showing which rows were completed. You rerun the job, and the extra API calls increases &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;cost&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1002" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;A worker crashes after writing chunks but&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;before&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;flipping the parent row's&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;processed&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;flag. Now your &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;embeddings&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;are&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; quietly &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;inconsistent,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; and nobody knows.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Every one of these is the same missing primitive:&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;STRONG&gt;durable, checkpointed execution that lives where your data lives&lt;/STRONG&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;External orchestrators&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; can do it, but now &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;you're&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;operating&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; a second &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;service&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; just to feed the first one.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI pipelines move that logic into &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; itself. The source, the steps, the sink, and the full run history are all SQL protected by the same transactions, backups, and point-in-time &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;restore&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; your data already has. The database is already where your data &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;commits&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;It's&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;a&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; natural place for the pipeline to &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;live&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;too.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;a id="community--1-anatomy" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 2"&gt;Anatomy of an AI pipeline&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; in HorizonDB&lt;/SPAN&gt;&lt;/H2&gt;
&lt;img&gt;AI Pipeline in HorizonDB, the steps are optional and can be adjusted as needed.&lt;/img&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;A pipeline has four parts:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="1003" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Source&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; where rows come from. A&lt;/SPAN&gt; &lt;EM&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;table_source&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;(...)&lt;/SPAN&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;SPAN data-ccp-parastyle="Compact"&gt;over a &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; table, optionally with an&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;incremental_column&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;so the pipeline skips rows it already processed.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="1003" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Steps&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;the AI operations that transform each row, in order. Each step appends columns to the in-flight batch.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt; &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="1003" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Sink&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;where results land, ready for&amp;nbsp;use by&amp;nbsp;your AI apps or agent.&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="1003" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Trigger&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; &lt;/SPAN&gt;&lt;EM style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;'&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;on_change&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;'&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;(run automatically when source rows change) or&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;'manual'&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;(run only when you call&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.run&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;).&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Those four parts give the pipeline its shape. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;steps &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;are&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; where you define the AI work itself, using composable building blocks:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 94.0741%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Step&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;What it does&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.chunk&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Split long text into overlapping chunks&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.embed&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Generate vector embeddings&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.extract&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Pull structured fields out of text with an LLM&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.generate&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Generate text from a prompt&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp; (i.e content generation, classify, summarize and more)&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.rank&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Score documents against a query&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 23.1693%" /&gt;&lt;col style="width: 76.9095%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;How &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;the&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; pieces fit &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;together.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;The &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;ai.*&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; API gives you the&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; AI&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; pipeline shape: sources define where data comes from, steps define the AI work to perform, sinks define where results land, and triggers define when the pipeline runs. Under the covers, HorizonDB turns that definition into a durable execution graph, where each step can be checkpointed, retried, and resumed if something fails.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559685&amp;quot;:0,&amp;quot;335559731&amp;quot;:0,&amp;quot;335559737&amp;quot;:480,&amp;quot;335559738&amp;quot;:100,&amp;quot;335559739&amp;quot;:100}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;Built on open source&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Block Text"&gt;That durability &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;isn't&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; magic&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;every AI pipeline compiles down to a graph that runs on&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;, Microsoft's open-source durable-execution engine for PostgreSQL (built on the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/duroxide" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;duroxide&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Block Text"&gt;Rust runtime). The&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.*&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Block Text"&gt;API is the AI-shaped surface &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;(&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;sources, steps, sinks, triggers&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Block Text"&gt;and&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Block Text"&gt;is the general-purpose engine underneath that handles checkpointing, retries, and crash recovery. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;So,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; your pipelines stand on a transparent, inspectable foundation you can read, and run on any Postgres 17&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; &amp;amp; 18&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;. No black &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;box, no lock-i&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;n.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559685&amp;quot;:0,&amp;quot;335559731&amp;quot;:0,&amp;quot;335559737&amp;quot;:480,&amp;quot;335559738&amp;quot;:100,&amp;quot;335559739&amp;quot;:100}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;a id="community--1-use-cases" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 2"&gt;Use case 1&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; Semantic search over &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;your d&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;ata&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;This is one of the most popular use cases. Turn a table of documents into searchable vectors, durably, and&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;keep them fresh&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;as&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; the data changes. That last part matters: in production, documents are edited, added, and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;deleted&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; constantly, and every change needs the right chunks and embeddings updated without reprocessing the entire corpus or leaving stale vectors behind. With &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;AI &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pipeline&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; can track those incremental updates for you. Chunk the body, embed each chunk, and land the result in a &lt;/SPAN&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-index-diskann" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;DiskANN&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-index-diskann" target="_blank" rel="noopener"&gt;-indexed&lt;/A&gt; table.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Define the pipeline: source -&amp;gt; chunk -&amp;gt; embed -&amp;gt; sink. 
SELECT ai.create_pipeline( 
    name   =&amp;gt; 'rag_pipeline', 
    source =&amp;gt; ai.table_source(table_name =&amp;gt; 'documents'), 
    steps  =&amp;gt; ARRAY[ 
        ai.chunk(input =&amp;gt; 'content', chunk_size =&amp;gt; 512, overlap =&amp;gt; 64), 
        ai.embed(model =&amp;gt; 'default-embedding', input =&amp;gt; 'chunk_text', dimensions =&amp;gt; 1536) 
    ], 
    trigger =&amp;gt; 'on_change',   -- re-embed automatically as rows change 
    sink    =&amp;gt; ai.table_sink('rag_pipeline_output') 
); 

-- Run it
SELECT ai.run('rag_pipeline'); 
 
-- Search your data 
SELECT chunk_text, embedding &amp;lt;=&amp;gt; azure_openai.create_embeddings('text-embedding-3-small', 'how does vector search work?')::vector AS distance 
FROM rag_pipeline_output
ORDER BY distance 
LIMIT 3; &lt;/LI-CODE&gt;
&lt;P&gt;📘&amp;nbsp;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;Read more details in the AI Pipelines documentation&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;That's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; the entire ingestion &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;layer;&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;chunking, embedding, checkpointing, retries, and sink writes in one definition. Because&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;trigger =&amp;gt; '&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;on_change&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;'&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;EM&gt;,&lt;/EM&gt; the pipeline &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;update&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;s &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;embeddings whenever source rows change, processing only what is new or &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;modified&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; instead of redoing the whole corpus. Your vectors stay &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;in sync&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; with your data, and your ingestion work stays efficient as the dataset grows. Point a query at the &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-index-diskann" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;DiskANN&lt;/SPAN&gt; &lt;SPAN data-ccp-charstyle="Hyperlink"&gt;index&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;you've&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; got production semantic search without a single line of application glue.&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;That's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; the whole loop: define, run, inspect. The embedding service you were about to build the queue, the workers, the retry logic, the checkpoint table, the 2 a.m. &lt;SPAN data-ccp-parastyle="Body Text"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;roduction incident&lt;/SPAN&gt; doesn't happens.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Why &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;it's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; better than &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;an external &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;service:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;a failure in&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.embed&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;EM&gt; &lt;/EM&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;never re-runs&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;EM&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.chunk&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;(&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;)&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;,&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;each step is a durable node. If the database restarts mid-run, it resumes from the last checkpointed batch, not row zer&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;o.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Use case 2&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; Turn unstructured text into structured metadata &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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Support tickets, contracts, product reviews&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, research&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;papers&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; are&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; full of structure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;that's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; locked inside &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;unstructured &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;document&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;.&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.extract&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;EM&gt; &lt;/EM&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pulls named fields out of text and merges them into the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;metadata&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;JSONB column, so you can filter and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;aggregate on&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; thing&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;s an LLM r&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;ead for you.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT ai.create_pipeline( 
    name   =&amp;gt; 'extraction_pipeline', 
    source =&amp;gt; ai.table_source(table_name =&amp;gt; 'documents'), 
    steps  =&amp;gt; ARRAY[ 
        ai.chunk(input =&amp;gt; 'content'), 
        ai.extract( 
            input =&amp;gt; 'chunk_text', 
            data  =&amp;gt; ARRAY['topics: string - the main topics discussed', 
                           'entities: string - named people, products, or places'] 
             model =&amp;gt; 'my-gpt' -- optional, the default model when AI model management is activate 
        ) 
    ], 
    sink =&amp;gt; ai.table_sink('extraction_pipeline_output') 
); 
 
SELECT ai.run('extraction_pipeline'); 
 
-- Now query the structured fields the LLM extracted: 
SELECT doc_id, metadata-&amp;gt;'topics' AS topics, metadata-&amp;gt;'entities' AS entities 
FROM extraction_pipeline_output; &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;📘&amp;nbsp;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;Read more details in the AI Pipelines documentation&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;You describe each field as a&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;label: description&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;string&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; in the&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;EM&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;ai.extract&lt;/SPAN&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; step&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; does the rest durably, in bulk, with the same retry-and-resume guarantees.&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Each field is a label, either a bare name like &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;product&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, or the detailed form &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&lt;EM&gt;name: type - description&lt;/EM&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;(for example `sentiment: number - sentiment score from 1 to 5`). &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; does the rest, durably, in bulk, with the same retry-and-resume guarantees.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Use case 3&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; Summarize and rewrite content at scale &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;/H2&gt;
&lt;P&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.generate&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;EM&gt; &lt;/EM&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;runs an LLM prompt against every row&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; perfect for bulk summarization, classification, tone normalization, or generating titles. Because &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;it's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; a pipeline, "&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;summarize&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; 4 million documents" becomes a job that survives restarts instead of a script you &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;have to&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;monitor&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; overnight.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT ai.create_pipeline( 
    name   =&amp;gt; 'summary_pipeline', 
    source =&amp;gt; ai.table_source(table_name =&amp;gt; 'documents'), 
    steps  =&amp;gt; ARRAY[ 
        ai.chunk(input =&amp;gt; 'content'), 
        ai.generate( 
            input =&amp;gt; 'chunk_text', 
            system_prompt =&amp;gt; 'Create a concise summary in 50 words or fewer.'  
            model =&amp;gt; 'my-gpt' -- optional, the default model when AI model management is activate 
        ) 
    ], 
    sink =&amp;gt; ai.table_sink('generation_pipeline_output') 
); 
 
SELECT ai.run('summary_pipeline'); 
 
-- Now query the generated text: 
SELECT doc_id, left(generated_text, 100) AS summary_preview 
FROM generation_pipeline_output 
WHERE generated_text IS NOT NULL 
LIMIT 5; &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;📘 &lt;/SPAN&gt;&lt;A class="lia-external-url" style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;Read more details in the AI Pipelines documentation&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Swap the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;system_prompt&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;and the same shape becomes a classifier ("&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Label&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; this ticket as billing, bug, or feature request"), a translator, or a headline generator. The instruction goes in&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;system_prompt&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;; the result lands in&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;generated_text&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Use case &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;4&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; Keep embeddings fresh, and re-embed cleanly when the model changes&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;This is where AI pipelines become especially useful. In a real AI app, two things change constantly: &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;your data&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;STRONG&gt;your model&lt;/STRONG&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; AI pipelines are designed to handle both changes directly.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Your data changes.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;Set&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;incremental_column&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;and an&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;on_change&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;trigger, and the pipeline only embeds&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;new or changed&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;rows, automatically, forever, until you pause or drop it.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT ai.create_pipeline( 
    name   =&amp;gt; 'rag_pipeline', 
    source =&amp;gt; ai.table_source( 
        table_name =&amp;gt; 'documents', 
        incremental_column =&amp;gt; 'updated_at'   -- only process what changed 
    ), 
    steps  =&amp;gt; ARRAY[ 
        ai.chunk(input =&amp;gt; 'content'), 
        ai.embed(model =&amp;gt; 'default-embedding', input =&amp;gt; 'chunk_text', dimensions =&amp;gt; 1536) 
    ], 
    trigger =&amp;gt; 'on_change', 
    sink    =&amp;gt; ai.table_sink('rag_pipeline_output') 
); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Your model changes.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Bump the model or the dimensions, then run a single, resumable backfill&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; no migration script, no babysitting:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;TRUNCATE rag_pipeline_output;  
SELECT ai.backfill('rag_pipeline'); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;📘&amp;nbsp;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;Read more details in the AI Pipelines documentation&lt;/A&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The backfill runs as one durable instance. If the database restarts mid-backfill, it picks up from the last checkpointed batch instead of starting over.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The painful "re-embed everything" migration becomes a one-liner you can actually trust.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;a id="community--1-vs-code" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 2"&gt;Watch your pipelines run as live graphs in VS Code&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;A pipeline you can&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;see&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;is a pipeline you can trust. Install the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/development/vs-code-extension/vs-code-overview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;PostgreSQL extension for VS Code&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, connect to &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, then right-click your database and open&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Pipelines &amp;amp; Workflows → AI Pipelines&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;img&gt;AI Pipelines in HorizonDB&lt;/img&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Select any run and the center pane&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;renders&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; the execution as a&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;color-coded graph&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1004" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="9" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Blue 🔵 :&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;source and sink (where data enters and exits)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1004" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="9" data-aria-level="1"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;STRONG&gt;Green 🟢 :&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;processing steps (chunk, embed, extract, generate, rank)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt; &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1004" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="9" data-aria-level="1"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;STRONG&gt;Pink 🟣&amp;nbsp;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;STRONG&gt;:&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;external model and service calls&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;For each run you can read the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;status&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;(&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;completed&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;,&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;running&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;,&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;failed&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;), the&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;run ID&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;for traceability,&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;start time and duration&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;for performance, and a link back to the pipeline definition. When a run fails, open the graph and jump straight to the step where execution stopped&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;no log spelunking.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="4"&gt;&lt;a id="community--1-start-now" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN class="lia-linked-item" data-ccp-parastyle="heading 4"&gt;Get Started: Try It Now&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;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:600,&amp;quot;335559739&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;We have a few demoes of AI pipelines in action:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:150}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 92.5%; height: 194px; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;Resource&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;Link&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Microsoft Build AI Pipeline Demo&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;335557856&amp;quot;:16777215,&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;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://www.youtube.com/watch?v=_9JC2s7G3l8" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;Simplify app dev with cloud-native PostgreSQL in Azure HorizonDB | DEM364&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Microsoft Build AI Pipeline GitHub&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;A class="lia-external-url" href="https://github.com/microsoft/Build26-DEM364-simplify-app-dev-with-cloud-native-postgresql-in-azure-horizondb" target="_blank" rel="noopener"&gt;AI Pipelines Demo GitHub Repo | DEM364&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Microsoft Mechanic Demo&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;335557856&amp;quot;:16777215,&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;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;A class="lia-external-url" href="https://youtu.be/EzEPFMJuvrk?si=3dofK1sq3g1upHt5&amp;amp;t=504" target="_blank" rel="noopener"&gt;AI Pipeline Demo on Microsoft Mechanic&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 38.8px;"&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;Documentation&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.8px;"&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;A href="http://learn.microsoft.com/azure/horizondb/ai/ai-pipelines&amp;nbsp;" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;AI pipelines on &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 27.4417%" /&gt;&lt;col style="width: 72.5383%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;Enabling AI pipelines takes minutes: enable to &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;&lt;EM&gt;azure_ai, pg_durable, vecto&lt;/EM&gt;r &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;and &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;pg_diskann&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;extensions and you can get started.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:150}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- On Azure HorizonDB — the extensions are built in. 
CREATE EXTENSION IF NOT EXISTS pg_durable; 
CREATE EXTENSION IF NOT EXISTS azure_ai; 
CREATE EXTENSION IF NOT EXISTS vector; 
CREATE EXTENSION IF NOT EXISTS pg_diskann; &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="none"&gt;That's it, your PostgreSQL database can now run AI pipelines&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:150}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-linked-item" data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:150}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;a id="community--1-learn" class="lia-anchor"&gt;&lt;/a&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 32px;" data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Learn more&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 32px;" 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;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="12" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;A class="lia-external-url" href="http://learn.microsoft.com/azure/horizondb/ai/ai-pipelines&amp;nbsp;" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;MS Learn AI pipelines on &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="13" data-aria-level="1"&gt;&lt;A class="lia-external-url" href="http://learn.microsoft.com/azure/horizondb&amp;nbsp;" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; Preview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="14" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;A class="lia-external-url" href="http://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;pg_durable&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;A class="lia-external-url" href="http://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt; on GitHub (open source)&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="15" data-aria-level="1"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;A class="lia-external-url" href="http://learn.microsoft.com/azure/horizondb/development/durable-functions" target="_blank" rel="noopener"&gt;MS Learn Durable Functions on HorizonDB&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="16" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;A class="lia-external-url" href="http://learn.microsoft.com/azure/horizondb/ai/vector-index-diskann" target="_blank" rel="noopener"&gt;Scalable vector search with DiskANN&lt;/A&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1005" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="17" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;A class="lia-external-url" href="http://learn.microsoft.com/azure/horizondb/development/vs-code-extension" target="_blank" rel="noopener"&gt;PostgreSQL extension for VS Code&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Thu, 02 Jul 2026 16:52:43 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/from-rag-to-agents-build-ai-pipelines-inside-azure-horizondb/ba-p/4532696</guid>
      <dc:creator>abeomor-msft</dc:creator>
      <dc:date>2026-07-02T16:52:43Z</dc:date>
    </item>
    <item>
      <title>Log Insights in Minutes: A Simpler pgBadger Workflow</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/log-insights-in-minutes-a-simpler-pgbadger-workflow/ba-p/4531932</link>
      <description>&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Sometimes the fastest way to understand a PostgreSQL workload is not another dashboard. It is a good log report.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;A href="https://github.com/darold/pgbadger" target="_blank" rel="noopener"&gt;pgBadger&lt;/A&gt; is a PostgreSQL log analysis tool that turns raw PostgreSQL logs into an interactive HTML report. It helps summarize query activity, connection patterns, errors, temporary files, lock waits, autovacuum activity, and more.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Earlier &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/how-to-generate-pgbadger-report-from-azure-database-for-postgresql-flexible-serv/3756328" target="_blank" rel="noopener"&gt;guidance&lt;/A&gt; for generating pgBadger reports from Azure Database for PostgreSQL Flexible Server focused on exporting logs through Diagnostic Settings, storing them in a storage account, and then using tools such as BlobFuse and &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;jq&lt;/CODE&gt; to extract PostgreSQL log lines from JSON files.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;That workflow is still useful when customers centralize logs across multiple servers. However, if you are already using the &lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/how-to-server-logs-portal" target="_blank" rel="noopener"&gt;Server logs feature&lt;/A&gt; in Azure Database for PostgreSQL Flexible Server, there is a much simpler path.&lt;/P&gt;
&lt;DIV style="border-left: 5px solid #0078d4; background-color: #f3f9ff; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;In this post:&lt;/STRONG&gt; You’ll learn how to generate a pgBadger HTML report from Azure Database for PostgreSQL Flexible Server by downloading native PostgreSQL &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files directly from the Azure portal. No storage account, BlobFuse mount, or JSON extraction required.&lt;/P&gt;
&lt;/DIV&gt;
&lt;DIV style="border: 1px solid #d0d7de; border-radius: 8px; padding: 18px 22px; margin: 24px 0; background-color: #f6f8fa;"&gt;
&lt;P style="font-size: 18px; line-height: 1.65; margin-top: 0;"&gt;&lt;STRONG&gt;Fast path&lt;/STRONG&gt;&lt;/P&gt;
&lt;OL style="font-size: 18px; line-height: 1.65; margin-bottom: 0;"&gt;
&lt;LI&gt;Configure &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI&gt;Enable &lt;A class="lia-external-url" href="https://review.learn.microsoft.com/azure/postgresql/monitor/how-to-configure-server-logs?branch=pr-en-us-5322&amp;amp;tabs=portal-enable-capture-of-logs%2Cportal-disable-capture-of-logs%2Cportal-list-captured-logs%2Cportal-download-captured-logs#steps-to-enable-the-capture-of-postgresql-and-upgrade-logs-for-download" target="_blank" rel="noopener"&gt;Server logs for download&lt;/A&gt;.&lt;/LI&gt;
&lt;LI&gt;Download the PostgreSQL &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files.&lt;/LI&gt;
&lt;LI&gt;Run pgBadger with the matching prefix.&lt;/LI&gt;
&lt;LI&gt;Open &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;pgbadger-report.html&lt;/CODE&gt;.&lt;/LI&gt;
&lt;/OL&gt;
&lt;/DIV&gt;
&lt;H2&gt;Why use this workflow?&lt;/H2&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;With Server logs, you can download native PostgreSQL &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files directly from the Azure portal and run pgBadger locally.&lt;/P&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Older path&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Simpler path in this blog&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Diagnostic Settings → Storage account → BlobFuse → JSON extraction → pgBadger&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Server logs → Download &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;.log&lt;/CODE&gt; files → pgBadger&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;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Area&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Older Diagnostic Settings workflow&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Server logs workflow&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Export path&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Diagnostic Settings to storage account&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Download &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;.log&lt;/CODE&gt; files directly from the portal&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Format&lt;/td&gt;&lt;td style="padding: 10px;"&gt;JSON payloads need extraction&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Native PostgreSQL &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;.log&lt;/CODE&gt; files&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Extra tooling&lt;/td&gt;&lt;td style="padding: 10px;"&gt;BlobFuse and &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;jq&lt;/CODE&gt; JSON parsing&lt;/td&gt;&lt;td style="padding: 10px;"&gt;None&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Best suited for&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Centralized or multi-server logging&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Quick per-server analysis&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Outcome&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Flexible, but more setup&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Faster path to pgBadger&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;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Recommended:&lt;/STRONG&gt; Use the &lt;A class="lia-external-url" href="https://review.learn.microsoft.com/azure/postgresql/monitor/how-to-configure-server-logs?branch=pr-en-us-5322&amp;amp;tabs=portal-enable-capture-of-logs%2Cportal-disable-capture-of-logs%2Cportal-list-captured-logs%2Cportal-download-captured-logs" target="_blank" rel="noopener"&gt;Server logs&lt;/A&gt; workflow when you want a fast, low-friction way to generate a pgBadger report from one Azure Database for PostgreSQL Flexible Server.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;When should you use this workflow?&lt;/H2&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Use this workflow when...&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Use Diagnostic Settings when...&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;You need a quick report for one Flexible Server.&lt;/td&gt;&lt;td style="padding: 10px;"&gt;You centralize logs from many servers.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;You want to run pgBadger locally.&lt;/td&gt;&lt;td style="padding: 10px;"&gt;You need long-term retention or workspace-level querying.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;You want to avoid JSON extraction.&lt;/td&gt;&lt;td style="padding: 10px;"&gt;You already have automated log export pipelines.&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;H2&gt;Before you start&lt;/H2&gt;
&lt;UL style="font-size: 18px; line-height: 1.65;"&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;A machine where you can install or run pgBadger.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;A working Perl runtime.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Git Bash on Windows, so the multi-line shell commands work as shown.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Portal access to your Azure Database for PostgreSQL Flexible Server.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Permission to update server parameters and enable Server logs.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV style="border-left: 5px solid #ffb900; background-color: #fff8e5; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt; pgBadger can only analyze what PostgreSQL logs capture. To populate query timing and slow-query sections in the report, enable &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_min_duration_statement&lt;/CODE&gt; before collecting logs. Logs collected before that change will not include duration data.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Workflow overview&lt;/H2&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Task&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Type&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Rough effort&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Install or prepare pgBadger&lt;/td&gt;&lt;td style="padding: 10px;"&gt;One-time setup per analysis machine&lt;/td&gt;&lt;td style="padding: 10px;"&gt;5–10 minutes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Configure &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_line_prefix&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;One-time setup per server&lt;/td&gt;&lt;td style="padding: 10px;"&gt;2–3 minutes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Enable Server logs&lt;/td&gt;&lt;td style="padding: 10px;"&gt;One-time setup per server&lt;/td&gt;&lt;td style="padding: 10px;"&gt;2–3 minutes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Download logs and run pgBadger&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Repeatable&lt;/td&gt;&lt;td style="padding: 10px;"&gt;2–5 minutes&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;OL style="font-size: 18px; line-height: 1.65;"&gt;
&lt;LI&gt;Install or prepare pgBadger on the machine where you will analyze logs.&lt;/LI&gt;
&lt;LI&gt;Configure &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt; so pgBadger can parse each log line.&lt;/LI&gt;
&lt;LI&gt;Enable Server logs, so PostgreSQL logs are available for download.&lt;/LI&gt;
&lt;LI&gt;Download the logs and run pgBadger locally.&lt;/LI&gt;
&lt;/OL&gt;
&lt;DIV style="border-left: 5px solid #0078d4; background-color: #f3f9ff; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;💡Pro tip:&lt;/STRONG&gt; Start with a narrow log window first. Use one or two hourly log files, confirm the report looks right, and then expand the analysis window if needed.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Step 1: Install pgBadger&lt;/H2&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Before generating a report, you need pgBadger available on the machine where you plan to analyze the downloaded PostgreSQL log files. Run this on a Linux VM, WSL, or another Linux-based environment where you can install packages.&lt;/P&gt;
&lt;DIV style="border-left: 5px solid #0078d4; background-color: #f3f9ff; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; Azure Cloud Shell may work for quick testing, but package installation and build-tool availability can vary by session. For repeatable analysis, use a Linux VM, WSL, or another environment you control.&lt;/P&gt;
&lt;/DIV&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y git perl make gcc &amp;amp;&amp;amp; \
git clone https://github.com/darold/pgbadger.git &amp;amp;&amp;amp; \
cd pgbadger &amp;amp;&amp;amp; \
perl Makefile.PL &amp;amp;&amp;amp; \
make &amp;amp;&amp;amp; \
sudo make install &amp;amp;&amp;amp; \
pgbadger -V&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;What good looks like:&lt;/STRONG&gt; The install command completes successfully and &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;pgbadger -V&lt;/CODE&gt; returns the installed pgBadger version.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Step 2: Configure &lt;CODE&gt;log_line_prefix&lt;/CODE&gt;&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;This is a one-time server configuration step.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;The &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt; parameter controls the beginning of each PostgreSQL log line. pgBadger uses this prefix to extract useful fields such as timestamp, user, database, and process ID.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;In the Azure portal, open your Flexible Server and go to &lt;STRONG&gt;Server parameters&lt;/STRONG&gt;. Search for:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Parameter&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;log_line_prefix&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Set this value&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;%m user=%u db=%d pid=%p:&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Then select &lt;STRONG&gt;Save&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;In Server parameters, confirm that the custom value is saved for &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt;.&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-center" style="font-size: 18px; line-height: 1.65;"&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;EM&gt;Figure 1: Set &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt; so pgBadger can correctly parse timestamp, user, database, and process ID from each log line.&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;Prefix tokens&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Token&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Meaning&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;%m&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Timestamp with milliseconds&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;%u&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Username&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;%d&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Database name&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;%p&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Process ID&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 style="font-size: 18px; line-height: 1.65;"&gt;After this change, log lines should look like this:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Example log line&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;CODE&gt;2026-06-22 19:00:00.070 UTC user=pgadmin db=highcpu pid=3805603: LOG: statement: SELECT 1 FROM pg_extension WHERE extname='pg_stat_statements'&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;The matching pgBadger prefix for this log format is:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Matching pgBadger prefix&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;%m user=%u db=%d pid=%p:&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;You will use this same value later in the pgBadger command.&lt;/P&gt;
&lt;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;What good looks like:&lt;/STRONG&gt; The server parameter is saved, and new PostgreSQL log lines begin with timestamp, user, database, and process ID fields that match the pgBadger prefix.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Step 3: Enable Server logs for download&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;This is also a one-time setup step.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;In the Azure portal, open your Flexible Server and go to &lt;STRONG&gt;Server logs&lt;/STRONG&gt;. Enable:&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Portal setting&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE class="lia-align-justify" style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;Capture logs for download&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Set the retention period based on how long you want logs to remain available for download. For example, a 7-day retention period keeps logs available for download for 7 days.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;In Server logs, enable &lt;STRONG&gt;Capture logs for download&lt;/STRONG&gt; and choose the retention window.&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;EM&gt;Figure 2: Enable &lt;STRONG&gt;Capture logs for download&lt;/STRONG&gt; and set a retention period long enough to cover the analysis window you want to inspect.&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;What good looks like:&lt;/STRONG&gt; After Server logs are enabled, hourly PostgreSQL log files appear in the Server logs blade and can be downloaded from the Azure portal.&lt;/P&gt;
&lt;/DIV&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Once enabled, hourly log files appear in the Server logs blade. The files are named by date and hour, for example:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Example log files&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;CODE&gt;postgresql_2026_06_22_19_00_00.log
postgresql_2026_06_22_20_00_00.log&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H2&gt;Step 4: Download and organize the logs locally&lt;/H2&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;From the Server logs page, select the &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files for the time window you want to analyze and download them.&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;For example, to analyze activity between 19:00 and 21:00 UTC, download:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Example files to download&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;CODE&gt;postgresql_2026_06_22_19_00_00.log
postgresql_2026_06_22_20_00_00.log&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;On your local machine, create a folder for that analysis window. A simple convention is to use the &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;Mon-DD&lt;/CODE&gt; format.&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Folder name&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;CODE&gt;Jun-22&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Place the downloaded &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files inside that folder. Your local folder structure should look like this:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Folder structure&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;CODE&gt;pgbadger-13.1/
  pgbadger
  Jun-22/
    postgresql_2026_06_22_19_00_00.log
    postgresql_2026_06_22_20_00_00.log&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H2&gt;Step 5: Generate the pgBadger report&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Open Git Bash from the folder where pgBadger is located. For example, if pgBadger is inside the &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;pgbadger-13.1&lt;/CODE&gt; folder, open Git Bash from that folder.&lt;/P&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;#&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Action&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Command&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;1&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Set the folder&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;FOLDER=Jun-22&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;2&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Confirm files&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;ls -lh ./$FOLDER&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;3&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Run pgBadger&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Use the full command below.&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 style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;FOLDER=Jun-22

ls -lh ./$FOLDER

perl -X ./pgbadger -f stderr \
  --prefix '%m user=%u db=%d pid=%p:' \
  ./$FOLDER/*.log \
  -o ./$FOLDER/pgbadger-report.html&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H3&gt;Command breakdown&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Part of command&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Purpose&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;perl -X ./pgbadger&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Runs pgBadger and suppresses non-critical Perl warnings.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;-f stderr&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Parses PostgreSQL stderr log files.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;--prefix '%m user=%u db=%d pid=%p:'&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Matches the &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_line_prefix&lt;/CODE&gt; set on the server.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;./$FOLDER/*.log&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Analyzes every &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;.log&lt;/CODE&gt; file in the selected folder.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;-o ./$FOLDER/pgbadger-report.html&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Writes the HTML report into the same folder.&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 style="font-size: 18px; line-height: 1.65;"&gt;When the command completes successfully, you should see output like this:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Expected output&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #fff8e5; border: 1px solid #ffb900; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;CODE&gt;Parsed 12134249 bytes of 12134249 (100.00%), queries: 26684, events: 83
LOG: Ok, generating html report...&lt;/CODE&gt;&lt;/PRE&gt;
&lt;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;What good looks like:&lt;/STRONG&gt; pgBadger finishes parsing the logs and creates &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;pgbadger-report.html&lt;/CODE&gt; in the selected folder.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Step 6: Open the report&lt;/H2&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Open the generated report:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;start ./$FOLDER/pgbadger-report.html&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;The report opens in your default browser. The final report is created here:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Generated report path&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;Jun-22/pgbadger-report.html&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H2&gt;What the report can show&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;The pgBadger report gives you a quick view into the workload shape for the selected log window. For example, in a sample run across two hourly log files, pgBadger summarized:&lt;/P&gt;
&lt;UL class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;
&lt;LI&gt;Total number of queries.&lt;/LI&gt;
&lt;LI&gt;Number of unique normalized queries.&lt;/LI&gt;
&lt;LI&gt;Query traffic over time.&lt;/LI&gt;
&lt;LI&gt;Events such as errors and fatal messages.&lt;/LI&gt;
&lt;LI&gt;Session and connection patterns.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Once the report opens, start with &lt;STRONG&gt;Global Stats&lt;/STRONG&gt; to confirm the time range, total queries, normalized queries, and query peak.&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;EM&gt;Figure 3: Start with Global Stats to validate the selected time range, total query count, normalized query count, and query peak.&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;Query volume and normalized queries&lt;/H3&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;Many raw queries can often reduce to a smaller number of normalized query patterns. This helps identify whether the workload is spread across many different query shapes or dominated by a smaller set of repeated statements.&lt;/P&gt;
&lt;DIV style="border-left: 5px solid #0078d4; background-color: #f3f9ff; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Example:&lt;/STRONG&gt; In this sample run, &lt;STRONG&gt;26,684 queries&lt;/STRONG&gt; reduced to &lt;STRONG&gt;59 normalized query shapes&lt;/STRONG&gt;. That suggests the workload is mostly a small set of repeated statements, which can help focus tuning effort.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H3&gt;Traffic patterns&lt;/H3&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;The SQL Traffic section helps identify spikes, quiet periods, and workload changes over time.&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;EM&gt;Figure 4: Use SQL Traffic to identify query spikes, quiet periods, and workload changes during the selected log window.&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;SPAN class="lia-text-color-15"&gt;&lt;EM&gt;Figure 5: Review the query breakdown to compare read vs. write volume and query-type distribution for the selected Server logs window.&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;For example, if the report shows a steady baseline followed by a sharp spike, that spike can be correlated with application activity, batch jobs, synthetic tests, or operational events during the same time window.&lt;/P&gt;
&lt;H3&gt;Query duration&lt;/H3&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;If query duration shows &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;0 ms&lt;/CODE&gt; or the slow query sections are empty, it usually means duration logging was not enabled when the logs were collected.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;In that case, pgBadger can still show query counts and events, but it cannot calculate the slowest queries, total execution time, average duration, or maximum duration.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;To unlock those timing sections, enable &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_min_duration_statement&lt;/CODE&gt;, collect fresh logs, and rerun pgBadger.&lt;/P&gt;
&lt;H2&gt;What pgBadger cannot infer from missing logs&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;pgBadger reports are only as complete as the log data you provide. If PostgreSQL did not log duration, lock waits, temporary files, or autovacuum activity during the selected time window, pgBadger cannot reconstruct those details later.&lt;/P&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;To analyze...&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Enable before collecting logs&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Slow queries&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_min_duration_statement&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Lock waits&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_lock_waits&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Temporary files&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_temp_files&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Autovacuum activity&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_autovacuum_min_duration&lt;/CODE&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;H2&gt;Repeatable copy/paste block&lt;/H2&gt;
&lt;DIV style="border: 2px solid #107c10; border-radius: 8px; padding: 18px 22px; margin: 28px 0; background-color: #f3fbf3;"&gt;
&lt;P style="font-size: 18px; line-height: 1.65; margin-top: 0;"&gt;&lt;STRONG&gt;Reusable command block&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65; margin-bottom: 0;"&gt;Change only &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;FOLDER&lt;/CODE&gt; for each new analysis window.&lt;/P&gt;
&lt;/DIV&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;FOLDER=Jun-22

ls -lh ./$FOLDER

perl -X ./pgbadger -f stderr \
  --prefix '%m user=%u db=%d pid=%p:' \
  ./$FOLDER/*.log \
  -o ./$FOLDER/pgbadger-report.html

start ./$FOLDER/pgbadger-report.html&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;For another date, change only this line:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Update this value&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;FOLDER=Jun-22&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Examples:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Example folder values&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;FOLDER=Jun-23
FOLDER=Jul-01
FOLDER=Aug-15&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;H2&gt;Optional: Improve report quality&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;pgBadger can only analyze the information captured in PostgreSQL logs.&lt;/P&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;The default logs may be enough for query frequency, connection activity, and errors. For deeper performance troubleshooting, consider enabling additional logging parameters based on your scenario.&lt;/P&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Scenario&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Parameter&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Suggested value&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Notes&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Slow query analysis&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_min_duration_statement&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;1000&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Logs statements slower than 1 second.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Short controlled test&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_min_duration_statement&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;0&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Logs every statement. Use carefully.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Lock troubleshooting&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_lock_waits&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;on&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Helps identify lock waits.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Temporary file analysis&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_temp_files&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;0&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Logs all temporary files.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Autovacuum visibility&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_autovacuum_min_duration&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;&lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;0&lt;/CODE&gt;&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Useful during focused analysis.&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 style="font-size: 18px; line-height: 1.65;"&gt;Useful parameters include:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Recommended logging parameters&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;log_lock_waits = on
log_temp_files = 0
log_autovacuum_min_duration = 0&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;To capture query durations, configure:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Duration logging&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;log_min_duration_statement = 1000&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;This logs statements that run longer than 1000 milliseconds.&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;For short test runs, you can temporarily use:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Short test run only&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;log_min_duration_statement = 0&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;DIV style="border-left: 5px solid #ffb900; background-color: #fff8e5; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Caution:&lt;/STRONG&gt; Use &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_min_duration_statement = 0&lt;/CODE&gt; carefully on busy production servers. It logs every statement and can generate a large volume of logs.&lt;/P&gt;
&lt;/DIV&gt;
&lt;DIV style="border-left: 5px solid #0078d4; background-color: #f3f9ff; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Duration matters:&lt;/STRONG&gt; If duration logging is not enabled, pgBadger can still show query counts and events, but slowest-query, total duration, average duration, and maximum duration sections will be limited or empty.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;Common mistakes and quick fixes&lt;/H2&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;tbody&gt;&lt;tr&gt;&lt;th style="padding: 10px;"&gt;Symptom&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Likely cause&lt;/th&gt;&lt;th style="padding: 10px;"&gt;Fix&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;Report is empty&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Prefix mismatch&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Match &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;--prefix&lt;/CODE&gt; with &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_line_prefix&lt;/CODE&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;No duration data&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Duration logging was not enabled&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Set &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;log_min_duration_statement&lt;/CODE&gt; before collecting logs.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;No files visible&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Server logs disabled or retention expired&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Enable capture and check retention.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="padding: 10px;"&gt;pgBadger command fails&lt;/td&gt;&lt;td style="padding: 10px;"&gt;pgBadger is not in the current folder or path&lt;/td&gt;&lt;td style="padding: 10px;"&gt;Run &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 15px;"&gt;pgbadger -V&lt;/CODE&gt; to confirm installation.&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;H2&gt;Common troubleshooting FAQs&lt;/H2&gt;
&lt;DIV style="border: 1px solid #d0d7de; border-radius: 6px; padding: 16px 20px; margin: 18px 0;"&gt;
&lt;H3&gt;1. Report is created but empty&lt;/H3&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;This usually means the pgBadger prefix did not match the actual log format.&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Check the first few lines:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;head -5 ./$FOLDER/*.log&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Make sure the pgBadger &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;--prefix&lt;/CODE&gt; matches the server’s &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt;.&lt;/P&gt;
&lt;/DIV&gt;
&lt;DIV style="border: 1px solid #d0d7de; border-radius: 6px; padding: 16px 20px; margin: 18px 0;"&gt;
&lt;H3&gt;2. Report shows queries but no duration&lt;/H3&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;PostgreSQL logged statements but did not log durations.&lt;/P&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Enable one of the following, collect fresh logs, and rerun pgBadger:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Parameter options&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;log_min_duration_statement = 1000

# or temporarily for testing
log_min_duration_statement = 0&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;DIV style="border: 1px solid #d0d7de; border-radius: 6px; padding: 16px 20px; margin: 18px 0;"&gt;
&lt;H3&gt;3. No &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files are visible&lt;/H3&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Confirm that Server logs are enabled:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Portal setting&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;Capture logs for download&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Also check the retention period. If the retention period has expired, older logs may no longer be available for download.&lt;/P&gt;
&lt;/DIV&gt;
&lt;DIV style="border: 1px solid #d0d7de; border-radius: 6px; padding: 16px 20px; margin: 18px 0;"&gt;
&lt;H3&gt;4. pgBadger command fails&lt;/H3&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;Confirm that pgBadger is available in the current folder or installed in your path.&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;pgbadger -V&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P style="font-size: 18px; line-height: 1.65;"&gt;If you are running pgBadger from the local folder, use:&lt;/P&gt;
&lt;P style="font-size: 16px; line-height: 1.4; margin-bottom: 6px;"&gt;&lt;STRONG&gt;Copy and run&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; font-size: 15px; line-height: 1.55; overflow-x: auto; white-space: pre;"&gt;&lt;SPAN class="lia-text-color-13"&gt;&lt;CODE&gt;perl -X ./pgbadger&lt;/CODE&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;H2&gt;Summary&lt;/H2&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;For customers already using Azure Database for PostgreSQL Flexible Server logs, the pgBadger workflow is straightforward:&lt;/P&gt;
&lt;OL style="font-size: 18px; line-height: 1.65;"&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Install pgBadger.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Configure &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;log_line_prefix&lt;/CODE&gt;.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Enable Server logs for download.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Download the &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Place them in a local date-based folder.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Run pgBadger with the matching prefix.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV class="lia-align-justify"&gt;Open &lt;CODE style="background-color: #f6f8fa; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;pgbadger-report.html&lt;/CODE&gt;.&lt;/DIV&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;DIV style="border-left: 5px solid #107c10; background-color: #f3fbf3; padding: 16px 20px; margin: 24px 0;"&gt;
&lt;P class="lia-align-justify" style="font-size: 18px; line-height: 1.65;"&gt;&lt;STRONG&gt;Bottom line:&lt;/STRONG&gt; Server logs give you the shortest path from Azure Database for PostgreSQL Flexible Server logs to a pgBadger report. Download the native &lt;CODE style="background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 4px; padding: 2px 5px; font-size: 16px;"&gt;.log&lt;/CODE&gt; files, run pgBadger with the matching prefix, and open the generated HTML report.&lt;/P&gt;
&lt;/DIV&gt;
&lt;H2&gt;References&lt;/H2&gt;
&lt;UL style="font-size: 18px; line-height: 1.65;"&gt;
&lt;LI&gt;&lt;A href="https://github.com/darold/pgbadger" target="_blank" rel="noopener"&gt;pgBadger - source and documentation GitHub&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://pgbadger.darold.net/" target="_blank" rel="noopener"&gt;pgBadger - project site&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/how-to-server-logs-portal" target="_blank" rel="noopener"&gt;Azure - Download server logs from the portal Flexible Server&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-logging" target="_blank" rel="noopener"&gt;Azure - Logging concepts Flexible Server&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/how-to-configure-server-parameters-using-portal" target="_blank" rel="noopener"&gt;Azure - Configure server parameters via the portal&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-LINE-PREFIX" target="_blank" rel="noopener"&gt;PostgreSQL - log_line_prefix and logging parameters&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Thu, 30 Jul 2026 18:18:19 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/log-insights-in-minutes-a-simpler-pgbadger-workflow/ba-p/4531932</guid>
      <dc:creator>varun-dhawan</dc:creator>
      <dc:date>2026-07-30T18:18:19Z</dc:date>
    </item>
    <item>
      <title>Take control of your PostgreSQL maintenance</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/take-control-of-your-postgresql-maintenance/ba-p/4529918</link>
      <description>&lt;P&gt;Maintenance is an important part of keeping Azure Database for PostgreSQL flexible server secure, reliable, and up to date. It helps deliver platform updates, security patches, operating system updates, and PostgreSQL engine updates that keep servers running smoothly.&lt;/P&gt;
&lt;P&gt;But we also know that timing matters.&lt;/P&gt;
&lt;P&gt;For teams running production workloads, a maintenance event during peak traffic, a migration, financial close, a major release, or a seasonal business event can create unnecessary stress. Even a brief restart or connection interruption can affect applications, customers, and business operations.&lt;/P&gt;
&lt;P&gt;That’s why we’re excited to share that new self-service maintenance controls for Azure Database for PostgreSQL flexible server are now generally available in the Azure portal.&lt;/P&gt;
&lt;P&gt;With these new capabilities, customers can see upcoming maintenance, reschedule eligible planned maintenance to a preferred date and time, apply maintenance when they’re ready, and review maintenance history after events complete.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why we built this&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Azure Database for PostgreSQL flexible server already offers maintenance scheduling options through Custom Maintenance Windows (CMW) and System-managed Maintenance Windows (SMW). These options give you a starting point for controlling when maintenance updates are applied.&lt;/P&gt;
&lt;P&gt;But customers told us they needed more flexibility after a specific maintenance event was scheduled.&lt;/P&gt;
&lt;P&gt;Sometimes the original maintenance time still lands during a critical business period. In the past, customers who needed to defer maintenance often had to open a support request. That added time, extra coordination, and operational overhead for something many teams wanted to handle directly.&lt;/P&gt;
&lt;P&gt;With this release, you now have more control from the Azure portal.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What’s new&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The new maintenance experience introduces four key capabilities.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;1. View upcoming maintenance&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You can now view upcoming maintenance before it begins. This gives teams a clearer view of when maintenance is scheduled, what type of maintenance is planned, and whether the event can be rescheduled.&lt;/P&gt;
&lt;P&gt;To view upcoming maintenance:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the Azure portal, go to your Azure Database for PostgreSQL flexible server.&lt;/LI&gt;
&lt;LI&gt;On the server &lt;STRONG&gt;Overview&lt;/STRONG&gt; page, review the &lt;STRONG&gt;Next Maintenance&lt;/STRONG&gt; field.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img&gt;Figure 1: View upcoming maintenance&lt;/img&gt;
&lt;P&gt;If upcoming maintenance is available, the &lt;STRONG&gt;Next Maintenance&lt;/STRONG&gt; field displays the scheduled maintenance time.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Select the &lt;STRONG&gt;Next Maintenance&lt;/STRONG&gt; value to open the &lt;STRONG&gt;Maintenance&lt;/STRONG&gt; page.&lt;/LI&gt;
&lt;LI&gt;On the &lt;STRONG&gt;Maintenance&lt;/STRONG&gt; page, review the &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section shows upcoming maintenance events that apply to your server, including the scheduled time, status, maintenance type, and available actions.&lt;/P&gt;
&lt;P&gt;Instead of reacting at the last minute, database administrators and application teams can plan ahead with more confidence.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2. Reschedule maintenance to a preferred date and time&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;For eligible maintenance events, you can reschedule planned maintenance to a preferred date and time up to two weeks later.&lt;/P&gt;
&lt;P&gt;To reschedule maintenance:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the Azure portal, go to your Azure Database for PostgreSQL flexible server.&lt;/LI&gt;
&lt;LI&gt;In the left menu, under &lt;STRONG&gt;Settings&lt;/STRONG&gt;, select &lt;STRONG&gt;Maintenance&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section, review the upcoming maintenance event.&lt;/LI&gt;
&lt;LI&gt;If the event is eligible, select &lt;STRONG&gt;Reschedule&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Choose an eligible future date and time.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img&gt;Figure 2: Reschedule maintenance to a preferred date/time&lt;/img&gt;
&lt;P&gt;Only dates and times that meet the service rules and your maintenance policy are available for selection. &lt;STRONG&gt;Note:&lt;/STRONG&gt; Reschedule maintenance is not supported for servers on SMW schedule.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Reschedule&lt;/STRONG&gt; to confirm the new maintenance time.&lt;/LI&gt;
&lt;LI&gt;After confirmation, review the &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section to verify that the new start time is displayed.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The portal shows a confirmation after the maintenance event is successfully rescheduled.&lt;/P&gt;
&lt;P&gt;This is useful when the original maintenance time overlaps with a period where even a short interruption could be disruptive, such as peak application traffic, end-of-quarter processing, planned migrations, major releases, holiday events, or internal change freeze periods.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;3. Apply maintenance on demand&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;You can also apply eligible maintenance immediately when the timing works better for you.&lt;/P&gt;
&lt;P&gt;To apply maintenance on demand:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the Azure portal, go to your Azure Database for PostgreSQL flexible server.&lt;/LI&gt;
&lt;LI&gt;In the left menu, under &lt;STRONG&gt;Settings&lt;/STRONG&gt;, select &lt;STRONG&gt;Maintenance&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;In the &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section, review the upcoming maintenance event.&lt;/LI&gt;
&lt;LI&gt;If the event is eligible, select &lt;STRONG&gt;Reschedule&lt;/STRONG&gt;, followed by &lt;STRONG&gt;Apply now&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Yes - Apply Maintenance Now&lt;/STRONG&gt; to start maintenance.&lt;/LI&gt;
&lt;LI&gt;Monitor the &lt;STRONG&gt;Maintenance status&lt;/STRONG&gt; section.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img&gt;Figure 3: Apply maintenance on demand&lt;/img&gt;
&lt;P&gt;The maintenance event status updates as the workflow progresses. When maintenance completes, the status changes to &lt;STRONG&gt;Complete&lt;/STRONG&gt; and the event moves to the &lt;STRONG&gt;Maintenance history&lt;/STRONG&gt; section.&lt;/P&gt;
&lt;P&gt;For example, a team might decide to apply maintenance during a quieter period, after validating application readiness, or before a planned release. This gives customers a way to complete maintenance on their own timeline instead of waiting for the scheduled window.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;4. View maintenance history&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;After maintenance completes, you can review maintenance history for your server. This helps teams confirm when maintenance occurred and supports operational reviews, troubleshooting, and audit-related workflows.&lt;/P&gt;
&lt;P&gt;To view maintenance history:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;In the Azure portal, go to your Azure Database for PostgreSQL flexible server.&lt;/LI&gt;
&lt;LI&gt;In the left menu, under &lt;STRONG&gt;Settings&lt;/STRONG&gt;, select &lt;STRONG&gt;Maintenance&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;On the &lt;STRONG&gt;Maintenance&lt;/STRONG&gt; page, review the &lt;STRONG&gt;Maintenance history&lt;/STRONG&gt; section.&lt;/LI&gt;
&lt;LI&gt;Select a maintenance event &lt;STRONG&gt;Tracking ID&lt;/STRONG&gt; to view more details, such as the maintenance type, start time, and final status.&lt;/LI&gt;
&lt;LI&gt;Select &lt;STRONG&gt;Export to CSV&lt;/STRONG&gt; to download maintenance history.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img&gt;Figure 4: View maintenance history&lt;/img&gt;
&lt;P&gt;If no past maintenance events are available for the server, the maintenance history section might be empty.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Built for real production schedules&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Production environments rarely operate on a simple schedule. Maintenance often needs to be coordinated with application releases, internal change windows, customer commitments, and business calendars.&lt;/P&gt;
&lt;P&gt;These new controls are designed to make that coordination easier. By making maintenance more visible and actionable, Azure Database for PostgreSQL flexible server helps you plan with less uncertainty and more control.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Frequently asked questions&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Which maintenance events can I reschedule?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Only eligible planned maintenance events on Custom Maintenance Schedule (CMW) can be rescheduled. Some maintenance, such as time-sensitive security or compliance updates, might not be eligible for rescheduling.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;How far can I reschedule maintenance?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Eligible maintenance can be moved to a preferred date and time up to two weeks from the originally scheduled maintenance date.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Can I reschedule maintenance more than once?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Yes. You can update the selected maintenance date and time again, as long as the maintenance event remains eligible and the new time is within the allowed two-week rescheduling window.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Why can’t I reschedule maintenance right before it starts?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Rescheduling is unavailable shortly before the originally scheduled maintenance time. This lock-in period helps ensure the maintenance workflow can begin reliably.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Can I apply maintenance before its scheduled time?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Yes. When an upcoming maintenance event is eligible, you can select &lt;STRONG&gt;Apply now&lt;/STRONG&gt; in the Azure portal to begin maintenance immediately.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Will applying maintenance on demand restart my server?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;It might. Some maintenance operations require a server restart, which can result in a brief interruption or connection churn. Apply maintenance when your application can tolerate that impact.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Where can I use these maintenance controls?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;The new controls are available in the Azure portal. Open your Azure Database for PostgreSQL flexible server and go to &lt;STRONG&gt;Settings&lt;/STRONG&gt; &amp;gt; &lt;STRONG&gt;Maintenance&lt;/STRONG&gt;.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Can I use Azure CLI or REST API?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Azure CLI and REST API support are coming soon. At general availability, customers can use the Azure portal to view upcoming maintenance, reschedule eligible events, apply maintenance on demand, and view maintenance history.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Can I view maintenance that has already completed?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Yes. The &lt;STRONG&gt;Maintenance history&lt;/STRONG&gt; section in the Azure portal shows completed maintenance events. You can select an event to review its details and export the history to CSV when needed.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;What should I do if I need to defer maintenance for more than two weeks?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;Create an Azure support request. The self-service experience supports rescheduling eligible maintenance for up to two weeks, but support can help assess requests that require a longer deferral.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Getting started&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To get started, open your Azure Database for PostgreSQL flexible server in the Azure portal and navigate to &lt;STRONG&gt;Settings&lt;/STRONG&gt; &amp;gt; &lt;STRONG&gt;Maintenance&lt;/STRONG&gt;. These new self-service maintenance controls are now generally available in the Azure portal for Azure Database for PostgreSQL flexible server. CLI and API support are coming soon.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Learn More&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;To learn more about rescheduling maintenance and related Azure PostgreSQL capabilities, see:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/configure-maintain/concepts-maintenance" target="_blank" rel="noopener"&gt;Planned maintenance for Azure Database for PostgreSQL&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/configure-maintain/how-to-configure-scheduled-maintenance?tabs=portal-maintenance-settings#steps-to-reschedule-maintenance-to-a-future-date" target="_blank" rel="noopener"&gt;Reschedule planned maintenance to a future date&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/configure-maintain/concepts-maintenance#consolidated-maintenance-notifications" target="_blank" rel="noopener"&gt;Consolidated planned maintenance notifications&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jun 2026 22:21:20 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/take-control-of-your-postgresql-maintenance/ba-p/4529918</guid>
      <dc:creator>jasomaning</dc:creator>
      <dc:date>2026-06-26T22:21:20Z</dc:date>
    </item>
    <item>
      <title>Build a Knowledge Graph in Azure HorizonDB with AI Functions and Apache AGE</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/build-a-knowledge-graph-in-azure-horizondb-with-ai-functions-and/ba-p/4523394</link>
      <description>&lt;P&gt;Knowledge graphs appear in every AI architecture diagram, every conference keynote and every AI strategy deck. Yet the most common question we hear from customers and engineers alike is: &lt;EM&gt;"&lt;/EM&gt;What does a knowledge graph actually do for me?"&lt;/P&gt;
&lt;P&gt;That is a fair question, and one worth answering clearly, because most teams already have a knowledge graph problem and do not realize it.&lt;/P&gt;
&lt;H4&gt;The connections your relational tables cannot surface&lt;/H4&gt;
&lt;P&gt;Picture this: five incident tickets land over a week. One says the auth service returned 503s after an API gateway update, which broke checkout. Another says the payment service lost connectivity to fraud detection through a DNS failure. A third says auth got rate-limited by that same API gateway after a config change.&lt;/P&gt;
&lt;P&gt;Each ticket makes sense on its own. But no one in your postmortem can answer: "What upstream services most commonly trigger failures that reach checkout?" That question requires tracing relationships across tickets, teams, services, and root causes. Your relational tables store the facts. They do not store the connections between them. That is a knowledge graph problem.&lt;/P&gt;
&lt;H4&gt;What becomes queryable once you have a knowledge graph&lt;/H4&gt;
&lt;P&gt;Once you build a graph from those tickets, every node is an entity (a service, a team, an incident) and every edge is a relationship (CAUSED_FAILURE_IN, OPERATES_ON, INVOLVES). The graph does not just store data differently. It makes&lt;STRONG&gt; &lt;/STRONG&gt;a new class of questions answerable:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;What is the most common upstream cause of checkout failures?&lt;/LI&gt;
&lt;LI&gt;Which team resolves the most cross-service incidents?&lt;/LI&gt;
&lt;LI&gt;Show me every cascading failure chain that touched the payment service in the last 90 days.&lt;/LI&gt;
&lt;LI&gt;What is the timeline of incidents involving the same shared service?&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Each of these questions can be answered with a single Cypher query, without nested subqueries, recursive CTEs, or manually correlating data across spreadsheets.&lt;/P&gt;
&lt;H4&gt;Why graph-augmented RAG needs a knowledge graph first&lt;/H4&gt;
&lt;P&gt;Traditional RAG retrieves chunks of text by vector similarity. It works well when the answer lives in a single document. It falls apart when the answer requires&lt;STRONG&gt; &lt;/STRONG&gt;connecting facts across multiple documents. Ask "does this contract conflict with existing obligations?" and vector search returns a relevant clause. But it cannot follow links across regions, obligation types, and counterparties to prove a real conflict.&lt;/P&gt;
&lt;P&gt;Graph-augmented RAG combines vector search, semantic ranking, and graph traversal into one retrieval pipeline. The graph provides the structural context that vector search alone cannot: the actual chain of cause and effect, not just the five most similar paragraphs.&lt;/P&gt;
&lt;P&gt;But here is the catch most people miss: you cannot run graph-augmented RAG without a knowledge graph. And building the graph has always been the hard part. That is exactly what the new tutorial solves.&lt;/P&gt;
&lt;H4&gt;Building a knowledge graph in five steps inside Azure HorizonDB&lt;/H4&gt;
&lt;P&gt;We published a &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/build-knowledge-graph" target="_blank"&gt;hands-on tutorial&lt;/A&gt; on Microsoft Learn that takes you from raw incident tickets to a connected, queryable knowledge graph. No external NLP pipelines. No separate graph database. Just SQL.&lt;/P&gt;
&lt;P&gt;Here is the pipeline:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Extract entities and relationships&lt;/STRONG&gt; from unstructured text with azure_ai.extract(). The LLM parses services, teams, root causes, and relationship triples in one SQL call.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deduplicate entities&lt;/STRONG&gt; with azure_ai.generate() using structured JSON output. "API gateway," "api-gateway," and "the gateway service" collapse into one canonical node.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Load into an Apache AGE graph&lt;/STRONG&gt; using Cypher MERGE in PL/pgSQL loops. The tutorial builds service nodes, team nodes, incident hub nodes, all six relationship types, and a timeline chain linking incidents chronologically.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Query with Cypher traversals.&lt;/STRONG&gt; Variable-length path patterns like *1..3 trace cascading failure chains up to three hops deep.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Visualize results&lt;/STRONG&gt; in the PostgreSQL extension for VS Code, which renders Cypher output as an interactive node-edge graph.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;The tutorial walks through every SQL statement, explains the tricky parts (like why EXECUTE format() is needed for parameterized Cypher, and how CROSS JOIN LATERAL expands team-service pairs correctly), and shows the exact output at each step.&lt;/P&gt;
&lt;H4&gt;The same pipeline applied to any domain&lt;/H4&gt;
&lt;P&gt;The tutorial uses incident tickets to keep things concrete. But the pipeline applies to any domain:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 1008px; height: 989.334px; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr style="height: 38.6667px;"&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Domain&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Key Entities&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Question It Answers&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Contract intelligence&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Parties, clauses, obligations&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Does this new vendor contract conflict with existing obligations?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;E-commerce product catalog&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Products, categories, customers, orders&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;What do customers who bought X typically buy next?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 94.6667px;"&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Fraud detection&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Accounts, transactions, devices, IP addresses&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Which accounts are connected through shared devices and circular transfers?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Healthcare clinical data&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Patients, medications, conditions, providers&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Does this new prescription conflict with existing medications?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 94.6667px;"&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Codebase dependency analysis&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Tables, functions, views, triggers&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;If I alter this table, which downstream views and functions break?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Supply chain&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Suppliers, components, facilities&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Which tier-2 suppliers are single points of failure?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Research knowledge base&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Papers, authors, concepts&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;What evidence chain supports this treatment for condition X?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Data lineage and ETL&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Sources, transformations, dashboards&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;If this source schema changes, which dashboards break?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 94.6667px;"&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Identity and access management&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;Users, groups, roles, resources&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 94.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Which users have transitive access to production through nested groups?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Regulatory compliance&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Regulations, controls, systems&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;If this regulation changes, which controls need updating?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Customer 360&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Customers, interactions, campaigns&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;What sequence of touchpoints leads to churn for enterprise accounts?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Insurance claims&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Claimants, policies, events, providers&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;Which claims share overlapping parties or event timelines?&lt;/EM&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;M&amp;amp;A due diligence&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Companies, IP assets, contracts, liabilities&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;EM&gt;What hidden liabilities are linked to this acquisition target?&lt;/EM&gt;&lt;/P&gt;
&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;In every case, the shape is the same: azure_ai.extract() discovers the entities, azure_ai.generate() deduplicates them, and AGE stores and traverses the graph.&lt;/P&gt;
&lt;H4&gt;Get started&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Tutorial: &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/build-knowledge-graph" target="_blank"&gt;Build a knowledge graph from unstructured text using AI Functions and Apache AGE&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;Knowledge graph enhanced search:&amp;nbsp;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/graph-rag" target="_blank"&gt;Graph-augmented RAG patterns for Azure HorizonDB&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Solution accelerators:&lt;STRONG&gt; &lt;/STRONG&gt;&lt;A class="lia-external-url" href="https://github.com/Azure-Samples/graphrag-legalcases-postgres" target="_blank"&gt;GraphRAG Legal Research Copilot&lt;/A&gt;, &lt;A class="lia-external-url" href="https://github.com/Azure-Samples/postgreSQL-graphRAG-docker" target="_blank"&gt;GraphRAG with Docker and AI Agents&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;We would love to hear what you build. Share your feedback on the &lt;A class="lia-external-url" href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Faka.ms%2Fpostgres-hub-developer-forum&amp;amp;data=05%7C02%7CAditi.Gupta%40microsoft.com%7C5fb0d21296f449b0241a08debd5ec488%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639156412747925051%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=pRV4mHamkdLHcnw2AL1g%2B%2F56CUioLbHCta0E2AekBlY%3D&amp;amp;reserved=0" target="_blank"&gt;PostgreSQL Hub developer forum&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Thank you!&lt;/P&gt;</description>
      <pubDate>Thu, 11 Jun 2026 17:42:46 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/build-a-knowledge-graph-in-azure-horizondb-with-ai-functions-and/ba-p/4523394</guid>
      <dc:creator>Aditi_Gupta</dc:creator>
      <dc:date>2026-06-11T17:42:46Z</dc:date>
    </item>
    <item>
      <title>Last Call: Join Live the PostgreSQL Community at POSETTE: An Event for Postgres 2026 (T‑1 week)</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/last-call-join-live-the-postgresql-community-at-posette-an-event/ba-p/4527424</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;In just one week, the PostgreSQL community gathers again for one of the most anticipated global moments of the year:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;POSETTE: An Event for Postgres 2026&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. From June 16–18, this free and fully virtual event brings together PostgreSQL contributors, engineers, architects, and practitioners across 4 livestreams, 44 talks, and 50 speakers.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;But you might be wondering, why should I participate in POSETTE during the livestreams? Why join it live?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Explore the schedule and choose your livestreams on the official site:&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&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;Join POSETTE: An Event for Postgres 2026&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;Why joining live makes all the difference&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Yes, every talk will be available afterward. But the real value of POSETTE: An Event for Postgres 2026 happens while it is unfolding live.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Be part of the virtual hallway track&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Participating live gives you access to the #posetteconf &lt;A class="lia-external-url" href="https://discord.com/channels/723347736853741589/1197937060737187951" target="_blank" rel="noopener"&gt;Discord channel,&lt;/A&gt; where attendees and speakers interact in real time, asking questions, sharing perspectives, and comparing approaches.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&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 is where conversations extend beyond the talks and where ideas are challenged and refined collectively.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Learn and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;validate&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; your thinking in real time&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;POSETTE is not just about listening. It is about sharpening how you think about PostgreSQL:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Are you partitioning effectively?&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Are you approaching replication with the right mental model?&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Are your performance strategies aligned with how PostgreSQL actually behaves?&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Joining live means you can test those ideas immediately with people who build and run PostgreSQL systems at scale.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Connect with practitioners solving the same problems&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A recurring insight from POSETTE participants is how often they discover others facing the same challenges, whether around scaling, performance, or operability.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&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 shared experience often leads to the most valuable takeaways: not just what works, but why.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;What makes this year’s speakers worth your time&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;POSETTE: An Event for Postgres 2026 brings together a diverse set of voices:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;PostgreSQL core contributors&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Engineers and architects working on production systems&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Specialists in performance, replication, and security&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Developers shaping how PostgreSQL is used in modern applications&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Azure Database for PostgreSQL and Azure HorizonDB engineers and experts&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;These are practitioners who have built, debugged, and scaled real systems, and who are ready to share what they learned.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;Learn directly from the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;POSETTE speakers who are&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 2"&gt;shaping PostgreSQL&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Bruce Momjian&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; understanding PostgreSQL from the inside out&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/bruce-momjian/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Bruce Momjian’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Bruce Momjian, a co-founder and core member of the PostgreSQL Global Development Group, has spent decades helping people understand how PostgreSQL really works. His session on the write-ahead log (WAL) reflects that same focus: taking something fundamental but often misunderstood and making it approachable.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If you want to move beyond “using” PostgreSQL and start truly understanding its internals, how durability, recovery, and replication actually function, this is a rare opportunity to learn directly from someone who has helped build the system.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Chris Ellis&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; making PostgreSQL practical for developers&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/chris-ellis/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Chris Ellis’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Chris Ellis focuses on how to turn PostgreSQL’s extensive feature set into practical design choices. His session on design patterns highlights a reality many developers face: PostgreSQL offers powerful primitives, but knowing how to combine them effectively is what makes the difference.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;His work consistently centers on simplifying application architecture by using the database well, rather than pushing complexity into application code.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Chun Lin Goh&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; understanding performance in real environments&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/chun-lin-goh/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Chun Lin Goh’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Chun Lin Goh brings a cloud architecture and observability perspective to PostgreSQL performance. His session on performance degradation in burstable environments shows how the database behaves under real-world infrastructure constraints.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&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 is especially relevant if you run PostgreSQL in cloud environments, where system behaviour, not just query design,can have a major impact.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Derk van Veen&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; lessons from real-world partitioning&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/derk-van-veen/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Derk van Veen’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Derk van Veen’s work is grounded in hands-on experience operating PostgreSQL at scale. His partitioning session focuses not just on how to do things right, but also on what can go wrong,and why.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Partitioning decisions often look simple early on but have long-term consequences. Learning from real mistakes and trade-offs is what makes these sessions so valuable.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Hari Kiran&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; thinking deeply about replication&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/hari-kiran/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Hari Kiran’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Hari Kiran’s session explores logical decoding and replication, two foundational aspects of how PostgreSQL systems scale and integrate with other systems.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If your work involves distributed systems, data pipelines, or event-driven architectures, understanding these mechanics is essential.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Jimmy Angelakos&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;uncovering subtle behavior&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/jimmy-angelakos/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Jimmy Angelakos’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Jimmy Angelakos focuses on practical, often overlooked aspects of PostgreSQL behavior. His session on NOTIFY highlights how features that seem simple on the surface can introduce complexity in real systems.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;These are exactly the kinds of nuances that can save hours or days of debugging in production.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Sakshi Nasha&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;securing PostgreSQL for production&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/sakshi-nasha/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Sakshi Nasha’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Sakshi Nasha’s work emphasizes security and production readiness. Her session on securing PostgreSQL reflects a broader shift: as PostgreSQL becomes central to more systems, security needs to be built in from the start.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Her perspective is especially relevant for teams moving from development environments into production systems.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Taiob Ali&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;connecting community and real-world usage&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/taiob-ali/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Taiob Ali’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Taiob Ali brings a strong community-driven perspective to PostgreSQL, shaped by experience as both a practitioner and an advocate.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Sessions like his often help bridge the gap between concepts and how PostgreSQL is actually used across different teams and environments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Xuneng Zhou&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; an independent perspective from the ecosystem&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:246,&amp;quot;335559739&amp;quot;:246,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://posetteconf.com/speakers/xuneng-zhou/#interview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Read Xuneng Zhou’s interview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;As an independent PostgreSQL hacker, Xuneng Zhou represents a perspective deeply rooted in the open source ecosystem itself.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&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 viewpoint often brings a focus on fundamentals, experimentation, and how PostgreSQL evolves over time, valuable context for anyone who wants to understand not just where PostgreSQL is today, but where it is heading.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;This is more than a conference&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;POSETTE: An Event for Postgres 2026 is a shared moment for the PostgreSQL community.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;It is an opportunity to:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Learn from practitioners and contributors&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Challenge assumptions and refine your thinking&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Understand where PostgreSQL is heading next&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;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Stepping into the livestream is not just about attending talks, it is about participating in that moment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;Your next step: join live&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If PostgreSQL is part of your work, or becoming central to it, the best way to experience POSETTE: An Event for Postgres 2026 is live.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Pick the sessions that matter to you.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Add the livestreams to your calendar.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Join the discussion as it happens.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Start here:&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;A href="https://posetteconf.com/2026/schedule/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Check out the POSETTE schedule to figure out which livestreams &amp;amp; which talks are for you.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For any other answer you may still have, don't forget to take a look at the&lt;/SPAN&gt; &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/ultimate-guide-to-posette-an-event-for-postgres-2026-edition/4520246" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Ultimate Guide to POSETTE: An Event &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;f&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;or &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Postgres 2026&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;See you live at POSETTE&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:261,&amp;quot;335559739&amp;quot;:261,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Whether you are exploring PostgreSQL internals, building modern applications, or scaling production systems, POSETTE: An Event for Postgres 2026 is where those conversations come together.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;See you at POSETTE on 16-18 June 2026.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:210,&amp;quot;335559739&amp;quot;:210,&amp;quot;335559740&amp;quot;:300}"&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;</description>
      <pubDate>Thu, 11 Jun 2026 09:09:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/last-call-join-live-the-postgresql-community-at-posette-an-event/ba-p/4527424</guid>
      <dc:creator>scoriani</dc:creator>
      <dc:date>2026-06-11T09:09:00Z</dc:date>
    </item>
    <item>
      <title>What's new with Postgres at Microsoft, 2026 edition</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/what-s-new-with-postgres-at-microsoft-2026-edition/ba-p/4526963</link>
      <description>&lt;P&gt;A lot has happened with Postgres at Microsoft over the past year. This is the 2026 edition of our annual “what’s new” blog post, with highlights from the past 12–13 months—across both our managed services on Azure and our work in the upstream open source project.&lt;/P&gt;
&lt;P&gt;The infographic below pulls it all together—feature updates, new capabilities, and ongoing investments across our Postgres workstreams. You might notice it looks a bit different &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/whats-new-with-postgres-at-microsoft-2025-edition/4410710" target="_blank" rel="noopener"&gt;compared to last year&lt;/A&gt;: we redesigned the infographic to make space for two new sections—Azure HorizonDB (Preview) and Developer Tools.&lt;/P&gt;
&lt;P&gt;The table of contents follows the structure of the hand-made infographic, with each bullet linking to that section. Jump to what you care about, or settle in ☕️ and read the whole thing.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-azure-database-for-postgresql" target="_blank" rel="noopener" data-lia-auto-title="Azure Database for PostgreSQL flexible server" data-lia-auto-title-active="0"&gt;Azure Database for PostgreSQL flexible server&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-horizondb" target="_blank" rel="noopener" data-lia-auto-title="Azure HorizonDB" data-lia-auto-title-active="0"&gt;Azure HorizonDB&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-dev-tools" target="_blank" rel="noopener" data-lia-auto-title="Developer Tools" data-lia-auto-title-active="0"&gt;Developer Tools&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-lia-auto-title="PostgreSQL core" data-lia-auto-title-active="0"&gt;PostgreSQL core&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-citus" target="_blank" rel="noopener" data-lia-auto-title="Citus open source" data-lia-auto-title-active="0"&gt;Citus open source&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-community" target="_blank" rel="noopener" data-lia-auto-title="Postgres Community" data-lia-auto-title-active="0"&gt;Postgres Community&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;&lt;STRONG&gt;Figure 1:&lt;/STRONG&gt; This infographic maps out the major workstreams across Microsoft’s Postgres efforts as of June 2026—from the managed database services on Azure, to VS Code and Cursor, to upstream contributions to the Postgres open source project. For much of the open source work, our contributions to PostgreSQL involve collaboration with people across the global PostgreSQL community, both inside and outside Microsoft.&lt;/P&gt;
&lt;/img&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-azure-database-for-postgresql" class="lia-anchor"&gt;&lt;/a&gt;Azure Database for PostgreSQL flexible server&lt;/H2&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;Azure Database for PostgreSQL flexible server is a managed database service on Azure that meets the needs of large enterprises, small to medium-sized businesses, and early-stage startups. Flexible Server continues to grow in capability month over month, as evident in the monthly “feature recap” blog posts on Microsoft Tech Community (props to Gauri Kasar for publishing these) in &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://review.learn.microsoft.com/en-us/product-style-guide-msft-internal/a_z_names_terms/a/azure-database-for-postgresql?branch=main" target="_blank" rel="noopener"&gt;June 2025&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/july-2025-recap-azure-database-for-postgresql/4439578" target="_blank" rel="noopener"&gt;July&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/august-2025-recap-azure-database-for-postgresql/4450527" target="_blank" rel="noopener"&gt;August&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/september-2025-recap-azure-database-for-postgresql/4459848" target="_blank" rel="noopener"&gt;September&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/october-2025-recap-azure-database-for-postgresql/4468818" target="_blank" rel="noopener"&gt;October&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/november-2025-recap-postgresql-on-azure/4477020" target="_blank" rel="noopener"&gt;November&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/january-2026-recap-azure-database-for-postgresql/4492408" target="_blank" rel="noopener"&gt;January 2026&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/february-2026-recap-azure-database-for-postgresql/4501093" target="_blank" rel="noopener"&gt;February&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/march-2026-recap-azure-database-for-postgresql/4511432" target="_blank" rel="noopener"&gt;March&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://techcommunity.microsoft.com/blog/adforpostgresql/april-2026-recap-azure-database-for-postgresql/4519772" target="_blank" rel="noopener"&gt;April&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;TIP ON NAMING&lt;/STRONG&gt;: Throughout this post, we sometimes use the full name—Azure Database for PostgreSQL flexible server—and sometimes we just say “Flexible Server” for short. They mean the same thing. You might notice we use the two names interchangeably, so am flagging it here to avoid any confusion.&lt;/P&gt;
&lt;H3&gt;Performance &amp;amp; Scalability&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Premium SSDv2 storage: &lt;/STRONG&gt;With the general availability of Premium SSDv2 storage, significant performance and cost-efficiency improvements are now available for IO-intensive workloads. With SSDv2, storage and performance can be scaled independently so you only pay for what you use. Premium SSDv2 adds flexible server storage scaling up to 64TB, with up to 80,000 IOPS and 1,200 MiB/s throughput. (&lt;A href="https://learn.microsoft.com/azure/postgresql/compute-storage/concepts-storage-premium-ssd-v2" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Elastic Clusters support for Terraform, Bicep, &amp;amp; Ansible:&lt;/STRONG&gt; With the general availability of Elastic clusters, flexible server added built-in support for row-level and schema-level sharding of data across a cluster of servers. Built-on Citus open-source technology, elastic clusters provides horizontal scaling of workloads with all the enterprise features of flexible server. We’ve added infra-as-code support to deploy elastic clusters from Terraform, Bicep, and Ansible. (&lt;A href="https://learn.microsoft.com/azure/postgresql/elastic-clusters/concepts-elastic-clusters" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Cascading read replicas: &lt;/STRONG&gt;With the general availability of cascading read replicas, you can not only create read replicas from the primary, but from other replicas too—enabling up to 30 replicas, more efficient distribution of read traffic, and more flexibility for complex deployment topologies. (&lt;A href="https://learn.microsoft.com/azure/postgresql/read-replica/concepts-read-replicas#create-cascading-read-replicas" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Intel &amp;amp; AMD v6 series SKUs: &lt;/STRONG&gt;The Intel &amp;amp; AMD v6 General Purpose and Memory Optimized SKUs deliver high-performance, massive scale and better price performance. Powered by 5th Gen Intel® Xeon® processor and AMD's fourth Generation EPYC™ 9004 processors you can scale up to 192 vCores and 1.8 TiB of memory. Using the NVMe protocol for data disk access you can leverage the maximum IOPS and throughput from high performance IO options like SSDv2.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/postgresql/compute-storage/concepts-compute" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;New Azure Advisor performance recommendations:&lt;/STRONG&gt; Azure Advisor provides proactive performance, resiliency, and security recommendations for your workloads. We added Index scan insights to improve query efficiency, audit logging review to identify excessive logging, statistics monitoring with alerts on statistics resets, storage optimization recommendations, and connection management guidance.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/advisor/advisor-reference-performance-recommendations#azure-database-for-postgresql" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PgBouncer upgrades: &lt;/STRONG&gt;PgBouncer is the built-in connection pooling feature for flexible server, providing the ability to scale to thousands of connections. Upgrading to 1.25.1 added enhanced protocol handling and important stability and security fixes. (&lt;A href="https://learn.microsoft.com/azure/postgresql/connectivity/concepts-pgbouncer" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;pg_duckdb extension (Preview):&lt;/STRONG&gt; The &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_duckdb&lt;/CODE&gt; extension combines PostgreSQL’s transactional performance and reliability with DuckDB’s analytical speed for large datasets. This makes a great combination for hybrid OLTP and OLAP environments where you need to run analytical queries directly in PostgreSQL without compromising on performance.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://aka.ms/pg_duckdb" target="_blank" rel="noopener"&gt;link to demo video&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;pg_ivm extension:&lt;/STRONG&gt; The &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_ivm&lt;/CODE&gt; extension implements Incremental View Maintenance (IVM), allowing materialized views to by updated more efficiently by only applying incremental changes when the underlying data changes—resulting in improved performance for large datasets where only a small subset of the data is modified. (&lt;A href="https://github.com/sraoss/pg_ivm" target="_blank" rel="noopener"&gt;link to repo&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Manageability&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Built-in Grafana monitoring dashboard: &lt;/STRONG&gt;Grafana dashboards for your flexible server instances are now readily available from the Azure Portal in your Azure Database for PostgreSQL view. You can now visualize metrics and logs, correlate events by timestamp, and rapidly gain insights into performance, query behavior, and availability with built-in dashboards.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/dashboards-with-grafana---now-in-azure-portal-for-postgresql/4497607" target="_blank" rel="noopener"&gt;link to blog&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Maintenance payload visibility:&lt;/STRONG&gt; Maintenance updates to flexible server can include PostgreSQL minor version updates, security fixes, bug fixes and new functionality. It’s important to know what’s changing so you know what to expect, what improvements you can take advantage of, and whether to flag any concerns. You can now access the release notes for maintenance updates. (&lt;A href="https://learn.microsoft.com/azure/postgresql/release-notes-maintenance/release-notes-maintenance-index" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Defer maintenance &amp;amp; Maintenance on demand:&lt;/STRONG&gt; Using Custom Maintenance Windows (CMW) and System-managed Maintenance Windows (SMW) gives you control over when to apply flexible server maintenance updates. We’ve expanded that control with the ability to defer an upcoming maintenance update by up to 2 weeks, or to apply one on demand. These new options are available in the Azure Portal, with CLI and API support coming soon. (&lt;A href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-maintenance#system-managed-windows-smw-vs-custom-maintenance-windows-cmw" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL 18 (w/MVU &amp;amp; Terraform support): &lt;/STRONG&gt;PostgreSQL 18 was made available on Azure on the same day as the community release, with a host of performance and security improvements . PG18 general availability added support for all Azure public regions, Major Version Upgrade, Entra ID authentication, and Terraform support. (&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/postgresql-18-now-ga-on-azure-postgres-flexible-server/4469802" target="_blank" rel="noopener"&gt;link to blog&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;5 new regions added: Austria East, Denmark East, Indonesia Central, Malaysia West, Chile Central: &lt;/STRONG&gt;New Azure regions for flexible server are continually being added in response to customer demand. You can check out the region availability list to stay up to date with supported regions. (&lt;A href="https://learn.microsoft.com/azure/postgresql/overview#azure-regions" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;HA expansion: Japan West: &lt;/STRONG&gt;Existing regions are also being retrofitted to add availability zones which support zone-redundant High Availability. In this timeframe, we’ve added support for multi-zone deployment in Japan West. (&lt;A href="https://learn.microsoft.com/azure/postgresql/overview#azure-regions" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Resiliency&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Zonal resiliency HA setting:&lt;/STRONG&gt; Zone-redundant high Availability (HA) is the recommended and default HA configuration for maximum resiliency. The Azure Portal now includes a Zonal Resiliency setting that lets you select same-zone HA if a region doesn’t support zone-redundant HA—with automatic migration once capacity becomes available. (&lt;A href="https://learn.microsoft.com/azure/postgresql/high-availability/how-to-configure-high-availability" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Near-zero downtime scaling for HA-enabled servers:&lt;/STRONG&gt; This feature minimizes downtime when you modify the storage and compute tiers. Scaling operations such as vCore or Compute tier operations can now HA failovers to maintain the connection string, reducing downtime to typically under 30 seconds. You don’t need to take any action to use this feature. (&lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-scaling-resources#near-zero-downtime-scaling" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Long term backups:&lt;/STRONG&gt; Backups with Long Term Retention (LTR) enable you to keep backups for up to 10 years, enabling you to meet regulatory and audit-driven requirements for long-term data retention.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/postgresql/backup-restore/concepts-backup-restore#long-term-retention" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Logical replication slot synchronization metric: &lt;/STRONG&gt;A new metric called &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;logical_replication_slot_sync_status&lt;/CODE&gt; provides a binary signal to indicate whether logical replication slots are synchronized across High Availability (HA) primary and standby nodes. This adds a clear signal for failover readiness to help with scenarios where data continuity during failover is critical.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/monitor/concepts-monitoring#logical-replication" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Security and networking&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure Confidential Computing:&lt;/STRONG&gt; PostgreSQL flexible server instances can now run on Confidential Virtual Machines (CVMs) inside a Trusted Execution Environment (TEE)—a secure, isolated enclave with encrypted memory, enabling end-to-end security and enhanced privacy to meet the strictest security standards for regulated workloads. (&lt;A href="https://learn.microsoft.com/azure/postgresql/security/security-confidential-computing" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Entra ID group login using user credentials: &lt;/STRONG&gt;You can authenticate to Azure Database for PostgreSQL with your Entra ID as a member of a Microsoft Entra group by creating a group principal. Managed identities and service principals are also supported as group members.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/postgresql/security/security-entra-configure#authenticate-with-microsoft-entra-id-as-a-group-member" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Entra ID token refresh libraries for .NET, Python, Java:&lt;/STRONG&gt; Using Entra ID for authentication throughout your application supports an identity-based security perimeter, simplifying how applications authenticate with Azure Database for PostgreSQL, but it also means your application needs to handle additional complexities like Entra token refresh. These libraries take care of the token refresh logic, making it easy to add token refresh support to your applications with minimal code changes.&lt;STRONG&gt; &lt;/STRONG&gt;(link to libraries &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;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Credcheck, anon, ip4r extensions:&lt;/STRONG&gt; We onboarded several extensions over the last year that help with compliance and regulatory requirements, including:&lt;BR /&gt;&lt;BR /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;anon&lt;/STRONG&gt;: GA of the upgraded&amp;nbsp;&lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;anon&lt;/CODE&gt; extension, adding support for dynamic and static masking, anonymized exports, randonmization, and other advanced masking techniques.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;credcheck&lt;/STRONG&gt;: The&amp;nbsp;&lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;credcheck&lt;/CODE&gt; extension adds credential checks for usernames and password complexity.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;ip4r&lt;/STRONG&gt;: The&amp;nbsp;&lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;ip4r&lt;/CODE&gt; extension provides a set of data types for Ipv4 and Ipv6 network addresses which are useful for auditing, compliance, and intrusion detection.&lt;STRONG&gt; &lt;/STRONG&gt;(link to docs: &lt;A href="https://postgresql-anonymizer.readthedocs.io/en/latest/" target="_blank" rel="noopener"&gt;anon&lt;/A&gt;, &lt;A href="https://github.com/HexaCluster/credcheck" target="_blank" rel="noopener"&gt;credcheck&lt;/A&gt;, &lt;A href="https://github.com/RhodiumToad/ip4r" target="_blank" rel="noopener"&gt;IP4R&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Priority connectivity for azure_pg_admin users: &lt;/STRONG&gt;The &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;azure_pg_admin&lt;/CODE&gt; role provides a way to perform privileged administrator operations without access to the superuser role, reducing the risk of privilege escalation. This role was updated to work with PG16’s stricter role hierarchy, allowing management of objects owned by any non-restricted role. It also ensures that at least one database connection is always available to admin users—even when the client connection pool is full—helping prevent lockout situations and making troubleshooting easier.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/migration-service/concepts-required-user-permissions#online-migration-using-pgoutput---required-publication-permissions" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Defender security assessments (Preview): &lt;/STRONG&gt;Two new Microsoft Defender for Cloud CSPM security recommendations for flexible server are now availability:
&lt;UL&gt;
&lt;LI&gt;Geo-redundant backups should be enabled for PostgreSQL Servers, and&lt;/LI&gt;
&lt;LI&gt;&lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;require_secure_transport&lt;/CODE&gt; should be set to "on" for PostgreSQL Servers&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;BR /&gt;These assessments evaluate database configuration settings against recommended security practices, helping you manage risk and align with internal and industry standards. Additional security assessments will be added over time. &lt;STRONG style="color: rgb(30, 30, 30);"&gt; &lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;(&lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://learn.microsoft.com/azure/defender-for-cloud/release-notes-recommendations-alerts#recommendations-alerts-and-incidents-updates" target="_blank" rel="noopener"&gt;link to new recommendations&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;VNET to Private Link migration (Preview):&lt;/STRONG&gt; Previously, it wasn’t possible to migrate servers deployed inside a VNET to an updated secure network configuration based on Private Endpoint connectivity, which is simpler and more scalable. With the VNET to Private endpoint migration preview, you can use the Azure CLI, API or SDK to migrate your server without needing to recreate it. (&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;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Extended CVE support for PG11, 12, 13: &lt;/STRONG&gt;If you’re running a PostgreSQL version in flexible server that is no longer community supported like PG11, 12, or 13, it will continue to be patched with high priority CVEs for 3 years after the community retirement data as part of Azure Database for PostgreSQL extended support.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/azure/postgresql/configure-maintain/extended-support" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Integration&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Mirroring data to Microsoft Fabric:&lt;/STRONG&gt; The general availability of Fabric mirroring in flexible server opens up near real-time replication of data from Azure Database for PostgreSQL to Microsoft Fabric—enabling the advanced analytics and reporting capabilities of Fabric without the need for extensive ETL. It also means your PostgreSQL server is free to run mission-critical transactional workloads without being affected by spikes in analytical reporting.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://learn.microsoft.com/fabric/mirroring/azure-database-postgresql" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Ansible module update: &lt;/STRONG&gt;A new version of the Ansible collection for flexible server was released, adding support for support for Elastic clusters, PG18, virtual endpoints, on-demand backups, system-assigned identity, storage auto-grow, read replica switchover and more.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://docs.ansible.com/projects/ansible/latest/collections/azure/azcollection/azure_rm_postgresqldatabase_module.html" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Updated Go, Java, JavaScript, .NET &amp;amp; Python SDKs:&lt;/STRONG&gt; The udpated SDKs for performance flexible server operations add PG18 support, improved Elastic cluster features and improved response codes.&lt;STRONG&gt; &lt;/STRONG&gt;(link to SDKs: &lt;A href="https://www.nuget.org/packages/Azure.ResourceManager.PostgreSql/#versions-body-tab" target="_blank" rel="noopener"&gt;.NET&lt;/A&gt;, &lt;A href="https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/postgresql/armpostgresqlflexibleservers/v5@v5.0.0" target="_blank" rel="noopener"&gt;Go&lt;/A&gt;, &lt;A href="https://central.sonatype.com/artifact/com.azure.resourcemanager/azure-resourcemanager-postgresqlflexibleserver/2.0.0" target="_blank" rel="noopener"&gt;Java&lt;/A&gt;, &lt;A href="https://www.npmjs.com/package/@azure/arm-postgresql-flexible/v/9.0.0" target="_blank" rel="noopener"&gt;Javascript&lt;/A&gt;, &lt;A href="https://pypi.org/project/azure-mgmt-postgresqlflexibleservers/2.0.0/" target="_blank" rel="noopener"&gt;Python&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Upsert and Script activity in ADF and Azure Synapse:&lt;/STRONG&gt; New capabilities were provided to make merging data into existing tables easier with the Upsert method, and to run custom SQL scripts as part of workflows enabled more streamlined ETL processes with Azure Data Factory and Azure Synapse. (link to &lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/how-to-data-factory-copy-activity-azure?tabs=copy-command" target="_blank" rel="noopener"&gt;Upsert Method&lt;/A&gt;and &lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/how-to-data-factory-script-activity-azure?tabs=query" target="_blank" rel="noopener"&gt;script activity&lt;/A&gt; docs)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Stable REST API release for 2025:&lt;/STRONG&gt; The 2025-08-01 stable REST API release for Azure Database for PostgreSQL added support for the latest PostgreSQL major versions, Elastic Cluster and CMK enhancements.&lt;STRONG&gt; &lt;/STRONG&gt;(&lt;A href="https://github.com/Azure/azure-rest-api-specs/tree/main/specification/postgresql/resource-manager/Microsoft.DBforPostgreSQL/stable" target="_blank" rel="noopener"&gt;link to released APIs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure Storage extension Parquet support:&lt;/STRONG&gt; Parquet is a popular columnar storage format that is widely used in big data and analytics environments.&lt;STRONG&gt; &lt;/STRONG&gt;With Parquet support in &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;azure_storage&lt;/CODE&gt;, you can now perform direct SQL-based reads and writes to Parquet files in &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;azure_storage&lt;/CODE&gt;, making it easy to import and export data to and from PostgreSQL without needing external tools or scripts. (&lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-storage-extension" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Migration service in Azure Database for PostgreSQL&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;AI-assisted Oracle to PostgreSQL migration tool&lt;/STRONG&gt;: Migration from one database type to another has traditionally been a complex, time-consuming and costly project. The emergence of AI-assisted migration tooling has dramatically reduced this cost. The AI-assisted migration tooling available with the VS Code PostgreSQL extension converts Oracle schema and application code to Azure Database for PostgreSQL flexible server. This tooling leverages GitHub Copilot, Microsoft Foundry, and custom Language Model tools to convert Oracle schema, database code and client applications into PostgreSQL-compatible formats and validates every change against a running flexible server instance. (&lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/oracle-schema-conversions/schema-conversions-overview" target="_blank" rel="noopener"&gt;Link to schema conversion docs&lt;/A&gt;, &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/oracle-application-conversions/app-conversions-overview" target="_blank" rel="noopener"&gt;link to app conversion docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure Migrate discovery &amp;amp; assessment:&lt;/STRONG&gt; The first step in a database migration process is Discovery: understanding what you’re running and the state of migration readiness. Azure Migrate now provides PostgreSQL discovery and assessment to report on your on-prem PostgreSQL landscape, identify potential migration blockers, and learn tailored SKU and cost insights with a streamlined migration assessment. (&lt;A href="https://learn.microsoft.com/azure/migrate/tutorial-assess-postgresql?view=migrate" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Migration with pgoutput plugin&lt;/STRONG&gt;: Online migration to flexible server became generally available last June and we’ve continued to improve it. You can now leverage &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pgoutput&lt;/CODE&gt; (used by PostgreSQL’s logical replication framework) for online migration with improved reliability and performance. The update provides improved compatibility with modern PostgreSQL deployments and reduces dependency on legacy decoding mechanisms, enabling functionality like fine-grained filtering using Publications, allowing migration of specific tables and filtering by operations. (&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/migrate/migration-service/overview-migration-service-postgresql" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;AlloyDB &amp;amp; EDB migration sources:&lt;/STRONG&gt; You can now migrate directly from AlloyDB and EDB Extended Server to PostgreSQL using the Azure Database for PostgreSQL Migration Service, with both online and offline migration support. (link to docs: &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/migration-service/tutorial-migration-service-alloy-db-online?tabs=portal" target="_blank" rel="noopener"&gt;AlloyDB&lt;/A&gt;, &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/migration-service/tutorial-migration-service-enterprise-db-extended-server-online?tabs=portal" target="_blank" rel="noopener"&gt;EDB&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;AI capabilities in Flexible Server&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;AI Functions (Preview): &lt;/STRONG&gt;AI Functions add extraction, generation, classification, and re-ranking directly into SQL through the &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;azure_ai&lt;/CODE&gt; extension using an Azure OpenAI or Microsoft Foundry model. It replaces hundreds of lines of Python glue with a one-line SQL call. (&lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/azure-ai/generative-ai-azure-overview" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;pgvector 0.8.2 support: &lt;/STRONG&gt;pgvector 0.8.2, focuses on stabilizing parallel HNSW index builds, fixing correctness issues and improving reliability, all important steps toward production-grade vector search. (&lt;A href="https://learn.microsoft.com/azure/postgresql/flexible-server/concepts-extensions#vector" target="_blank" rel="noopener"&gt;link to docs)&lt;/A&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Microsoft Foundry integration (Preview):&lt;/STRONG&gt; We've shipped a PostgreSQL connector for Microsoft Foundry built on the Model Context Protocol (MCP). Foundry agents can now explore your Postgres schema, retrieve records, run analytical queries, and perform vector similarity searches in natural language, secured by Microsoft Entra ID (&lt;A href="https://learn.microsoft.com/azure/postgresql/azure-ai/generative-ai-foundry-integration" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;LangGraph/LangChain connector&lt;/STRONG&gt;: The new native Azure Database for PostgreSQL connector for both frameworks gives agents first-class vector retrieval, checkpointing, and conversational memory backed by your Postgres instance with Entra ID authentication and production-grade reliability out of the box. (&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/build-enterprise-ready-ai-agents-with-the-new-azure-postgres-langchain--langgrap/4453420" target="_blank" rel="noopener"&gt;link to blog&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Apache AGE extension support&lt;/STRONG&gt;: Apache AGE is now supported on Azure Database for PostgreSQL, bringing graph queries to the same database that already holds your relational tables, JSON, vectors, and full-text indexes. (&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/postgresql-as-your-graph-database-in-the-ai-era/4516323" target="_blank" rel="noopener"&gt;link to blog&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Try it out: Quickstart for Azure Database for PostgreSQL&lt;/H3&gt;
&lt;P&gt;The&amp;nbsp;&lt;A href="https://learn.microsoft.com/azure/postgresql/configure-maintain/quickstart-create-server" target="_blank" rel="noopener"&gt;Quickstart: Create an Azure Database for PostgreSQL flexible server&lt;/A&gt;&amp;nbsp;docs page walks you through how to get started deploying your own flexible server instance, including a link to a free Azure trial account.&lt;/P&gt;
&lt;H2&gt;Our Postgres team is hiring!&lt;/H2&gt;
&lt;P&gt;If you’re a deep Postgres expert—or a strong Linux systems engineer—this might be your moment. We’re continuing to grow the Postgres team at Microsoft. (&lt;A href="https://apply.careers.microsoft.com/careers/job/1970393556744853" target="_blank" rel="noopener"&gt;link to Principal Software Engineer role&lt;/A&gt;; and &lt;A href="https://apply.careers.microsoft.com/careers/job/1970393556744851" target="_blank" rel="noopener"&gt;link to Software Engineer II role&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;As Affan Dar, the VP of Engineering for Postgres at Microsoft says all the time:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;“We are &lt;EM&gt;always&lt;/EM&gt; looking for strong Linux systems engineers and PostgreSQL experts to help us build the future of Postgres at Microsoft.”&amp;nbsp;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-horizondb" class="lia-anchor"&gt;&lt;/a&gt;Azure HorizonDB (Preview)&lt;/H2&gt;
&lt;P&gt;Azure HorizonDB launched in private preview last November, and at Microsoft Build in May 2026 we&amp;nbsp;&lt;A href="https://news.microsoft.com/build-2026-live-blog/microsoft-build-2026-live/?live-feed-entry-id=4977" target="_blank" rel="noopener"&gt;announced the public preview&lt;/A&gt;. If you want a quick overview, the excerpt below from the &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai-era/4524094" target="_blank" rel="noopener"&gt;announcement blog post&lt;/A&gt; is a good place to start—or you can dive straight into some of the key HorizonDB features further down. &lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;"Azure HorizonDB is built to meet the demands of security, resilience, scale, and performance—combining the flexibility developers expect from Postgres with the operational rigor enterprises require.&lt;BR /&gt;&lt;BR /&gt;It extends the core Postgres engine with cloud-native capabilities such as integrated identity, fine-grained network and security controls, and seamless lifecycle management, while preserving full compatibility with the open ecosystem of extensions.&lt;/P&gt;
&lt;P&gt;HorizonDB introduces advanced, natively integrated capabilities like vector data support and AI model management, enabling new classes of intelligent applications without sacrificing transactional integrity or developer productivity." &lt;BR /&gt;&lt;BR /&gt;—Excerpted from "Azure HorizonDB: Enterprise-Ready Postgres, Engineered for the AI Era" announcement blog post&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Low latency commits&lt;/STRONG&gt;:&lt;STRONG&gt; &lt;/STRONG&gt;The architecture of Azure HorizonDB (Preview) separates compute and storage, so storage is shared by all compute nodes. This shared storage architecture enables low-latency, millisecond commits within region providing critical support for tier-1, performance-sensitive workloads. (&lt;A href="https://learn.microsoft.com/azure/horizondb/overview" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Scale up to 192 Cores&lt;/STRONG&gt;: Azure HorizonDB supports compute scaling up to 192 cores for both primary and replica instances, enabling the capacity needed to handle workload spikes. (&lt;A href="https://learn.microsoft.com/azure/horizondb/configure-maintain/how-to-scale-compute" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Read scale-out with 15 replicas&lt;/STRONG&gt;: Support for up to 15 read replicas, with read connections automatically load-balanced across them to efficiently scale out read workloads. (&lt;A href="https://learn.microsoft.com/azure/horizondb/configure-maintain/how-to-add-remove-replica" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Autoscaling storage up to 128 TB&lt;/STRONG&gt;: Support for storage auto-scaling up to 128 TB, eliminating the need to pre-provision storage size. Storage automatically shrinks as your data footprint decreases. (&lt;A href="https://learn.microsoft.com/azure/horizondb/overview#storage" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Zone resilient storage&lt;/STRONG&gt;: Azure HorizonDB leverages Azure Blob Storage, which is zone-resilient by default, to ensure zero data loss. (&lt;A href="https://learn.microsoft.com/azure/horizondb/overview#storage" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Entra ID Authentication&lt;/STRONG&gt;: Azure HorizonDB provides native integration with Microsoft Entra ID, enabling centralized identity and access management for PostgreSQL workloads. This integration supports secure, token-based authentication while allowing organizations to enforce enterprise security policies such as multi-factor authentication and conditional access.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Private Endpoints &lt;/STRONG&gt;: Azure HorizonDB supports Azure Private Endpoints, ensuring that database connectivity remains entirely within a customer’s private Azure VNET boundary. This capability minimizes exposure to the public internet and helps organizations satisfy stringent security, compliance, and regulatory requirements.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Mirroring to Microsoft Fabric&lt;/STRONG&gt;: Azure HorizonDB includes native mirroring to Microsoft Fabric, enabling near real-time replication of operational PostgreSQL data into analytics-ready OneLake storage. This capability simplifies modern analytics architectures by reducing dependency on complex ETL pipelines while supporting scalable BI, AI, and data engineering workloads. &lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;~75 popular Postgres extensions&lt;/STRONG&gt;: Azure HorizonDB is fully PostgreSQL-compatible and supports approximately ~75 popular extensions such as &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_stat_statements&lt;/CODE&gt;, &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;auto_explain&lt;/CODE&gt;, &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_duckdb&lt;/CODE&gt;, &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_diskann&lt;/CODE&gt;. It will continue to expand support for additional extensions, including both PostgreSQL and Azure-specific offerings such as AI extensions. (&lt;A href="https://learn.microsoft.com/azure/horizondb/extensions/concepts-extensions-versions" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Full-text search with BM25 ranking (pg_textsearch)&lt;/STRONG&gt;: &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_textsearch&lt;/CODE&gt; brings BM25 the same relevance algorithm behind every major search engine directly into HorizonDB as a native extension. BM25 offers better relevance than PostgreSQL's built-in &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;ts_rank&lt;/CODE&gt;, and you can combine it with vector search in one SQL query for true hybrid retrieval. (&lt;A href="https://learn.microsoft.com/azure/horizondb/ai/full-text-search" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;DiskANN Advanced filtering&lt;/STRONG&gt;: DiskANN Advanced Filtering offers lower latency on filtered vector search compared to traditional approaches, so a query like "find the most similar products under $50 in the Electronics category" runs at full DiskANN speed. (&lt;A href="https://learn.microsoft.com/azure/horizondb/ai/vector-index-diskann#use-advanced-filtering" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;AI model management&lt;/STRONG&gt;: AI Model Management in Azure HorizonDB simplifies how you bring AI into your database. With a single step, it provisions fully managed AI models for embeddings, semantic ranking, and generation through Microsoft Foundry—and installs and configures the &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;azure_ai&lt;/CODE&gt; extension to enable AI functions like &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;generate()&lt;/CODE&gt;, &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;extract()&lt;/CODE&gt;, &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;create_embeddings()&lt;/CODE&gt;, and &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;rank()&lt;/CODE&gt; for immediate use directly in SQL. This removes the need for manual setup and context switching, with model provisioning, management, monitoring, and billing handled seamlessly within HorizonDB. (&lt;A href="https://learn.microsoft.com/azure/horizondb/ai/ai-model-management" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;AI pipelines&lt;/STRONG&gt;: AI Pipelines let you describe an AI workflow (chunking, embedding, extraction, generation, ranking, human approval) declaratively in SQL, and run it as a fault-tolerant pipeline that lives inside the database built on pg_durable. (&lt;A href="https://learn.microsoft.com/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Durable functions (pg_durable):&lt;/STRONG&gt; &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_durable&lt;/CODE&gt; is an open source extension that lets you describe long-running workflows such as sequential steps, parallel fan-out, scheduled jobs, human-in-the-loop, and retries declaratively in SQL. And then you can run them as fault-tolerant durable functions that live inside the database. (&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;link to GitHub Repo&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;BACKSTORY&lt;/STRONG&gt;: Beyond features, if you want to learn more about the story behind Azure HorizonDB, listen to the &lt;A href="https://talkingpostgres.com/episodes/from-memsql-to-horizondb-an-engineers-journey-with-adam-prout" target="_blank" rel="noopener"&gt;Talking Postgres podcast episode with guest Adam Prout&lt;/A&gt;, one of the founding architects of Azure HorizonDB.&lt;/P&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-dev-tools" class="lia-anchor"&gt;&lt;/a&gt;Developer Tools&lt;/H2&gt;
&lt;P&gt;We &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/announcing-a-new-ide-for-postgresql-in-vs-code-from-microsoft/4414648" target="_blank" rel="noopener"&gt;launched a new IDE for PostgreSQL in VS Code&lt;/A&gt; in May 2025—and the response was strong, including a day at the top of Hacker News and over 170K views of the original blog post. One year later, the extension has &lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql" target="_blank" rel="noopener"&gt;more than 560K+ installs&lt;/A&gt;, we’ve kept building and adding more capabilities. Below are some of the highlights. We also recently &lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/your-postgresql-workflow-just-found-its-new-home-in-cursor/4524081" target="_blank" rel="noopener"&gt;added support for Cursor&lt;/A&gt;, available via the Open VSX Registry.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;VS Code extension to connect to any Postgres, anywhere&lt;/STRONG&gt;: You can connect to any PostgreSQL database directly from the VS Code extension for PostgreSQL—whether it’s running locally, in a container, on-prem, or in any cloud. Connection profiles let you switch between environments without leaving the editor. (&lt;A href="https://learn.microsoft.com/azure/postgresql/developer/vs-code-extension/vs-code-connect" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;One-click Dockerized Postgres + integrated psql&lt;/STRONG&gt;: Local development is streamlined through the PostgreSQL extension in VS Code, including quick setup of a PostgreSQL environment and support for familiar tools like psql. This reduces the amount of manual setup needed to start querying. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#create-a-docker-postgresql" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Object Explorer with cross-database search&lt;/STRONG&gt;: Within VS Code, the PostgreSQL extension provides an Object Explorer for browsing tables, views, and functions across databases. You can also search across schemas and databases without manually navigating the full tree. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#object-explorer-search" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Schema visualization&lt;/STRONG&gt;: Schema visualization is built into the VS Code extension for PostgreSQL, making it easier to understand relationships between tables. This can be especially useful when working with unfamiliar or complex data models (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#schema-visualization" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Intellisense query editor with CSV/JSON&lt;/STRONG&gt;: The VS Code extension for PostgreSQL includes a query editor with IntelliSense that is schema aware. Query results are returned in a grid and can be exported to formats like CSV or JSON for further analysis. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#query" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Query plan visualizer &amp;amp; Copilot analysis&lt;/STRONG&gt;: Query plans can be visualized directly in VS Code using the PostgreSQL extension, helping surface bottlenecks and execution details. With GitHub Copilot, you can also get explanations and suggestions for improving query performance. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#query-plan-visualization" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Apache AGE Cypher graph visualization&lt;/STRONG&gt;: Support for Apache AGE allows graph queries to be run and visualized as node-edge diagrams directly in VS Code. This enables exploration of graph data without requiring a separate visualization tool. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#apache-age-graph-visualization" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Copilot Agent Mode tools (run SQL, design schemas, import CSV):&lt;/STRONG&gt; When used with the VS Code extension for PostgreSQL, GitHub Copilot can operate in agent mode to assist with multi-step workflows such as running queries, designing schemas, or importing data. These actions are suggested in natural language while still requiring user confirmation. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#copilot-pgsql-agent" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Copilot metrics intelligence in Server dashboard&lt;/STRONG&gt;: The VS Code extension for PostgreSQL includes server dashboards that surface database performance metrics. GitHub Copilot can help interpret these signals and guide troubleshooting or optimization efforts. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#metrics-intelligence-with-github-copilot" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Entra authentication for Azure Database for PostgreSQL&lt;/STRONG&gt;: Connections from the VS Code extension for PostgreSQL to Azure Database for PostgreSQL support Microsoft Entra ID authentication. This enables secure, passwordless access directly from the editor. (&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql#connect-to-postgresql" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure server browse, create, &amp;amp; manage in-IDE&lt;/STRONG&gt;: Azure Database for PostgreSQL resources can be discovered, created, and managed directly within VS Code through the PostgreSQL extension. This reduces the need to switch to the Azure portal for common workflows. (&lt;A href="https://learn.microsoft.com/azure/postgresql/developer/vs-code-extension/vs-code-connect" target="_blank" rel="noopener"&gt;link to docs&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Cursor extension for PostgreSQL&lt;/STRONG&gt;: An extension for PostgreSQL is also available in Cursor and other Open VSX-compatible editors, bringing the same database tooling into those environments. In Cursor, these workflows integrate with Cursor’s native AI experience while preserving the core Postgres capabilities. (&lt;A href="https://techcommunity.microsoft.com/blog/adforpostgresql/your-postgresql-workflow-just-found-its-new-home-in-cursor/4524081" target="_blank" rel="noopener"&gt;link to blog post&lt;/A&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;Contributing to PostgreSQL core&lt;/H2&gt;
&lt;P&gt;Microsoft continues to invest in our open-source PostgreSQL contributors team and reaffirms its commitment to open source. The team continues to drive large and ambitious projects in upstream PostgreSQL and make all those features available to all Postgres users.&lt;/P&gt;
&lt;P&gt;The team has a broad range of expertise, and our contributions to Postgres span almost all areas in Postgres, including the Query Planner, Executor, Storage/IO subsystems, Security, Operational and Manageability improvements, new SQL features and much more.&lt;/P&gt;
&lt;P&gt;Our commitment to supporting Postgres development hasn’t changed since &lt;A href="https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/what-s-new-with-postgres-at-microsoft-august-2023/ba-p/3914506#postgres-open-source" target="_blank" rel="noopener"&gt;Claire Giordano first wrote this back in August 2023&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;In order to thrive, an open source ecosystem needs commercial support as well as volunteer efforts. Even open source developers need to eat! For the Postgres open source ecosystem to flourish, companies like Microsoft need to support the project by funding development in the Postgres core. Which we do.&lt;BR /&gt;&lt;BR /&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;PostgreSQL is a complex piece of software that runs mission-critical workloads across the globe. To provide the best possible experience on Azure, it follows that we need to thoroughly understand how it works. By having PostgreSQL committers and contributors on our team, they can share knowledge internally across different orgs, or directly answer internal questions regarding incidents or extension development.&lt;BR /&gt;&lt;BR /&gt;Because today's cloud operates at a scale most on-prem solutions never encountered, unique cloud data center problems, often relating to performance, now require special attention. Our in-house team of deep Postgres experts are focused on tackling these cloud-scale issues upstream, in the Postgres core. Another benefit: our team's Postgres expertise gives Azure customers confidence in our cloud database services, too.&lt;BR /&gt;&lt;BR /&gt;Commercial funding of PostgreSQL developers has another benefit: it gives developers the long-term stability to pursue the big things, the groundbreaking changes that are super important to the future. In particular, the Postgres contributor team at Microsoft is focused on some big architectural changes (example: Asynchronous IO) that you wouldn’t be able to do without the funding for a full-time, multi-year effort.&lt;/EM&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Highlights of our team’s Postgres 19 code contributions (so far!)&lt;/H3&gt;
&lt;P&gt;Big news: &lt;A href="https://www.postgresql.org/about/news/postgresql-19-beta-1-released-3313/" target="_blank" rel="noopener"&gt;Postgres 19 Beta 1 just released&lt;/A&gt;, and PG 19 is expected to GA later this year, likely in September 2026.&lt;/P&gt;
&lt;P&gt;Below are highlights from ~440 commits our Microsoft team authored or co-authored (so far) in Postgres 19.&lt;/P&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;And because attribution matters in open source, it must be said: the Postgres 19 work you’ll see below was done in collaboration with Postgres developers and contributors from around the world—including many outside Microsoft. That’s how the Postgres open source project works. We’re grateful to be part of it.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;Figure 2: Team members at Microsoft that contribute to the upstream Postgres open source project.&lt;/img&gt;
&lt;H3&gt;Performance&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Faster Tuple Deformation&lt;/STRONG&gt;: This work accelerates scans of tables with many fixed-width columns. The patches add a dedicated fast loop for columns at pre-calculated offsets and a smaller Attribute struct for reduced memory footprint. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c456e39113809376f6604e720910ccd24e18e034" target="_blank" rel="noopener"&gt;link to optimize tuple deformation commit&lt;/A&gt;; &lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d8a859d22b1accd8ea749394a488e4de014b2396" target="_blank" rel="noopener"&gt;link to CompactAttribute commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Fast path for Foreign Key checks: &lt;/STRONG&gt;A committed patch series that adds a faster path for foreign key checks. It avoids SPI by probing the referenced index directly, reuses execution state across trigger batches, and uses array-based index probes to reduce setup overhead. In the common case of bulk inserts into single-column, non-partitioned primary-key tables, it delivers about a 2.9x speedup. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git&amp;amp;a=search&amp;amp;h=HEAD&amp;amp;st=commit&amp;amp;s=b7b27eb" target="_blank" rel="noopener"&gt;link to commit series&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Faster COPY using SIMD for &lt;/STRONG&gt;&lt;STRONG&gt;delimiter matching&lt;/STRONG&gt;: The &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;COPY FROM&lt;/CODE&gt; text/CSV parsing was optimized by using SIMD instructions to process input data a chunk at a time, quickly skipping over bytes that don't contain special characters (delimiters, newlines, escapes) rather than checking byte-by-byte in the state machine. The performance speedups can be up to 60% in certain cases, with no regressions. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=e0a3a3fd5" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Parallel TID range scan: &lt;/STRONG&gt;The change allows for queries that filter on &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;ctid&lt;/CODE&gt; ranges to be executed by multiple parallel workers. This is particularly useful for logical replication initializers, data migration, and custom ETL scripts. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=0ca3b1697" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Improved TS counter for low-overhead EXPLAIN&lt;/STRONG&gt;&lt;STRONG&gt;: &lt;/STRONG&gt;The commit reduces the overhead of &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;EXPLAIN ANALYZE&lt;/CODE&gt; timing by using the x86 RDTSC instruction directly. This reduces pipeline stalls which dominated the timing cost and makes &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;EXPLAIN ANALYZE&lt;/CODE&gt; much faster. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=294520c44" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;On-access Visib&lt;/STRONG&gt;&lt;STRONG&gt;ility Map updates: &lt;/STRONG&gt;The change allows us to mark pages all-visible during SELECT queries. This leads to more index-only scans, which previously had to wait for a Vacuum to run, and additionally also results in less I/O needed by Vacuum. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=b46e1e54d" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Reduce Vacuum WAL generation: &lt;/STRONG&gt;A series of changes to reduce WAL generation by Vacuum and &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;COPY FREEZE&lt;/CODE&gt;. After these commits, we no longer emit separate heap visible WAL records and instead include that information in other existing WAL records, halving the number of WAL records emitted per heap block for both heap vacuuming and &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;COPY FREEZE&lt;/CODE&gt;. This makes vacuum and &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;COPY FREEZE&lt;/CODE&gt; faster and decreases disk space usage. (links to commits: &lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d96f87332b3786abd23cba47459546799c562b8c" target="_blank" rel="noopener"&gt;d96f87332b3&lt;/A&gt;, &lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=add323da40a6bf9e01cdda510e32ea924c89cd1a" target="_blank" rel="noopener"&gt;add323da40a&lt;/A&gt;, &lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=1252a4ee28636734d68f1acd33be45399c83dc53" target="_blank" rel="noopener"&gt;1252a4ee286&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;New SQL Features:&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;SQL/PGQ: &lt;/STRONG&gt;SQL Property Graph Queries is Part 16 of the SQL:2023 ISO standard which lets you define graph structures on top of your existing relational tables and query them with a dedicated pattern matching syntax. This is a major new feature, led by Peter Eisentraut along with Ashutosh Bapat from our team. In practical terms, for PostgreSQL, this means you can now express things like social network traversals, dependency graphs, fraud detection paths, or supply chain analysis using concise graph syntax without leaving Postgres, without extensions, and without duplicating your data into a separate graph store. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=2f094e7ac" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Operational Improvements:&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Automated resizing of AIO worker&lt;/STRONG&gt;&lt;STRONG&gt;s: &lt;/STRONG&gt;The patch automatically adjusts the I/O worker pool size for PostgreSQL's async I/O subsystem, replacing the old fixed &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;io_workers&lt;/CODE&gt; setting with dynamic scaling that grows the pool under load and shrinks it back down after an idle timeout—so you no longer have to guess the right static worker count. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=d1c01b79d" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;New EXPLAIN (IO) for better IO visibility: &lt;/STRONG&gt;The change introduces a new &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;IO&lt;/CODE&gt; option to &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;EXPLAIN&lt;/CODE&gt;, which adds per-scan-node I/O instrumentation to &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;EXPLAIN ANALYZE&lt;/CODE&gt; output. These apply to nodes backed by the ReadStream API’s and reports prefetch queue metrics (average and maximum distance, capacity) and I/O request stats. This gives you direct visibility into how the ReadStream/AIO layer is performing underneath each scan, instead of having to guess from BUFFERS alone. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=681daed93" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Security and Reliability:&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;CVE-2026-2006: &lt;/STRONG&gt;The change modified an internal string length function to report ERROR if the input string ends in an incomplete multibyte character. The general philosophy was to raise encoding errors on a &lt;STRONG&gt;just-in-time basis&lt;/STRONG&gt;—that is, the low-level multibyte string length functions now actively detect and reject truncated/incomplete characters rather than silently ignoring them. This hardens PostgreSQL's multibyte encoding handling, Incomplete characters in stored data are a sign of corruption or encoding bugs and surfacing them as errors is safer than silently computing wrong character counts. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=1e7fe06c10c0a8da9dd6261a6be8d405dc17c728" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Online checksum enablement: &lt;/STRONG&gt;Enabling checksums to detect data corruption was only available during initdb, or having to shut down the entire cluster and calculating the checksums on all the files. For larger production databases, that downtime is often unacceptable. This change allows you to enable this in a running cluster, and the checksums are calculated in the background. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=f19c0ecca" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Server Side SNI support:&lt;/STRONG&gt; PostgreSQL 19 &lt;A href="https://postgr.es/c/4f433025f" target="_blank" rel="noopener"&gt;adds server-side support&lt;/A&gt; for SNI, with a new configuration file $datadir/pg_hosts.conf that specifies the hostname/certificate/key pairs. The server inspects the hostname TLS extension in the SSL handshake and selects the right SSL certificate, key, and CA certificate to use for that connection. This means a single PostgreSQL instance can present different certificates depending on which hostname the client is connecting to. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=4f433025f" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Groundwork/Futures:&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Buffer Mgr Locking improvements&lt;/STRONG&gt;: Andres Freund has been working on several improvements in the way buffer management and locking has been done, paving the way to use AIO for writes. The change also now performs buffer page un-lock and un-pin in a single atomic operation, showing some pgbench runs to see up to 25% improvement.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Index Pre-fetching groundwork: &lt;/STRONG&gt;Index pre-fetching did not make it for PG19, but a lot of the groundwork has been done in this cycle, including all the major design pieces, preliminary improvements in the AIO infrastructure and mitigation of any performance regressions. The feature is in good shape to land in PG19.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Shared Buffer Elasticity groundwork: &lt;/STRONG&gt;Ashutosh and Heikki have worked on improving shared memory management in PG 19. This would help support changing shared-buffers without server restart in a future release. In PG19, extensions using small shared memory structures can be created/loaded after startup without going through &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;shared_preload_libraries&lt;/CODE&gt; and without restarting the server. (&lt;A href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=283e823f9" target="_blank" rel="noopener"&gt;link to commit&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The features above capture some highlights of the work done by the team at Microsoft for open-source PostgreSQL, but it’s not a comprehensive list—and certainly doesn’t reflect all the engineering work to review patches and mentor contributors across the project. Let’s look at some numbers:&lt;/P&gt;
&lt;H3&gt;Microsoft’s code contributions to Postgres 19 (to date) as of 31st May 2026&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;colgroup&gt;&lt;col style="width: 25%" /&gt;&lt;col style="width: 25%" /&gt;&lt;col style="width: 25%" /&gt;&lt;col style="width: 25%" /&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-align-right"&gt;&lt;STRONG&gt;Code contributions in Postgres 19&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;440&lt;/STRONG&gt;&lt;BR /&gt;Commits with Microsoft authors or co-authors&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;3,088&lt;/STRONG&gt;&lt;BR /&gt;total commits to PG19 to date (from everyone)&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;14.2%&lt;/STRONG&gt;&lt;BR /&gt;of commits have code authors from Microsoft&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-align-right"&gt;&lt;STRONG&gt;Patch Reviews in Postgres 19&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;907&lt;/STRONG&gt;&lt;BR /&gt;Commits with reviews from the Microsoft Team&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;5,603&lt;/STRONG&gt;&lt;BR /&gt;total commits to PG18 to date (from everyone)&lt;/td&gt;&lt;td class="lia-align-center"&gt;&lt;STRONG&gt;16.2%&lt;/STRONG&gt;&lt;BR /&gt;of commits had reviews from team @ Microsoft&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To interpret the numbers, here are 3 things to keep in mind:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Not all commits are created equal&lt;/STRONG&gt;. Some commits are small; others are complex and high-impact. So while commits are a useful signal, they’re not a perfect measure of effort or impact. Still, it’s a metric many people care about, so we’re sharing it.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Many commits have multiple authors (and reviewers)&lt;/STRONG&gt;: The 440 commits with Microsoft authors in Postgres 19 (as of May 31 2026) were authored by 19 different people on our team. But those commits were often co-authored by other contributors—both inside and outside Microsoft. That’s one of the things I love about the Postgres community: developers collaborating across companies, countries, and continents.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Code is just one part of the story&lt;/STRONG&gt;: Code and review contributions are essential to the Postgres project—but they’re not the whole picture. As you’ll see later in this post, our team also contributes in other ways: to extensions like &lt;A class="lia-internal-link" href="#community--1-citus" target="_blank" rel="noopener" data-lia-auto-title="Citus" data-lia-auto-title-active="0"&gt;Citus&lt;/A&gt;, and to the &lt;A class="lia-internal-link" href="#community--1-community" target="_blank" rel="noopener" data-lia-auto-title="Postgres Community" data-lia-auto-title-active="0"&gt;Postgres Community&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-citus" class="lia-anchor"&gt;&lt;/a&gt;Citus Open Source&lt;/H2&gt;
&lt;P&gt;The &lt;A href="https://github.com/citusdata/citus" target="_blank" rel="noopener"&gt;Citus open source extension&lt;/A&gt; to Postgres is a good fit for data-intensive applications that need more compute, memory, or scale than a single Postgres node can handle.&lt;/P&gt;
&lt;P&gt;With over 12.5K stars on GitHub, Citus is a popular extension that gives Postgres the superpower of distributed tables. You can download Citus open source, or you can use Citus on Azure via the &lt;A href="https://learn.microsoft.com/azure/postgresql/elastic-clusters/concepts-elastic-clusters" target="_blank" rel="noopener"&gt;Elastic Clusters feature&lt;/A&gt; in Azure Database for PostgreSQL.&lt;/P&gt;
&lt;H3&gt;New Citus open source features in last 13 months&lt;/H3&gt;
&lt;P&gt;The Citus open source extension scales out Postgres horizontally, using either row-based sharding or schema-based sharding, or both.&lt;/P&gt;
&lt;P&gt;The &lt;A href="https://www.citusdata.com/updates/" target="_blank" rel="noopener"&gt;Release Notes pages for Citus&lt;/A&gt; are online—and for Citus major releases you can often find a dedicated blog post as well:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Mehmet Yilmaz’s release blog post titled, &lt;A href="https://www.citusdata.com/blog/2026/02/17/distribute-postgresql-18-with-citus-14/" target="_blank" rel="noopener"&gt;Distribute PostgreSQL 18 with Citus 14&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Check out the &lt;A href="https://www.citusdata.com/updates/v14-0/" target="_blank" rel="noopener"&gt;Citus 14.0 release notes&lt;/A&gt; that added PG18 support&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Here are highlights of new Citus open source capabilities added in the last 13 months:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Citus 13.2, 14.0, and 14.1 releases&lt;/STRONG&gt;: You can find the release notes online for &lt;A href="https://www.citusdata.com/updates/v13-2/" target="_blank" rel="noopener"&gt;Citus 13.2&lt;/A&gt;, &lt;A href="https://www.citusdata.com/updates/v14-0/" target="_blank" rel="noopener"&gt;Citus 14.0&lt;/A&gt;, and for the latest release which is actually two paired minor releases, &lt;A href="https://www.citusdata.com/updates/v14-1/" target="_blank" rel="noopener"&gt;Citus 14.1/13.3&lt;/A&gt;.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Postgres 18 support in Citus&lt;/STRONG&gt; &lt;STRONG&gt;14&lt;/STRONG&gt;: Citus 14 primarily about PG18 compatibility, with upstream benefits like faster scans and maintenance via AIO; better index usage with skip-scan; uuidv7() for time-ordered UUIDs; OAuth authentication support; and temporal constraints flowing through once compatibility lands. (&lt;A href="https://www.citusdata.com/updates/v14-0/#pg18-highlights" target="_blank" rel="noopener"&gt;link to Citus 14.0 release notes&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Snapshot-based node split / faster scale-out&lt;/STRONG&gt;: From the release notes, “the snapshot based node-addition feature enables faster scale-out operations by adding a new worker node using a clone of an existing worker node. This significantly reduces rebalance times when adding new nodes to the cluster.” Why? Because the cloned work already contains a copy of the data. (&lt;A href="https://www.citusdata.com/updates/v13-2/#snapshot_based_node_addition" target="_blank" rel="noopener"&gt;link to release notes&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Faster parallel shard rebalancing&lt;/STRONG&gt;: Citus 13.2 explicitly improved rebalancer performance by parallelizing moves and removing logical-replication bottlenecks. (&lt;A href="https://www.citusdata.com/updates/v13-2/#shard_rebalancing_performance" target="_blank" rel="noopener"&gt;link to release notes&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;New Citus observability views/stats&lt;/STRONG&gt;: Citus added new observability views and user-defined functions (UDFs) for distributed clusters. Citus 13.1 introduced &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;citus_stat_counters&lt;/CODE&gt; to expose Citus-specific counters collected when &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;citus.enable_stat_counters&lt;/CODE&gt; is enabled; and 13.1 also introduced &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;citus_nodes&lt;/CODE&gt; to show node name, port, role, and active status, as well as supporting UDFs to query/reset counters and identify whether the current node is primary. &lt;BR /&gt;&lt;BR /&gt;Citus 13.2 added &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;citus_stats()&lt;/CODE&gt;, which retrieves distributed &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;pg_stats&lt;/CODE&gt; for a Citus table, giving users more cluster-level visibility into statistics and node state. (&lt;A href="https://www.citusdata.com/updates/v13-1/#css_section" target="_blank" rel="noopener"&gt;link to citus stat counters&lt;/A&gt; in release notes; &lt;A href="https://www.citusdata.com/updates/v13-1/#citus_nodes_section" target="_blank" rel="noopener"&gt;link to citus nodes view&lt;/A&gt; in release notes; &lt;A href="https://www.citusdata.com/updates/v13-2/#citus_stats" target="_blank" rel="noopener"&gt;link to citus_stats view&lt;/A&gt; in release notes)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Expanded DDL/role propagation&lt;/STRONG&gt;: Citus 13.1 adds support for propagating more DDLS from the coordinator to ease role and database management in a Citus cluster, including support for: GRANT/REVOKE rights on table columns; REASSIGN OWNED BY commands; CREATE/DROP database commands; SECURITY LABEL on tables and columns; ALTER USER RENAME commands; ALTER DATABASE .. SET .. commands; and role management from worker nodes. (&lt;A href="https://www.citusdata.com/updates/v13-1/#propagation_of_more_ddls_section" target="_blank" rel="noopener"&gt;link to Citus 13.1 release notes&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Planner/query performance improvements&lt;/STRONG&gt;: Citus 13.2 includes outer join pushdown and local fast-path query optimization. (link to &lt;A href="https://www.citusdata.com/updates/v13-2/#outer_join_pushdown" target="_blank" rel="noopener"&gt;outer join pushdown&lt;/A&gt; in release notes; &lt;A href="https://www.citusdata.com/updates/v13-2/#delayed_fast_path_planning" target="_blank" rel="noopener"&gt;link to fast-path query optimization&lt;/A&gt; in release notes)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 class="lia-linked-item"&gt;&lt;a id="community--1-community" class="lia-anchor"&gt;&lt;/a&gt;Postgres Community work&lt;/H2&gt;
&lt;P&gt;Given my role as head of Postgres open source community initiatives at Microsoft, it’s not a surprise: contributing to Postgres is something I care deeply about. &lt;BR /&gt;&lt;BR /&gt;Last year, I gave a talk at &lt;A href="https://speakerdeck.com/clairegiordano/behind-postgres-18-the-people-the-code-and-the-invisible-work-claire-giordano-pgconfeu-2025" target="_blank" rel="noopener"&gt;PGConf EU that shared an analysis of contributions&lt;/A&gt; to Postgres v18, based on research I did with Daniel Gustafsson. And if you’ve ever raced sailboats, you know: &lt;EM&gt;every role matters&lt;/EM&gt;. &lt;BR /&gt;&lt;BR /&gt;One thing I’m quite proud of are the different ways the team at Microsoft contributes to the Postgres ecosystem. This Postgres Contributions infographic—inspired by a hand-drawn sketch by Cornelia Biacsics—shines a light on the ways we’re contributing to this ecosystem.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;&lt;STRONG&gt;Figure 3&lt;/STRONG&gt;: Infographic of the 8 different ways the team at Microsoft contributes to the Postgres ecosystem, from our Azure managed services to Postgres open-source community contributions.&lt;/P&gt;
&lt;/img&gt;
&lt;H3&gt;Highlights from the Postgres community work done by our team at Microsoft&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Serve on organizing &amp;amp; talk selection teams for multiple Postgres events&lt;/STRONG&gt;: The in-person Postgres community conferences are a great way to learn, share your expertise, and connect with other Postgres people. And if you lean into the “hallway track”, you might be surprised by the doors it can open. &lt;BR /&gt;&lt;BR /&gt;Over the past 13 months, members of our Postgres team at Microsoft have served on the organizing committees or talk selection teams for these 9 Postgres community conferences, in time-order (oldest to most recent):&lt;BR /&gt;&lt;BR /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf.dev 2025 &lt;/STRONG&gt;(Melanie Plageman)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf NYC 2025 &lt;/STRONG&gt;(Daniel Gustafsson)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL Down Under (PGDU) 2025 &lt;/STRONG&gt;(Thomas Munro)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Prague PostgreSQL Developers Day (P2D2) 2026 &lt;/STRONG&gt;(Tomas Vondra)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;FOSSASIA PGDay 2026 &lt;/STRONG&gt;(Amit Langote)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf India 2026 &lt;/STRONG&gt;(Thomas Munro)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Nordic PGDay 2026 &lt;/STRONG&gt;(Daniel Gustafsson)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL Conference Germany 2026 &lt;/STRONG&gt;(Cornelia Biacsics)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf.dev 2026 &lt;/STRONG&gt;(Melanie Plageman, Claire Giordano)&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Co-organize PGConf.dev annual PostgreSQL development conference&lt;/STRONG&gt;: Special shout-out to Melanie Plageman, who is part of the team that organizes PGconf.dev, which in the last 3 years has become a “go to” event. This annual gathering (the successor to PGCon) is unique in how it brings together current and future PostgreSQL hackers from around the world to collaborate in person. (&lt;A href="https://2026.pgconf.dev/schedule/tuesday" target="_blank" rel="noopener"&gt;link to PGConfdev 2026 schedule&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Sponsor 17 Postgres conferences around the world&lt;/STRONG&gt;: Postgres community conferences don’t just happen—they rely on financial support to bring people together. Over the past ~13 months, our team at Microsoft has sponsored these 17 in-person Postgres events:&lt;BR /&gt;&lt;BR /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf.dev 2025 – &lt;/STRONG&gt;Gold&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;Hyderabad PG Days 2025 –&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; Sponsor&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGDay Austria 2025 &lt;/STRONG&gt;- Silver&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGDay UK 2025&lt;/STRONG&gt; – Benefactor&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGDay Lowlands 2025&lt;/STRONG&gt; – Supporter&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGDay Napoli 2025 &lt;/STRONG&gt;– Supporter&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf NYC 2025 &lt;/STRONG&gt;– Platinum&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf EU 2025 in Riga &lt;/STRONG&gt;– Gold&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PG Down Under 2025 &lt;/STRONG&gt;– Silver&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Prague PostgreSQL Developers Day (P2D2) 2026 &lt;/STRONG&gt;– Bronze&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;FOSSASIA PGDay 2026 &lt;/STRONG&gt;- Silver&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf India 2026 &lt;/STRONG&gt;– Diamond&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Nordic PGDay 2026 &lt;/STRONG&gt;– Supporter&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL Conference Germany 2026&lt;/STRONG&gt; – Silver&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGConf.dev 2026&lt;/STRONG&gt; – Gold&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PG DATA 2026 (formerly PGDay Chicago) &lt;/STRONG&gt;– Gold&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PGDay Boston 2026&lt;/STRONG&gt; – Silver&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;Figure 4: Logos of the PostgreSQL community conferences our Microsoft team is proud to have sponsored over the last 13 months—along with thanks and gratitude to the conference organizers for making these events happen.&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;POSETTE: An Event for Postgres&lt;/STRONG&gt;: POSETTE is a free &amp;amp; virtual developer conference organized by our Postgres team at Microsoft. Now in its 5&lt;SUP&gt;th&lt;/SUP&gt; year, and aided by the fact that it’s virtual, it’s safe to say POSETTE is the largest Postgres event in the world—bringing together developers, users, contributors, and experts from across the globe to share their knowledge. (&lt;A href="https://posetteconf.com/2026/" target="_blank" rel="noopener"&gt;link to PosetteConf.com&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;Last year’s event in June 2025 was a hit—and you can still watch all of last year’s talks on the &lt;A href="https://aka.ms/posette-playlist-2025" target="_blank" rel="noopener"&gt;POSETTE 2025 playlist&lt;/A&gt; on YouTube. &lt;BR /&gt;&lt;BR /&gt;Special thanks to my teammates on the 2026 talk selection team—Daniel Gustafsson, Divya Bhargov, and Melanie Plageman—for reviewing all 238 of this year’s talk proposals. And of course POSETTE 2026 would not be happening without the full &lt;A href="https://posetteconf.com/2026/about/#organizing-team" target="_blank" rel="noopener"&gt;organizing team behind POSETTE 2026&lt;/A&gt;, nor without the partnership and financial support from AMD.&lt;BR /&gt;&lt;BR /&gt;Looking ahead, POSETTE 2026 is coming up soon: 16-18 Jun, online. With 4 livestreams, 2 keynotes, 44 talks, and &lt;A href="https://posetteconf.com/2026/speakers/" target="_blank" rel="noopener"&gt;50 speakers&lt;/A&gt;, there’s something for everyone.
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;Check out the schedule &lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;on the &lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;&lt;A href="https://posetteconf.com/2026/schedule/" target="_blank" rel="noopener"&gt;PosetteConf website&lt;/A&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Register&lt;/STRONG&gt;: To make sure you don’t get doublebooked, register for the POSETTE 2026 livestream(s) that works for you:
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://developer.microsoft.com/reactor/events/26853/" target="_blank" rel="noopener"&gt;Livestream 1&lt;/A&gt; / &lt;A href="https://developer.microsoft.com/reactor/events/26854/" target="_blank" rel="noopener"&gt;Livestream 2&lt;/A&gt; / &lt;A href="https://developer.microsoft.com/reactor/events/26855/" target="_blank" rel="noopener"&gt;Livestream 3&lt;/A&gt; / &lt;A href="https://developer.microsoft.com/reactor/events/26856/" target="_blank" rel="noopener"&gt;Livestream 4&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;If you attend live, the benefit is:&lt;/STRONG&gt; you’ll be able to ask the speakers questions &lt;A href="https://aka.ms/open-source-discord" target="_blank" rel="noopener"&gt;in the text chat on Discord&lt;/A&gt; while the talks are being livestreamed—and be part of the conversation. It’s a good way to connect with the speakers and the community.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Can’t make it live? No problem&lt;/STRONG&gt;, you can always catch the 2026 talks later on YouTube.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;&lt;STRONG&gt;Figure 5:&lt;/STRONG&gt; POSETTE: An Event for Postgres 2026 is a free and virtual developer event, organized by our Postgres team at Microsoft and now in its 5&lt;SUP&gt;th&lt;/SUP&gt; year. This graphic gives you a map of the 44 talks in POSETTE 2026, from the keynotes to the Postgres core talks, Postgres ecosystem talks, and Azure Database talks too.&lt;/P&gt;
&lt;/img&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Talking Postgres podcast: &lt;/STRONG&gt;Hard to believe, but our monthly podcast is now over 3 years old—with 39 episodes published as of the date of writing. Focused on the human side of Postgres, the conversations dig into why people who work with Postgres do what they do—and how they got to where they are. (&lt;A href="https://talkingpostgres.com/" target="_blank" rel="noopener"&gt;link to podcast&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;In the past year alone, I’ve had the chance to talk with these amazing people: Adam Prout, Andres Freund, Boriss Mejías, Charles Feddersen, Gwen Shapira, Melanie Plageman, Rob Emanuele, Shireesh Thota, Simon Willison, Tomas Vondra, Luigi Nardi, Peter Cooper, and Peter Farkas.&lt;BR /&gt;&lt;BR /&gt;You can find all episodes at &lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://talkingpostgres.com/" target="_blank" rel="noopener"&gt;Talking Postgres.com&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, on the &lt;/SPAN&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://aka.ms/TalkingPostgres-playlist" target="_blank" rel="noopener"&gt;YouTube playlist&lt;/A&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;, or wherever you get your podcasts. Bonus: we record episodes &lt;/SPAN&gt;&lt;EM style="color: rgb(30, 30, 30);"&gt;live&lt;/EM&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt; on the Microsoft Open Source Discord, where you can join the parallel live text chat during the show. It’s a fun way to connect with the community in real time.&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deliver 63 conference talks at Postgres events&lt;/STRONG&gt;: Both in-person and virtually, our Postgres teams have been sharing their expertise with the user and developer community on the conference circuit—delivering 63 talks in the last 13 months.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Organize Postgres user groups &amp;amp; meetups&lt;/STRONG&gt;: User groups and meetups are a great way to learn and meet other Postgres users and contributors—but it takes work to make it all happen: to find locations, line up speakers, organize food and drink, and get the word out. &lt;BR /&gt;&lt;BR /&gt;+1 to those on our team at Microsoft—and to everyone—who volunteer their time and partner with others in the Postgres community to help organize local Postgres user groups, including:&lt;BR /&gt;&lt;BR /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Malmö PostgreSQL User Group (M-PUG)&lt;/STRONG&gt;: Daniel Gustafsson (&lt;A href="https://www.meetup.com/malmo-postgresql-user-group-m-pug/" target="_blank" rel="noopener"&gt;link to meetup&lt;/A&gt;)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Prague PostgreSQL Meetup:&lt;/STRONG&gt; Tomas Vondra (&lt;A href="https://www.meetup.com/prague-postgresql-meetup/" target="_blank" rel="noopener"&gt;link to meetup&lt;/A&gt;)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL User Group Vienna&lt;/STRONG&gt;: Cornelia Biacsics (&lt;A href="https://www.meetup.com/postgresql-user-group-vienna/" target="_blank" rel="noopener"&gt;link to meetup&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Hosting local meetups at Microsoft&lt;/STRONG&gt;: Shout-out to the people involved in making Microsoft offices available as venues for local Postgres meetups, including:&lt;BR /&gt;&lt;BR /&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Postgres Bangalore (PGBLR) Meetup&lt;/STRONG&gt;: hosted at the Microsoft office in Feb 2026 (&lt;A href="https://www.linkedin.com/posts/nitin-jadhav-b4807950_what-an-incredible-postgres-bangalore-ugcPost-7427227964427182081-FTzs/" target="_blank" rel="noopener"&gt;post by Nitin Jadhav about the meetup&lt;/A&gt;)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Barcelona (+Valencia) PostgreSQL User Group&lt;/STRONG&gt;: hosted at the Microsoft office in Oct 2025 (&lt;A href="https://www.meetup.com/barcelona-postgresql-meetup-group/events/311165188/" target="_blank" rel="noopener"&gt;link to meeting #4 at Microsoft&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG style="color: rgb(30, 30, 30);"&gt;Serve on Postgres core team, project committees, &amp;amp; PGCA Board of Directors&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);"&gt;: Every open source project needs governance, and there are many teams and efforts that comprise the project beyond code. Shout-out to:&lt;BR /&gt;&lt;/SPAN&gt;
&lt;UL&gt;
&lt;LI&gt;Andres Freund from Microsoft serves on the &lt;STRONG&gt;PostgreSQL Core Team.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Melanie Plageman serves on the &lt;STRONG&gt;PostgreSQL Contributors committee&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Noah Misch and Andres Freund serve on the &lt;STRONG&gt;PostgreSQL Security team&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Claire Giordano serves on the board of directors for the &lt;STRONG&gt;PostgreSQL Community Association (PGCA) non-profit&lt;/STRONG&gt;, an organization that stewards the PostgreSQL brand assets including trademarks and domain names. (&lt;A href="https://www.postgresql.org/about/governance/" target="_blank" rel="noopener"&gt;link to PostgreSQL governance&lt;/A&gt; / &lt;A href="https://www.postgres.ca/" target="_blank" rel="noopener"&gt;link to PGCA non-profit&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Benefactor sponsor of PostgreSQL Community Association (PGCA) non-profit: &lt;/STRONG&gt;As of May 2026, Microsoft is a Benefactor sponsor of the PGCA non-profit and the PostgreSQL project, providing financial support to protect the PostgreSQL project’s trademarks and brand assets. (&lt;A href="https://www.postgres.ca/" target="_blank" rel="noopener"&gt;link to PGCA non-profit website&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;PostgreSQL developer meetings&lt;/STRONG&gt;: Twice a year the developer community hosts invitation-only summits—typically coinciding with FOSDEM PGDay and PGConf.dev—to discuss “wicked problems”, technical issues, or development processes that are not easily addressed over email. Members of our Postgres contributor team have a seat at this table.&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Blogging&lt;/STRONG&gt;: The blog platform where our Postgres team has been publishing the most in the last year—with 99 new posts—is on Microsoft Tech Community. Blogging continues to be a super useful way to share information—and when I’m researching something at 2AM, I’m definitely appreciative of all the Postgres people who take time to share information via blog! (link to the &lt;A href="https://aka.ms/microsoft-blog-postgres" target="_blank" rel="noopener"&gt;Microsoft Blog for PostgreSQL&lt;/A&gt;)&lt;BR /&gt;&lt;BR /&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Contribute to Patroni 4.0.x and 4.1.x&lt;/STRONG&gt;: Patroni is a popular High Availability (HA) solution for Postgres. It helps you deploy, manage, and monitor HA clusters using streaming replication—and it’s open source. Alexander Kukushkin from our team is the technical lead and collaborates with engineers from different companies on Patroni. &lt;BR /&gt;&lt;BR /&gt;In the last 13 months, Patroni added Postgres 18 support as well as support for &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;patronictl demote-cluster&lt;/CODE&gt; and &lt;CODE style="color: #000; background: #f1f1f1; border-radius: 2px; padding: 1px 3px; display: inline-block;"&gt;patronictl promote-cluster&lt;/CODE&gt; which automate switching of a Patroni cluster between primary and standby cluster roles. &lt;BR /&gt;&lt;BR /&gt;I started to include individual release notes links for the last 13 months but there were too many to list: 5 minor releases and 1 new major release. (&lt;A href="https://patroni.readthedocs.io/en/latest/releases.html#release-notes" target="_blank" rel="noopener"&gt;link to Patroni release notes&lt;/A&gt;)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Microsoft ❤️ Postgres&lt;/H2&gt;
&lt;P&gt;For the 4&lt;SUP&gt;th&lt;/SUP&gt; year in a row, this blog post is a snapshot of the work our Postgres team at Microsoft has done over the last year. There are too many contributors to name—but without their efforts, this post would not exist.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P&gt;As I wrap-up, I’m struck by just how many ways the team at Microsoft shows up for Postgres. We run a managed Postgres service on Azure—and in the past year, we’ve launched a new Postgres extension for VS Code as well as a new Postgres database service called Azure HorizonDB (in Preview). We contribute upstream to the PostgreSQL project with code, architecture, reviews, testing, extensions, volunteering in the community, organizing user groups, and more. We maintain open source projects like Citus and Patroni. To share expertise, we write blog posts and give talks. We sponsor and help organize conferences—including POSETTE, the world’s largest virtual event for Postgres. And yes, we even produce a monthly podcast.&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;And the infographic that pulls it all together? I think it's a work of art.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;
&lt;P class="lia-align-center"&gt;********************&lt;/P&gt;
&lt;H3&gt;Acknowledgements&lt;/H3&gt;
&lt;P&gt;In addition to significant contributions by this blog post’s co-authors Guy Bowerman (Azure Database for PostgreSQL chapter) and Sumedh Pathak (PostgreSQL core chapter), many thanks to people who contributed to this year’s blog post: Abe Omorogbe, Brian Holt, Denzil Ribeiro, Dingding Lu, Isaac Alves, My Nguyen, Shreya Aithal, and Silvano Coriani. I could not have pulled this together alone: thank you!&lt;/P&gt;</description>
      <pubDate>Tue, 04 Aug 2026 18:31:29 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/what-s-new-with-postgres-at-microsoft-2026-edition/ba-p/4526963</guid>
      <dc:creator>clairegiordano</dc:creator>
      <dc:date>2026-08-04T18:31:29Z</dc:date>
    </item>
    <item>
      <title>Introducing Durable Functions in PostgreSQL</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/introducing-durable-functions-in-postgresql/ba-p/4526821</link>
      <description>&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph" data-ccp-parastyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;276295ed-5df2-5456-988c-5fdbab071054|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Aptos&amp;quot;,469777842,&amp;quot;Arial&amp;quot;,469777843,&amp;quot;游明朝&amp;quot;,469777844,&amp;quot;Aptos&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Aptos,Arial,游明朝&amp;quot;,268442635,&amp;quot;24&amp;quot;,335559739,&amp;quot;180&amp;quot;,335559738,&amp;quot;180&amp;quot;,469775450,&amp;quot;First Paragraph&amp;quot;,201340122,&amp;quot;2&amp;quot;,134234082,&amp;quot;true&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;FirstParagraph&amp;quot;,335572020,&amp;quot;1&amp;quot;,469775498,&amp;quot;Body Text&amp;quot;,469778324,&amp;quot;Body Text&amp;quot;]}"&gt;By Abe Omorogbe, Senior PM |&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&amp;nbsp;Pino De Can&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;dia, Principal Software Engineer | TJ Green, Principal Software Engineer&lt;BR /&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Postgres will happily store your data, run your queries, and scale with you for years. But the moment you need to do more with that data, such as running multi-step transformation, scheduling nightly rollups, generating embeddings or waiting on an approval&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; you hit a wall. Postgres has no built-in way to run long-lived, fault-tolerant work.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;That's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; why we built&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;, &lt;/SPAN&gt;&lt;/SPAN&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; new &lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;open-source PostgreSQL extension&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;that brings &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; execution&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; directly into the database.&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;With &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, Postgres &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;doesn’t&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; just &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;store your &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;data,&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;it runs long-lived, fault-tolerant workflows on it, with built-in retries, parallelism, scheduling, and recovery. Instead of stitching together PL/&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pgSQL&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; functions or building external &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;orchestration&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; systems, you can now define and&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;run resilient workflows entirely in your database&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, backed by Postgres' durability and high availability.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;And on&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://aka.ms/AzureHorizonDB" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Azure HorizonDB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;also &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;powers &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI pipelines&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;enabling &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;production-ready &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;data and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;w&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;orkflows&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;end-to-end&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; right inside the database.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;In this post, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;we'll&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; cover:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact" data-ccp-parastyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;eafb41c0-47a4-52dc-ac6b-3b5a7536b560|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Aptos&amp;quot;,469777842,&amp;quot;Arial&amp;quot;,469777843,&amp;quot;游明朝&amp;quot;,469777844,&amp;quot;Aptos&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Aptos,Arial,游明朝&amp;quot;,268442635,&amp;quot;24&amp;quot;,335559739,&amp;quot;36&amp;quot;,335559738,&amp;quot;36&amp;quot;,469775450,&amp;quot;Compact&amp;quot;,201340122,&amp;quot;2&amp;quot;,134234082,&amp;quot;true&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;Compact&amp;quot;,335572020,&amp;quot;1&amp;quot;,469778324,&amp;quot;Body Text&amp;quot;]}"&gt;The hidden trap: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;blocking background work&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;What&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; is &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;and&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;DSL&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; that drives it&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;How&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;this &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;engine powers &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;AI &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;ipelines&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; on &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Sample patterns worth exploring&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Getting started on&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;, on your laptop, and in VS Code&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;🚀 &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;&lt;STRONG&gt;Want to try it out?&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; ships in &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;,&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; Microsoft's new PostgreSQL cloud service. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;The &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt; Preview is the fastest way to try&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;pg_durable&lt;/SPAN&gt;&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;&lt;STRONG&gt;AI pipelines&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;together&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Block Text"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Get started in HorizonDB →&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:480,&amp;quot;335559738&amp;quot;:100,&amp;quot;335559739&amp;quot;:100}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Figure 1: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; visualization&lt;/SPAN&gt;&lt;/img&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;The &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;hidden &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;trap: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;blocking background work&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Most Postgres teams eventually reach a point where &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;they need to run &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;critical tasks &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;on&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; their data: transformations, nightly aggregations,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; database maintenance workflows,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&amp;nbsp;embedding jobs, or multi-step business processes. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;So,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; they do the natural thing and try to keep that work inside Postgres.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Th&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;ey&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; end up on a journey of increasing complexity and maintenance burden&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;First,&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;just run the task as a function in your database&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;You cram the whole workflow into one PL/&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pgSQL&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; function: loop, transform, call APIs, write results, return. It looks &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;simple&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; until you &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;have to&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; run it in production. One connection &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;stays&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; tied up the whole time. Everything runs inside one big transaction, with long locks and no visibility into partial progress. If the connection drops or the database restarts, the whole run is gone. No per-step retries. No parallelism. No scheduling. No clean way to &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pause for&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; human input.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;When it fails,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; you move it outside&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;You push the workflow into an external service: a job queue, polling workers, state tables, step coordination, retry logic, crash-recovery sweeps, and cleanup jobs. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;What started as a few background tasks turns into a full distributed system. Before &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you’ve&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; even touched the business logic, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you’re&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; building and operating infrastructure just to coordinate work &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;that’s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; still fundamentally tied to your data.&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Both &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;paths &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;are workarounds for the same missing primitive&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;: &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;durable,&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;asynchronous &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;background work&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; that lives where your data lives.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;That's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; the gap &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; fills.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;What &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;pg_durable&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 2"&gt;actually is&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph" data-ccp-parastyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;276295ed-5df2-5456-988c-5fdbab071054|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Aptos&amp;quot;,469777842,&amp;quot;Arial&amp;quot;,469777843,&amp;quot;游明朝&amp;quot;,469777844,&amp;quot;Aptos&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Aptos,Arial,游明朝&amp;quot;,268442635,&amp;quot;24&amp;quot;,335559739,&amp;quot;180&amp;quot;,335559738,&amp;quot;180&amp;quot;,469775450,&amp;quot;First Paragraph&amp;quot;,201340122,&amp;quot;2&amp;quot;,134234082,&amp;quot;true&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;FirstParagraph&amp;quot;,335572020,&amp;quot;1&amp;quot;,469775498,&amp;quot;Body Text&amp;quot;,469778324,&amp;quot;Body Text&amp;quot;]}"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; is a&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; Postgres extension that consists of a DSL (Domain specific language) and the &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/duroxide" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;duroxide runtime&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; hosted in a &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Postgres&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; background worker&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;.&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; You describe a workflow as a small SQL expression, call &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;df.start&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;(...)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, and get an instance ID back &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;immediately&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;. The work runs off to the side in a background worker, so it never blocks your connection or transaction, and you can check progress later with &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;df.status&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;df.result&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;. The execution state lives in Postgres, which means it &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;benefits&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; from the database’s durability, HA, backups, and recovery&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;. Additionally, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;the workflow definition does not have to live in the database&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;:&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;your application can send it to &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;df.start&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;(...)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; over a regular Postgres connection.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Figure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;2&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; orch&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;estra&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;tion of worker and schema&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/img&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Because execution is asynchronous, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; automatically breaks a workflow into discrete steps. Each step runs in its own session and transaction, commits its progress, and hands off to the next instead of keeping one giant transaction open. Steps are checkpointed in Postgres and recovered by deterministic replay, so workflows survive crashes, restarts, and failovers and resume where they left off. If a step fails, only &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;that&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; step retries.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;The whole thing is expressed through a tiny DSL of composable operators:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 89.2593%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Operator&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Meaning&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char" data-ccp-charstyle-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;a31b87fc-7929-525d-a968-aa0f568a0536|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Consolas&amp;quot;,469777842,&amp;quot;Arial&amp;quot;,469777843,&amp;quot;游明朝&amp;quot;,469777844,&amp;quot;Consolas&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Consolas&amp;quot;,268442635,&amp;quot;22&amp;quot;,469775450,&amp;quot;Verbatim Char&amp;quot;,201340122,&amp;quot;1&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;VerbatimChar&amp;quot;,335572020,&amp;quot;1&amp;quot;,134231262,&amp;quot;true&amp;quot;,469777929,&amp;quot;Source Code&amp;quot;,469778324,&amp;quot;Caption Char&amp;quot;]}" data-ccp-charstyle-linked-defn="{&amp;quot;ObjectId&amp;quot;:&amp;quot;94116779-72d8-55e3-836f-dfb3e4f6a90b|1&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[201342446,&amp;quot;1&amp;quot;,201342447,&amp;quot;5&amp;quot;,201342448,&amp;quot;3&amp;quot;,201342449,&amp;quot;1&amp;quot;,469777841,&amp;quot;Aptos&amp;quot;,469777842,&amp;quot;Arial&amp;quot;,469777843,&amp;quot;游明朝&amp;quot;,469777844,&amp;quot;Aptos&amp;quot;,201341986,&amp;quot;1&amp;quot;,469769226,&amp;quot;Aptos,Arial,游明朝&amp;quot;,268442635,&amp;quot;24&amp;quot;,469775450,&amp;quot;Source Code&amp;quot;,201340122,&amp;quot;2&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;SourceCode&amp;quot;,335572020,&amp;quot;1&amp;quot;,335557856,&amp;quot;16316664&amp;quot;,469777929,&amp;quot;Verbatim Char&amp;quot;,469778324,&amp;quot;Normal&amp;quot;]}"&gt;~&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Sequential&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;run this, then that&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;&amp;amp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Parallel&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;fan out, wait for &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;all&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;|&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Race&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;fan out, take the &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;first&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; to finish&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;?&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; / &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;!&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Conditional&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;.&amp;nbsp;&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Compact"&gt;if / else&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;@&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Loop. repeat durably, survive restarts&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;|=&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Capture a step's result into a variable (reuse with &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;$&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Advanced Functions&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.if&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Conditional branch&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.loop&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Repeat &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;statements&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.join&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Execute in parallel, wait for all&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.http&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;To call an allowlisted endpoint&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.wait_for_schedule&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;For &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;cron&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;-style timing&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;df.wait_for_signal&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Pause for an external event&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&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;&lt;SPAN data-contrast="auto"&gt;Read more about &lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/blob/main/USER_GUIDE.md#key-features" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;all operators and functions in pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt; &lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 32px;" data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Without&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; vs. with &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 32px;" 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;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The hand-rolled version of &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;"run three aggregations in parallel, then refresh a dashboard with retries and crash recovery"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; usually means 300+ lines of queue tables, polling workers, state-machine rows, per-step retry logic, crash-recovery sweeps, and cleanup jobs. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Plus,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; the runbook &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;to operate&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; it.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; version&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT df.start( 
    'SELECT count(*) FROM users' 
  &amp;amp; 'SELECT count(*) FROM orders' 
  &amp;amp; 'SELECT sum(amount) FROM orders' 
  ~&amp;gt; 'REFRESH MATERIALIZED VIEW metrics', 
    'refresh-dashboard' 
); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;You write&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;the SQL&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; owns the queue, the state, the coordination, the retries, and the crash recovery.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Two ways to use &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;pg_&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;durable&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;/H2&gt;
&lt;H3 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;1&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;:&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="heading 3"&gt;Use &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; directly (works on &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; or &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;any Postgres 17)&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="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Enable it and start orchestrating:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;CREATE EXTENSION pg_durable; 
 
SELECT df.start($$ SELECT 'Hello, durable world!' AS message $$); 
-- returns an instance ID immediately; the worker runs it asynchronously &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;From there you compose: sequential pipelines, conditional branches, races for timeout-or-result, variable passing between steps, human-in-the-loop approvals, scheduled maintenance all in SQL, close to the data, with no new infrastructure. This is the "just use Postgres" answer to a problem teams usually solve by&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;leaving&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; Postgres.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Because &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;it's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; open source under the permissive PostgreSQL License, you can clone the repo and run it on your laptop, your server, or any cloud.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;2&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;: &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;AI pipelines (&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; capability&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;)&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="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;On &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; becomes the foundation for something even more approachable: a managed, declarative&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; &lt;STRONG&gt;AI pipeline&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;surface in the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;azure_ai&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; extension. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; gives you the durable execution engine, while the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;ai.*&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; API gives you an AI-shaped model of sources, steps, sinks, and triggers that compile &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;into a &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;durable graph.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Traditional app-tier embedding pipelines fail in predictable ways: a transient API error mid-batch with no shared checkpoint&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;a worker that crashes after writing chunks but before marking the parent row processed&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; no clean way to re-embed just the rows that changed.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Move that logic into &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; and the source, the steps, the sink, and the run history are all SQL&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;protected by the same transactions, backups, and PITR&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; (point-in-time recovery) &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;your data already has.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;A complete chunk → embed &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;AI &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pipeline is one definition:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT ai.create_pipeline( 
    name   =&amp;gt; 'ai_pipeline', 
    source =&amp;gt; ai.table_source(table_name =&amp;gt; 'documents_ai_pipeline'), 
    steps  =&amp;gt; ARRAY[ 
        ai.chunk(input =&amp;gt; 'content'), 
        ai.embed(model =&amp;gt; 'default-embedding', input =&amp;gt; 'chunk_text', dimensions =&amp;gt; 1536) 
    ], 
    trigger =&amp;gt; 'on_change', 
    sink    =&amp;gt; ai.table_sink('documents_ai_pipeline_output') 
); 
 
SELECT ai.run('ai_pipeline'); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Each AI step becomes a durable node, so if &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.embed&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; fails, &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;ai.chunk&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;doesn’t&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; run again. And with &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;trigger =&amp;gt; '&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;on_change&lt;/SPAN&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;'&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, the pipeline runs automatically as rows change, embedding only &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;what’s&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; new.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Add a &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/ai/vector-index-diskann" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;DiskANN&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt; index&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; on the resulting table, and you have &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;production-ready &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;vector search end to end, entirely inside the database.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Where &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt; fits and where it &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;doesn't&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;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;If &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;you've&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; used&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; external &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;orchestrators&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; such as&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; Temporal or Airflow, your first reaction is probably: &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;why would I put control flow in my database?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;EM&gt; &lt;/EM&gt;Fair question. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;pg_durable&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;isn't&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; trying to be a universal orchestrator.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Reach for &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; when&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; the workflow is &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;tightly coupled to Postgres state&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; T&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;he rows it reads and writes live in the same &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;database,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; it &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;benefits&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; from the database's own durability, backups, and PITR, and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you'd&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; rather not stand up a separate system to coordinate work that never leaves the data tier. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Think: e&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;mbedding pipelines, ETL &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;job&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;s, scheduled &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;maintenance,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; and &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;queue-style background jobs.&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Reach for a dedicated orchestrator&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;when the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;workflow's&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; center of gravity is &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;outside&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; Postgres&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; fanning across heterogeneous services, or &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;running&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;arbitrary application logic that does not map cleanly to SQL steps, branching, loops, or HTTP calls.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Get started&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; &lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;" data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;On Azure &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;HorizonDB&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;" 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;/H2&gt;
&lt;LI-CODE lang="sql"&gt;CREATE EXTENSION IF NOT EXISTS pg_durable; 
 
-- Execute a simple SQL query as a durable function 
SELECT df.start($$ SELECT 'Hello, durable world!' AS message $$); 
-- Returns: a1b2c3d4 (8-character instance ID) 
 
-- Get result of a specific instance 
SELECT df.result(&amp;lt;ID&amp;gt;); 

That's it: submit, walk away, inspect. &lt;/LI-CODE&gt;
&lt;P&gt;Read the &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/horizondb/development/durable-functions" target="_blank" rel="noopener"&gt;documentation for more details.&lt;/A&gt;&lt;BR /&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;" data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;In VS Code, with the PostgreSQL extension&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 28px;" 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;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;A dense one-liner of &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;~&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;&amp;amp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;|=&amp;gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; is precise once it clicks, but the learning curve is real so &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;flatten&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; it with tooling. Install the &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/horizondb/development/vs-code-extension/vs-code-overview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;PostgreSQL extension for VS Code&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; from the Marketplace:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img&gt;Figure 3: AI pipelines and pg_durable in VSCode extension&lt;/img&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Connect to &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; or your local Postgres&lt;/SPAN&gt;&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;directly from the extension&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Let Copilot write the SQL.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;The&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/tree/main/.agents/skills/pg-durable-sql" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;pg-durable-sql skill&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; turns a plain-English description ("every night, archive orders older than &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;90 days&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;") into correct pg_durable syntax.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Run it and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;watch&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; it.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; The extension renders &lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;pg_durable&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;EM&gt; &lt;/EM&gt;workflows and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;azure_ai&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/EM&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; pipelines as live graphs&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;definition&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;and&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt; each run&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;so you can see every step, its timing, and exactly where a failure happened.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:36,&amp;quot;335559739&amp;quot;:36}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Authoring, execution, run visualization, and inspection in one window and the same tooling works against any Postgres, not just &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;HorizonDB&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;On your laptop&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="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Prefer to run it yourself? Clone &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-charstyle="Verbatim Char"&gt;microsoft/pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, use the &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Codespace&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; prebuild or VS Code Dev Container, and add the extension&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&amp;nbsp;on any Postgres 17.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&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;Sample &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;pattern&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;s worth exploring&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;201341983&amp;quot;:0,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:259}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/blob/main/docs/SCENARIOS.md" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;scenario guide&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;has &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;a&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; full catalog&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; of scenarios; &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;however, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;these are the three &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;I would&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; start with.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&lt;STRONG&gt;ETL Pipeline:&lt;/STRONG&gt; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;a multi-step data transformation&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; where each step must &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;be completed&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; before the next begins. Failures should stop the pipeline.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT df.start( 
    'DELETE FROM target WHERE loaded_at &amp;lt; now() - interval ''7 days'''        -- Step 1: Cleanup old 
    ~&amp;gt; 'UPDATE staging SET processed_at = now() WHERE processed_at IS NULL'   -- Step 2: Mark staging 
    ~&amp;gt; 'INSERT INTO target (data, source_id) 
        SELECT data, source_id FROM staging WHERE processed_at IS NOT NULL',  -- Step 3: Load 
    'etl-pipeline'  -- Label for easy identification 
); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;If the database restarts mid-backfill, it picks up from the last checkpointed batch&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;, &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;not row zero&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;. &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/blob/main/docs/SCENARIOS.md#scenario-2-etl-pipeline" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;See full example&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;Scheduled Data Sync&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;poll an external API or run a job on a schedule (hourly, daily, every 30 minutes). The job should run forever and survive restarts.&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; (&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/blob/main/docs/SCENARIOS.md#scenario-5-scheduled-data-sync" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;See full example&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;)&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;-- Scheduled sync: fetch data every 30 minutes (runs forever) 
SELECT df.start( 
    @&amp;gt; (  -- @&amp;gt; creates an eternal loop 
        -- Fetch from external API 
        (df.http( 
            'https://httpbingo.org/json', 
            'GET' 
        ) |=&amp;gt; 'response') 
         
        -- Store the response 
        ~&amp;gt; 'INSERT INTO external_data_sync (data)  
            VALUES ($response::jsonb)' 
         
        -- Wait for next scheduled run 
        ~&amp;gt; df.wait_for_schedule('*/30 * * * *')  -- Cron: every 30 minutes 
    ), 
    'scheduled-data-sync' 
); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;Human-in-the-loop approval&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;&lt;STRONG&gt; &lt;/STRONG&gt;auto-apply routine changes, pause the risky ones until a person signals approval&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; (&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable/tree/main/examples/invoice-approval" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;See full example&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;)&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT df.start( 
    'SELECT amount &amp;gt; 10000 AS needs_review FROM invoices WHERE id = 42' |=&amp;gt; 'risky' 
    ?&amp;gt; ( df.wait_for_signal('invoice-42') ~&amp;gt; 'UPDATE invoices SET status = ''paid'' WHERE id = 42' ) 
    !&amp;gt; 'UPDATE invoices SET status = ''paid'' WHERE id = 42', 
    'invoice-approval' 
); &lt;/LI-CODE&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The workflow simply waits minutes or days until a reviewer releases it with the matching signal, then resumes.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&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;The community is already running with it&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="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;pg_durable&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; launched as open &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;source&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; and the community is already kicking the tires. &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;The project &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;was&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="Body Text"&gt;a top&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; article&lt;/SPAN&gt;&lt;/SPAN&gt; &lt;A href="https://news.ycombinator.com/item?id=48414367" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;on Hacker News&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; on launch day&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; and &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;1.7K stars on GitHub&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; within &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;its &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;first&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; few&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; days of &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;initial&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; launch&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; Also&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://franckpachot.medium.com/" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Franck Pachot&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; (PostgreSQL community veteran) published an independent walkthrough&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;, &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://dev.to/franckpachot/getting-started-with-pgdurable-durable-workflows-inside-postgresql-3980" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Getting Started with pg_durable: durable workflows inside PostgreSQL&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; within days of release.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;The repo is actively &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;developed,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; and the maintainers are reading every issue and PR.&lt;/SPAN&gt; &lt;SPAN data-ccp-parastyle="First Paragraph"&gt;If &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;you want improvements in our&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; DSL ergonomics, say so. If you want an operator that &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;doesn't&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; exist yet, open an issue. If &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;you've&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; got a scenario we &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;haven't&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; covered, send a PR. The syntax, the docs, and the rough edges all get better when people who &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt;run&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="First Paragraph"&gt; Postgres in production push back.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;So,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; clone it,&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; and&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; build something real. If you find rough edges, open an issue or send a PR at &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;microsoft/pg_durable&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;. We think &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt;you'll&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Body Text"&gt; be surprised by how much it can take.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:180,&amp;quot;335559739&amp;quot;:180}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Learn more&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;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;&lt;A class="lia-external-url" href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;pg_durable&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;&lt;A class="lia-external-url" href="https://github.com/microsoft/pg_durable" target="_blank" rel="noopener"&gt; on GitHub&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;A class="lia-external-url" style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://learn.microsoft.com/en-us/azure/horizondb/development/durable-functions" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;Durable Functions on&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335551671&amp;quot;:0,&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;A class="lia-external-url" style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://learn.microsoft.com/en-us/azure/horizondb/ai/ai-pipelines" target="_blank" rel="noopener"&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;AI&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;p&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;ipelines on &lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="Compact"&gt;HorizonDB&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 09 Jun 2026 17:28:31 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/introducing-durable-functions-in-postgresql/ba-p/4526821</guid>
      <dc:creator>abeomor-msft</dc:creator>
      <dc:date>2026-06-09T17:28:31Z</dc:date>
    </item>
    <item>
      <title>Make upgrades predictable with Pre-Upgrade Validation Checks</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/make-upgrades-predictable-with-pre-upgrade-validation-checks/ba-p/4522593</link>
      <description>&lt;P style="font-size: 18px;"&gt;Major version upgrades are an important part of keeping PostgreSQL environments current with the latest features, security updates, and performance improvements. But for production workloads, the hardest part is often not the upgrade itself - it is knowing whether the server is ready before the upgrade window begins.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Today, we’re announcing the Public Preview of &lt;STRONG&gt;Pre-Upgrade Validation Checks&lt;/STRONG&gt; for &lt;A class="lia-external-url" href="https://azure.microsoft.com/products/postgresql" target="_blank" rel="noopener"&gt;Azure Database for PostgreSQL&lt;/A&gt;. This new capability lets you validate upgrade readiness before starting the actual major version upgrade, helping you identify and resolve blockers early.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;With Pre-Upgrade Validation Checks, you can run upgrade checks independently, review actionable results, fix issues, and re-run validation until your server is ready. This shifts upgrade troubleshooting from the upgrade window to a proactive pre-flight step.&lt;/P&gt;
&lt;H1&gt;Why this matters&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;Azure Database for PostgreSQL flexible server already supports in-place &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;major version upgrades&lt;/A&gt; using PostgreSQL &lt;A href="https://www.postgresql.org/docs/current/pgupgrade.html" target="_blank" rel="noopener"&gt;&lt;CODE&gt;pg_upgrade&lt;/CODE&gt;&lt;/A&gt;. The service preserves the server name and connection settings, runs upgrade prechecks, takes an implicit backup when checks pass, and then performs the engine upgrade.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Pre-Upgrade Validation Checks extend this model by &lt;STRONG&gt;decoupling validation from upgrade execution&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Instead of: &lt;STRONG&gt;Upgrade → Discover issue → Troubleshoot → Retry&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;You can now follow: &lt;STRONG&gt;Validate → Fix → Re-Validate → Upgrade&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;This helps reduce failed upgrade attempts, improves planning, and gives teams more confidence before entering a production change window.&lt;/P&gt;
&lt;H1&gt;What Pre-Upgrade Validation Checks validate&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;Pre-Upgrade Validation Checks evaluate both Azure-specific upgrade requirements and PostgreSQL compatibility checks, including &lt;CODE&gt;pg_upgrade --check&lt;/CODE&gt;.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;At a high level, the validation covers:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Configuration and platform prerequisites&lt;/STRONG&gt;, such as server state, target version support, storage headroom, and upgrade readiness.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Extension compatibility&lt;/STRONG&gt;, including unsupported or version-sensitive extensions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Database dependencies and objects&lt;/STRONG&gt;, such as read replicas, logical replication slots, event triggers, &lt;CODE&gt;PostGIS search_path&lt;/CODE&gt;, and upgrade-sensitive objects.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Engine compatibility&lt;/STRONG&gt;, using PostgreSQL &lt;CODE&gt;pg_upgrade --check&lt;/CODE&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P style="font-size: 18px;"&gt;If a blocking issue is found, the result includes details to help you understand what needs to be fixed before retrying validation or starting the upgrade.&lt;/P&gt;
&lt;H1&gt;How to run Pre-Upgrade Validation Checks from the Azure portal&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;You can run Pre-Upgrade Validation Checks directly from the existing &lt;STRONG&gt;Upgrade&lt;/STRONG&gt; experience in the Azure portal.&lt;/P&gt;
&lt;H2 style="font-size: 18px;"&gt;&lt;STRONG&gt;Step 1: Select &lt;CODE&gt;Validate only&lt;/CODE&gt;&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P style="font-size: 18px;"&gt;From your Azure Database for PostgreSQL flexible server, select &lt;STRONG&gt;Upgrade&lt;/STRONG&gt;. Choose the target PostgreSQL version, then select &lt;STRONG&gt;&lt;CODE&gt;Validate only&lt;/CODE&gt;&lt;/STRONG&gt; as the action. This runs validation checks without starting the actual upgrade.&lt;/P&gt;
&lt;img&gt;Figure 1: Select &lt;CODE&gt;Validate only&lt;/CODE&gt; before starting upgrade&lt;/img&gt;
&lt;H2 style="font-size: 18px;"&gt;&lt;STRONG&gt;Step 2: Review successful validation results&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P style="font-size: 18px;"&gt;If all validation checks pass, the result shows a successful status. At this point, the server is ready to proceed with the major version upgrade.&lt;/P&gt;
&lt;img&gt;Figure 2: Successful validation results&lt;/img&gt;
&lt;P style="font-size: 18px;"&gt;In this example, all pre-upgrade validation checks completed successfully, and no blocking issues were detected for the selected target PostgreSQL version.&lt;/P&gt;
&lt;H2 style="font-size: 18px;"&gt;&lt;STRONG&gt;Step 3: Review and fix validation errors&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P style="font-size: 18px;"&gt;If validation detects issues, the results page shows failed checks with details and remediation guidance. You can fix the reported issues and run validation again.&lt;/P&gt;
&lt;img&gt;Figure 3: Failed validation with remediation details&lt;/img&gt;
&lt;P style="font-size: 18px;"&gt;In this example, validation found an event trigger issue before the upgrade was started. The upgrade action remains blocked until the issue is resolved and validation passes.&lt;/P&gt;
&lt;H2 style="font-size: 18px;"&gt;&lt;STRONG&gt;Step 4: Download validation results&lt;/STRONG&gt;&lt;/H2&gt;
&lt;P style="font-size: 18px;"&gt;You can also download the validation results as a CSV file. This makes it easier to share findings with DBA, application, platform, or support teams before the actual upgrade window.&lt;/P&gt;
&lt;img&gt;Figure 4: Download validation results as CSV&lt;/img&gt;
&lt;P style="font-size: 18px;"&gt;The CSV output is useful for offline review, internal tracking, and support collaboration.&lt;/P&gt;
&lt;H1&gt;Recommended workflow&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;Use Pre-Upgrade Validation Checks as part of your upgrade planning process: run validation early, review the results, fix any reported blockers, re-run validation until all checks pass, and then proceed with the major version upgrade.&lt;/P&gt;
&lt;H1&gt;What happens after validation passes?&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;Once validation succeeds, you can proceed with the &lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/how-to-perform-major-version-upgrade?tabs=portal-major-version-upgrade" target="_blank" rel="noopener"&gt;major version upgrade&lt;/A&gt; using the existing Azure PostgreSQL upgrade workflow. The actual upgrade remains a separate operation and still includes the managed backup and &lt;CODE&gt;pg_upgrade&lt;/CODE&gt; execution steps.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Pre-Upgrade Validation Checks do not remove the upgrade downtime window. Instead, they help ensure that known blockers are resolved before that window begins.&lt;/P&gt;
&lt;H1&gt;Frequently asked questions&lt;/H1&gt;
&lt;P style="font-size: 18px;"&gt;&lt;STRONG&gt;Does &lt;CODE&gt;Validate only&lt;/CODE&gt; perform the upgrade?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;No. The &lt;STRONG&gt;&lt;CODE&gt;Validate only&lt;/CODE&gt;&lt;/STRONG&gt; option runs readiness checks without upgrading the server. The actual major version upgrade remains a separate action.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;&lt;STRONG&gt;Does this remove downtime?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;No. Major version upgrades still require an execution window. The benefit is that compatibility issues can be discovered and resolved before downtime begins.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;&lt;STRONG&gt;Can I re-run validation?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Yes. Validation is designed to be repeatable. You can fix reported issues and re-run checks until all validations pass.&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;&lt;STRONG&gt;What types of blockers can be detected?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P style="font-size: 18px;"&gt;Common examples include unsupported extensions, logical replication slots, event triggers, insufficient storage headroom, configuration issues, and PostgreSQL compatibility findings from &lt;CODE&gt;pg_upgrade --check&lt;/CODE&gt;.&lt;/P&gt;
&lt;H2&gt;Get started&lt;/H2&gt;
&lt;P&gt;Pre-Upgrade Validation Checks are now available in Public Preview for Azure Database for PostgreSQL flexible server.&lt;/P&gt;
&lt;P&gt;To try it, open your flexible server in the Azure portal, go to &lt;STRONG&gt;Upgrade&lt;/STRONG&gt;, select your target PostgreSQL version, and choose &lt;STRONG&gt;Validate only&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H2&gt;Learn more&lt;/H2&gt;
&lt;P style="font-size: 18px;"&gt;To learn more about major version upgrades and related Azure PostgreSQL capabilities, see:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;Major version upgrades in Azure Database for PostgreSQL&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/how-to-perform-major-version-upgrade?tabs=portal-major-version-upgrade" target="_blank" rel="noopener"&gt;Perform a major version upgrade&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-supported-versions" target="_blank" rel="noopener"&gt;Supported PostgreSQL versions &lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/extensions/concepts-extensions-by-engine?pivots=postgresql-18" target="_blank" rel="noopener"&gt;PostgreSQL extensions supported by Azure Database for PostgreSQL &lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/monitor/how-to-configure-server-logs?tabs=portal-enable-capture-of-logs%2Cportal-disable-capture-of-logs%2Cportal-list-captured-logs%2Cportal-download-captured-logs" target="_blank" rel="noopener"&gt;Download PostgreSQL server logs&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://www.postgresql.org/docs/current/pgupgrade.html" target="_blank" rel="noopener"&gt;PostgreSQL &lt;CODE&gt;pg_upgrade&lt;/CODE&gt; documentation&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-10"&gt;&lt;EM&gt;&lt;STRONG&gt;Validate early. Fix with confidence. Upgrade when ready.&lt;/STRONG&gt;&lt;/EM&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Thu, 11 Jun 2026 14:31:16 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/make-upgrades-predictable-with-pre-upgrade-validation-checks/ba-p/4522593</guid>
      <dc:creator>varun-dhawan</dc:creator>
      <dc:date>2026-06-11T14:31:16Z</dc:date>
    </item>
    <item>
      <title>Announcing new security, maintenance and analytics features for PostgreSQL at Microsoft Build 2026</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/announcing-new-security-maintenance-and-analytics-features-for/ba-p/4524559</link>
      <description>&lt;P&gt;&lt;SPAN data-teams="true"&gt;At &lt;STRONG&gt;Microsoft Build 2026&lt;/STRONG&gt;, we’re announcing a major wave of PostgreSQL innovation across Azure. Alongside&lt;/SPAN&gt;&amp;nbsp;the public preview of &lt;STRONG&gt;&lt;A class="lia-external-url" href="https://aka.ms/HorizonDB-Build-blog" target="_blank" rel="noopener"&gt;Azure HorizonDB&lt;/A&gt;&lt;/STRONG&gt;, &lt;SPAN data-teams="true"&gt;we’re delivering a broad set of enhancements for&lt;/SPAN&gt; our fully managed open-source PostgreSQL service: &lt;STRONG&gt;&lt;A href="https://learn.microsoft.com/azure/postgresql/overview" target="_blank" rel="noopener"&gt;Azure Database for PostgreSQL flexible server.&lt;/A&gt;&lt;/STRONG&gt; These updates span &lt;EM&gt;performance&lt;/EM&gt;,&lt;EM&gt; analytics&lt;/EM&gt;,&lt;EM&gt; security&lt;/EM&gt;,&lt;EM&gt; operations&lt;/EM&gt;,&lt;EM&gt; resilience&lt;/EM&gt; and &lt;EM&gt;migration&lt;/EM&gt;&amp;nbsp;-&lt;SPAN style="color: rgb(30, 30, 30);"&gt; helping you build faster, operate with more control, secure your workloads, and modernize with confidence.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;Here’s a quick tour of the top flexible server announcements at Build 2026.&lt;/P&gt;
&lt;H1&gt;Feature Highlights&lt;/H1&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-duck-db" target="_self" rel="noopener"&gt;pg_duckdb Extension&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-ivm" target="_self" rel="noopener"&gt;pg_ivm Extension&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-assessments" target="_self" rel="noopener"&gt;Defender Security assessments&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-tables" target="_self" rel="noopener"&gt;temporal_tables Extension&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-cmk-support" target="_self" rel="noopener"&gt;&lt;STRONG&gt;Cross-tenant CMK&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-token" target="_self" rel="noopener"&gt;&lt;STRONG&gt;Automatic Entra token refresh libraries&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-powershell" target="_self" rel="noopener"&gt;&lt;STRONG&gt;New Powershell module:&amp;nbsp; Az.PostgreSQLFlexibleServer&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A class="lia-internal-link" href="#community--1-maintenance" target="_self" rel="noopener" data-lia-auto-title="More control over planned maintenance" data-lia-auto-title-active="0"&gt;&lt;STRONG&gt;More control over planned maintenance&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A href="#community--1-pvc" target="_self" rel="noopener"&gt;Pre-Upgrade validation checks&lt;/A&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-dashboard" target="_self" rel="noopener"&gt;&lt;STRONG&gt;New Built-in Grafana dashboards&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-chaos" target="_self" rel="noopener"&gt;&lt;STRONG&gt;Chaos Studio supports Azure Database for PostgreSQL&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-ai-migration" target="_self" rel="noopener"&gt;&lt;STRONG&gt;AI-assisted Oracle to PostgreSQL migration&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-migration-service" target="_self" rel="noopener"&gt;&lt;STRONG&gt;Migration Service for Azure Database for PostgreSQL improvements (EDB, AlloyDB)&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;H1&gt;Performance, Scale &amp;amp; Analytics&lt;/H1&gt;
&lt;H4 id="duck-db"&gt;pg_duckdb Extension Generally Available&lt;/H4&gt;
&lt;P&gt;The &lt;STRONG&gt;pg_duckdb&lt;/STRONG&gt; extension enables you to accelerate high-performance analytics and data-intensive applications with DuckDB’s SQL engine running inside your Postgres server. We’re pleased to announce pg_duckdb is now generally available in Azure Database for PostgreSQL. The latest version builds on the preview with the latest DuckDB engine improvements and optimized performance. This version adds &lt;STRONG&gt;vectorized execution for faster analytical queries&lt;/STRONG&gt;, delivering significant improvements in aggregation performance, along with new support for &lt;STRONG&gt;writing to Azure Blob Storage&lt;/STRONG&gt; and &lt;STRONG&gt;querying Parquet data directly from PostgreSQL&lt;/STRONG&gt;. These capabilities enable high-performance analytics on your external data and simplify data processing workflows. Learn more: &lt;A href="https://learn.microsoft.com/azure/postgresql/extensions/concepts-extensions-versions#pg_duckdb" target="_blank" rel="noopener"&gt;pg_duckdb&lt;/A&gt;.&lt;/P&gt;
&lt;H4 id="ivm"&gt;pg_ivm Extension Generally Available&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Materialized views&lt;/STRONG&gt; are a useful way to optimize performance for queries that run regularly, but if underlying data becomes stale the result set needs to be recomputed. With the &lt;STRONG&gt;pg_ivm&lt;/STRONG&gt; &lt;STRONG&gt;extension&lt;/STRONG&gt; you can automatically maintain materialized views as the underlying data changes. This is particularly &lt;STRONG&gt;valuable for large datasets with small incremental changes that need real-time freshness&lt;/STRONG&gt;, like dashboards, catalog analytics and SaaS usage reporting. We are pleased to announce the pg_ivm extension is now generally available in Azure Database for PostgreSQL. Learn more: &lt;A href="https://learn.microsoft.com/azure/postgresql/extensions/concepts-extensions-versions#pg_ivm" target="_blank" rel="noopener"&gt;pg_ivm&lt;/A&gt;.&lt;/P&gt;
&lt;H1&gt;Security, Auditing &amp;amp; Identity&lt;/H1&gt;
&lt;H4 id="assessments"&gt;Defender security assessments Preview&amp;nbsp;&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Microsoft Defender Security Assessments for Azure Database for PostgreSQL&lt;/STRONG&gt; enables continuous evaluation of your database security posture, helping identify vulnerabilities and misconfigurations across server and database configurations. Previously limited to reactive threat detection, in the latest preview release, Defender now provides &lt;STRONG&gt;proactive, risk-based insights through assessments tailored to PostgreSQL-specific best practices&lt;/STRONG&gt;, delivering more relevant and actionable guidance. This helps you strengthen your security baseline, prioritize remediation, and align with best practices and compliance requirements. Learn more: &lt;A href="https://aka.ms/Defender-Assessments-for-PG-Preview" target="_blank" rel="noopener"&gt;https://aka.ms/Defender-Assessments-for-PG-Preview&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="tables"&gt;temporal_tables Extension Generally Available&lt;/H4&gt;
&lt;P&gt;We’ve had many customer requests to support the &lt;STRONG&gt;temporal_tables&lt;/STRONG&gt; extension, which provides&lt;STRONG&gt; built-in support for tracking and querying historical changes to data over time&lt;/STRONG&gt;. Temporal tables are now generally available in Azure Database for PostgreSQL. With this extension enabled you can easily perform time-based queries, audit data changes, and maintain historical records without building custom tracking logic, simplifying application development and compliance scenarios. Learn more: &lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/extensions/concepts-extensions-versions#temporal_tables" target="_blank" rel="noopener"&gt;temporal_tables&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="cmk-support"&gt;Cross-tenant CMK Preview&lt;/H4&gt;
&lt;P&gt;Azure Database for &lt;STRONG&gt;PostgreSQL now supports cross-tenant customer-managed keys (CMK) in public preview&lt;/STRONG&gt;, allowing you to encrypt your data at rest using an Azure Key Vault key that resides in a separate Microsoft Entra tenant from the database service. This feature is designed for SaaS providers and enterprises that need to maintain strict separation of duties and ownership of encryption keys, enabling you to retain full control over key lifecycle management while PostgreSQL runs in a service provider’s tenant. Learn more: &lt;A href="https://learn.microsoft.com/en-us/azure/postgresql/security/security-data-encryption" target="_blank" rel="noopener"&gt;Data encryption at rest in Azure Database for PostgreSQL&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="token"&gt;Automatic Entra token refresh libraries Preview&lt;/H4&gt;
&lt;P&gt;We’re making it easier to use Entra ID authentication with Azure Database for PostgreSQL throughout the application stack by introducing&amp;nbsp;&lt;STRONG&gt;new token refresh libraries for .NET, JavaScript, and Python&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;With Entra ID, access tokens are short-lived which can make managing their lifecycle complex in real-world applications. Developers need to be aware of token refresh and build additional handling around token expiration, connection retry, and session continuity.&lt;/P&gt;
&lt;P&gt;These new libraries remove that friction. By handling Entra token refresh seamlessly in the background, they allow applications to stay connected without interruption and with no custom logic required. The result is a simpler development experience and more resilient applications, especially for long-running or connection-heavy workloads.&lt;/P&gt;
&lt;P&gt;Across languages, the libraries provide a consistent and streamlined way to adopt secure, passwordless authentication, helping teams focus more on building their applications and less on managing authentication. Learn more: &lt;A class="lia-external-url" 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;,&amp;nbsp;&lt;A class="lia-external-url" href="https://www.npmjs.com/package/@azure/postgresql-auth" target="_blank" rel="noopener"&gt;JavaScript&lt;/A&gt;, and&amp;nbsp;&lt;A class="lia-external-url" href="https://pypi.org/project/azure-postgresql-auth/" target="_blank" rel="noopener"&gt;Python&lt;/A&gt;.&lt;/P&gt;
&lt;H1&gt;Operations, Maintenance &amp;amp; Monitoring&lt;/H1&gt;
&lt;H4 id="powershell"&gt;New Powershell module:&amp;nbsp; Az.PostgreSQLFlexibleServer Generally Available&lt;/H4&gt;
&lt;P&gt;We’re excited to introduce the newly renamed &lt;STRONG&gt;Az.PostgreSQLFlexibleServer PowerShell module&lt;/STRONG&gt;, delivering a streamlined experience for managing Azure Database for PostgreSQL with PowerShell. Building on the capabilities of the previous Az.PostgreSql module, the updated module aligns with the new features in the 2026-01-01 preview REST API. This module brings support for PostgreSQL 18, elastic clusters for scalable workloads and a range of enhancements designed to simplify management and improve performance. Whether you're provisioning new deployments or managing complex environments, this module ensures you can take full advantage of the latest platform capabilities directly from PowerShell.&lt;/P&gt;
&lt;P&gt;To learn more, visit our official documentation on PowerShell: &lt;A href="https://learn.microsoft.com/powershell/module/az.postgresql/?view=azps-15.6.0" target="_blank" rel="noopener"&gt;Az.PostgreSql Module | Microsoft Learn&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="maintenance"&gt;More control over planned maintenance Generally Available&lt;STRONG&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/STRONG&gt;&lt;/H4&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We’ve seen many requests to provide more control when a maintenance update is applied to Azure Database for PostgreSQL. Sometimes when a critical workload is running you want to &lt;STRONG&gt;apply the maintenance when you’re ready&lt;/STRONG&gt;. &amp;nbsp;Announcing general availability this week, we’re building on the existing System and Custom maintenance window options and adding new self-service maintenance capabilities to the Azure portal.&lt;/P&gt;
&lt;P&gt;You can now &lt;STRONG&gt;reschedule upcoming maintenance updates for up to two weeks and apply maintenance on demand&lt;/STRONG&gt; at a time that suits you. You can also view scheduled maintenance and review your server’s maintenance history after updates are complete. &lt;BR /&gt;&lt;BR /&gt;These options help you better align maintenance with your business schedules, reduce disruption during critical workload periods, and minimize the need for support-driven deferral requests. CLI and API support are coming soon. Learn more: &lt;A href="https://aka.ms/azure-postgres-reschedule-maintenance" target="_blank" rel="noopener"&gt;https://aka.ms/azure-postgres-reschedule-maintenance&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="pvc"&gt;Pre-Upgrade validation checks Preview&lt;/H4&gt;
&lt;img&gt;PVC detects an event trigger blocker before upgrade execution and keeps the upgrade action disabled until issues are resolved.&lt;/img&gt;
&lt;P class="lia-align-justify lia-clear-both"&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/azure/postgresql/configure-maintain/concepts-major-version-upgrade" target="_blank" rel="noopener"&gt;Major version upgrades&lt;/A&gt; are critical for staying current with PostgreSQL features, security updates, and performance improvements, but you often discover blockers only after starting the upgrade workflow. &lt;STRONG&gt;&lt;A class="lia-external-url" href="https://review.learn.microsoft.com/en-us/azure/postgresql/configure-maintain/how-to-run-upgrade-validation-checks" target="_blank" rel="noopener"&gt;Pre-Upgrade Validation Checks&lt;/A&gt; lets you validate upgrade readiness before initiating the actual upgrade by running Azure-specific upgrade checks and PostgreSQL &lt;SPAN class="lia-text-color-13"&gt;pg_upgrade --check&lt;/SPAN&gt; validations independently&lt;/STRONG&gt;. &lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;The shift is simple: you can identify and fix upgrade blockers before the upgrade window begins&lt;/STRONG&gt;. The feature surfaces actionable issues across configurations, extensions, dependencies, replication slots, event triggers, and other upgrade-sensitive objects. You can fix blockers, re-run validation until all checks pass, and proceed with the upgrade with greater predictability. &lt;BR /&gt;&lt;BR /&gt;Learn more: &lt;A href="https://aka.ms/pg-flex-upgrade-checks" target="_blank" rel="noopener"&gt;https://aka.ms/pg-flex-upgrade-checks&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="dashboard"&gt;New Built-in Grafana dashboards Generally Available&lt;/H4&gt;
&lt;img&gt;Monitor Azure PostgreSQL with built-in Grafana dashboards — no setup, no extra cost, and no separate service to manage.&lt;/img&gt;
&lt;P data-start="58" data-end="470"&gt;&lt;STRONG data-start="92" data-end="255"&gt;&lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/postgresql/monitor/how-to-use-dashboards-with-grafana" target="_blank" rel="noopener"&gt;Grafana dashboards&lt;/A&gt; are now built directly into the Azure portal for Azure Database for PostgreSQL - no setup, no extra cost, and no separate service to manage.&lt;/STRONG&gt; You can open your PostgreSQL resource in the portal and immediately access prebuilt dashboards for key health and performance signals such as CPU, memory, storage, IOPS, connections, transactions, and availability.&lt;/P&gt;
&lt;P data-start="472" data-end="787"&gt;&lt;STRONG data-start="472" data-end="521"&gt;The key value is &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/postgresql/monitor/concepts-monitoring" target="_blank" rel="noopener"&gt;metrics &lt;/A&gt;+ &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/postgresql/monitor/concepts-logging" target="_blank" rel="noopener"&gt;logs &lt;/A&gt;in one place.&lt;/STRONG&gt; You can quickly correlate performance spikes with PostgreSQL logs, understand what changed, and troubleshoot faster using the familiar Grafana experience. Dashboards can also be customized, saved to your subscription, and shared across teams for ongoing operations. &lt;BR /&gt;&lt;BR /&gt;Learn more:&amp;nbsp;&lt;A href="https://aka.ms/azure-postgres-dashboards-grafana" target="_blank" rel="noopener" data-start="801" data-end="849" data-is-last-node=""&gt;https://aka.ms/azure-postgres-dashboards-grafana&lt;/A&gt;&lt;/P&gt;
&lt;H1&gt;Resilience &amp;amp; Business Continuity&lt;/H1&gt;
&lt;H4 id="chaos"&gt;Chaos Studio supports Azure Database for PostgreSQL Preview&lt;/H4&gt;
&lt;P&gt;No matter how much you prepare, you only really know how good your database disaster recovery plan is when something breaks. With&amp;nbsp;&lt;STRONG&gt;Chaos Studio support for Azure Database for PostgreSQL,&lt;/STRONG&gt;&amp;nbsp;you can simulate zone-down scenarios on PostgreSQL HA-enabled instances and validate the resilience of your mission-critical workloads.&lt;/P&gt;
&lt;P&gt;With Chaos Studio integration, you can proactively test failover behavior and gain confidence in how your applications respond to real-world zonal failures.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This feature is currently available through a gated private preview. To get started, submit your subscription details using the&lt;A href="https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR_xNHyVnMH5NvQCAJk-wFYxUQzBGOEdUUDBUVFJVRVlETEJOQ1BZSUpIMi4u" target="_blank" rel="noopener"&gt; form&lt;/A&gt;. Once reviewed, our team will enable the feature for your subscription, with guidance to help you begin testing.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Getting started is simple:&lt;/STRONG&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Create a Chaos Studio workspace via the &lt;A href="https://aka.ms/chaos-portal" target="_blank" rel="noopener"&gt;Chaos Studio portal&lt;/A&gt; and configure your subscription, resource group, and region.&lt;/LI&gt;
&lt;LI&gt;Define the scope and assign the required managed identity and permissions.&lt;/LI&gt;
&lt;LI&gt;Review and verify your workspace setup.&lt;/LI&gt;
&lt;LI&gt;Browse available scenarios and select the PostgreSQL zone-down scenario.&lt;/LI&gt;
&lt;LI&gt;Configure the test (name, duration), then run it from My Library to begin validating failover behavior.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;With just a few steps, you’ll be able to simulate real-world failure conditions and gain confidence in your application’s resilience.&lt;/P&gt;
&lt;P&gt;To get started, please submit your details using this link: &lt;A href="https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR_xNHyVnMH5NvQCAJk-wFYxUQzBGOEdUUDBUVFJVRVlETEJOQ1BZSUpIMi4u" target="_blank" rel="noopener"&gt;Private Preview Support for Chaos Studio&lt;/A&gt;&lt;/P&gt;
&lt;H1&gt;Migration &amp;amp; Modernization&lt;/H1&gt;
&lt;H4 id="ai-migration"&gt;AI-assisted Oracle to PostgreSQL migration Generally Available&lt;/H4&gt;
&lt;P&gt;AI-assisted migration tooling has dramatically lowered the bar for moving between different databases and is changing the way people look at the return on investment for migration. The VS Code PostgreSQL extension comes with AI-Assisted migration tooling which converts Oracle schema and application code to Azure Database for PostgreSQL. This tooling uses GitHub Copilot, Microsoft Foundry, and custom Language Model tools to convert Oracle schema, database code and client applications into the PostgreSQL equivalents, and validates every change against a running flexible server instance. Learn more: &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/oracle-schema-conversions/schema-conversions-overview" target="_blank" rel="noopener"&gt;Schema conversion&lt;/A&gt;, &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/oracle-application-conversions/app-conversions-overview" target="_blank" rel="noopener"&gt;App conversion.&lt;/A&gt;&lt;/P&gt;
&lt;H4 id="migration-service"&gt;Migration Service for Azure Database for PostgreSQL improvements (EDB, AlloyDB) Generally Available&lt;/H4&gt;
&lt;P&gt;We’ve added AlloyDB and EDB Extended Server as new sources for migrating to PostgreSQL in the Azure Database for PostgreSQL Migration Service, with support for both online and offline migration support. Learn more: &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/migration-service/tutorial-migration-service-alloy-db-online?tabs=portal" target="_blank" rel="noopener"&gt;Migrate from AlloyDB&lt;/A&gt;, &lt;A href="https://learn.microsoft.com/azure/postgresql/migrate/migration-service/tutorial-migration-service-enterprise-db-extended-server-online?tabs=portal" target="_blank" rel="noopener"&gt;Migrate from EDB&lt;/A&gt;.&lt;/P&gt;
&lt;H1&gt;Looking ahead&lt;/H1&gt;
&lt;P&gt;That wraps up the Build 2026 announcements for Azure Database for PostgreSQL flexible server. There are also many great PostgreSQL technical sessions at Build this week, covering cloud-native app &amp;amp; AI development and migration. To find out more, here's a link to the Build session catalog for PostgreSQL sessions: &lt;A href="https://aka.ms/Postgres-on-Azure_Build-2026" target="_blank" rel="noopener"&gt;https://aka.ms/Postgres-on-Azure_Build-2026.&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;We'll continue to build out our roadmap over the coming months to deliver on your asks to improve the performance, security and stability of your PostgreSQL workloads. Check the&amp;nbsp;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/category/azuredatabases/blog/adforpostgresql" target="_blank" rel="noopener" data-lia-auto-title="Microsoft Blog for PostgreSQL" data-lia-auto-title-active="0"&gt;Microsoft Blog for PostgreSQL&lt;/A&gt; for a regular monthly recap where we share the latest enhancements and product updates.&lt;/P&gt;</description>
      <pubDate>Mon, 29 Jun 2026 22:36:55 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/announcing-new-security-maintenance-and-analytics-features-for/ba-p/4524559</guid>
      <dc:creator>GuyBowerman</dc:creator>
      <dc:date>2026-06-29T22:36:55Z</dc:date>
    </item>
    <item>
      <title>Azure HorizonDB: Enterprise-Ready Postgres, Engineered for the AI Era</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai/ba-p/4524094</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Affan Dar&lt;/STRONG&gt;, Vice President of Engineering, PostgreSQL at Microsoft&lt;BR /&gt;&lt;STRONG&gt;Charles Feddersen&lt;/STRONG&gt;, Partner Director of Program Management, PostgreSQL at Microsoft&lt;/P&gt;
&lt;P&gt;Today at Microsoft Build, we’re pleased to announce the public preview of&amp;nbsp;&lt;A href="https://aka.ms/AzureHorizonDB" target="_blank" rel="noopener"&gt;Azure HorizonDB&lt;/A&gt;, a new enterprise-ready Postgres-compatible database service designed to meet the needs of modern AI applications, alongside a set of enhancements to our PostgreSQL tooling in Visual Studio Code to further streamline the developer experience.&lt;/P&gt;
&lt;P&gt;Postgres is rapidly solidifying its role as a foundational layer in modern data architectures, with accelerating adoption across industries. For developers, it has become the preferred platform for new application development, driven by its extensible architecture, mature extension ecosystem, and adherence to open standards and APIs. At the same time, enterprises are choosing Postgres to re-platform and modernize existing systems, taking advantage of its ability to support a broad range of operational workloads while enabling advanced capabilities such as vector-based data access all within a single, interoperable platform.&lt;/P&gt;
&lt;H4&gt;A Postgres Platform Grounded in Security, Resilience, Scale, and Performance&lt;/H4&gt;
&lt;P&gt;Azure HorizonDB is purpose-built to meet these demands, combining the flexibility developers expect from Postgres with the operational rigor enterprises require. It extends the core Postgres engine with cloud-native capabilities such as integrated identity, fine-grained network and security controls, and seamless lifecycle management, while preserving full compatibility with the open ecosystem of extensions and tools. At the same time, HorizonDB introduces advanced, natively integrated capabilities like vector data support and AI model management, enabling new classes of intelligent applications without sacrificing transactional integrity or developer productivity.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;These capabilities are backed by a platform designed for enterprise performance and scale. HorizonDB supports databases up to 128 TB, scales out with up to 15 read replicas for high-throughput workloads, and delivers sub-millisecond commit latency across availability zones for low-latency transactions and high availability. This combination is critical for modern applications that require consistent performance under load, including high-concurrency transactional systems, real-time AI-driven interactions, and globally distributed services.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;The result is a unified platform that scales from the first line of code to globally distributed, mission-critical systems. Enterprise adoption ultimately depends on trust in the platform itself. Azure HorizonDB delivers this with native integration into Microsoft Entra ID for centralized identity and access control, private endpoints for network isolation, and built-in encryption to protect data at rest and in transit. These capabilities are essential for meeting compliance requirements and enabling organizations to run mission-critical workloads with confidence, without added complexity.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;This foundation is critical for any application, but it becomes indispensable for AI, where secure access to data and controlled model interaction underpin every intelligent experience. Building on this, HorizonDB introduces a set of integrated AI capabilities designed to bring intelligence directly into the database.&lt;/P&gt;
&lt;H4&gt;Run Fast, Memory-Efficient Vector Search with DiskANN&lt;/H4&gt;
&lt;P&gt;HorizonDB brings high-performance vector search directly into Postgres through DiskANN with spherical quantization. This enables efficient, low-latency similarity search at scale while significantly reducing memory and storage overhead. Spherical quantization works by normalizing vectors and encoding them into compact representations that preserve angular distance, allowing the system to compare vectors efficiently with minimal loss in accuracy. The result is the ability to index and query large embedding datasets within the transactional engine itself, making vector search a first-class capability rather than an external dependency.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;EM&gt;"HorizonDB is compelling because it brings a PostgreSQL-compatible foundation, AI-native capabilities and enterprise-grade controls closer to the operational data layer." &lt;/EM&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;&lt;EM&gt;Jennings Balavari, Founder, Opsen AI&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H4&gt;Build Smarter Apps with Hybrid Search in Postgres&lt;/H4&gt;
&lt;P&gt;HorizonDB supports hybrid search by combining vector similarity through pgvector with full-text search enabled via the pg_textsearch extension, allowing applications to match both semantic meaning and precise keyword relevance in a single query. This enables more accurate, context-aware results, such as blending intent-driven retrieval with exact term matching for search, recommendations, or RAG scenarios. By unifying these capabilities within Postgres, HorizonDB improves result quality while simplifying application design without the need for external search systems.&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Operationalize AI with Built-In AI Model Management&lt;/H4&gt;
&lt;P&gt;Working with vectors requires models to generate, interpret, and evolve embeddings, making model lifecycle a core part of the application stack. HorizonDB introduces integrated AI model management to simplify how models are registered, versioned, and governed alongside data, including built-in support for generative GPT models and ranking models. For example, GPT models can be used to generate summaries, responses, or structured outputs directly from application data, while ranking models enable relevance scoring for search results or recommendations over vector results. By managing these models alongside the data they operate on, HorizonDB ensures consistency, traceability, and control, creating a unified environment where models and data evolve together.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;EM&gt;“As we build a multi-tenant, AI-driven commerce platform, HorizonDB has been particularly compelling in two areas: scale and how close AI capabilities are to the data itself. Running vector search, filtering, and model-driven workflows directly inside the database removes a lot of the complexity we’d normally manage across separate services."&lt;/EM&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;&lt;EM&gt;James Frawley, CIAO, ReFiBuy&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp;&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;Bring AI into SQL with AI Functions&lt;/H4&gt;
&lt;P&gt;With models managed in place, AI Functions provide a direct way to invoke them from within SQL and application logic. These functions are implemented through the azure_ai extension, which brings model invocation directly into the Postgres engine. This allows developers to embed inference into queries and transactions, eliminating the need for external orchestration. By bringing model execution closer to the data, AI Functions reduce latency, simplify application design, and make intelligent behavior a natural extension of existing Postgres workloads.&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;EM&gt;"What stood out with HorizonDB is that it aligns closely with how we already think about the problem. Instead of stitching together multiple components, it brings transactional data, vector search, and AI capabilities into a single platform, which simplifies the architecture without forcing a complete rethink." &lt;/EM&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;&lt;EM&gt;Mohsin Shafqat, Director Software Engineering, Nasdaq&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H4&gt;Run Reliable, Event-Driven Workflows with AI Pipelines&lt;/H4&gt;
&lt;P&gt;Finally, AI Pipelines operationalize these capabilities through reliable, event-driven workflows for model execution and data processing. Pipelines execute on data changes, enabling real-time asynchronous reactions without external orchestration and ensuring consistent, repeatable behavior as data evolves. Combined with model management and AI Functions, they turn embedded intelligence into something that can be run, scaled, and trusted in production, while inheriting the database’s high availability and failover characteristics for resilience. Pipelines can also be visualized and observed in real time through the Visual Studio Code extension for PostgreSQL, giving developers and operators immediate visibility into execution flow, state, and outcomes&lt;/P&gt;
&lt;img /&gt;
&lt;H4&gt;Modern Unified Experience for Data, AI, and Operations in VS Code&lt;/H4&gt;
&lt;P&gt;As intelligence becomes a core part of the data platform, the developer and operator experience becomes equally critical. HorizonDB extends seamlessly into Visual Studio Code with enhanced PostgreSQL tooling that works across any Postgres deployment, not just HorizonDB. Features like AI-assisted query plans and integrated monitoring enable faster debugging and optimization, helping teams understand both database performance and AI-driven behaviors.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;At the same time, for Azure-based deployments, the experience is deeply integrated with platform capabilities, enabling management of networking configuration, server parameters, and server logs directly from the development environment, streamlining operations across application and infrastructure layers.&lt;/P&gt;
&lt;P&gt;Azure HorizonDB brings together enterprise-grade security, deep Postgres compatibility, and a modern AI-native data platform, all engineered for developers. It scales efficiently across workloads, from transactional systems to intelligent applications, while delivering a world-class, Azure-integrated experience in Visual Studio Code for both developers and operators.&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Ready to get started with Azure HorizonDB?&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;Azure HorizonDB is now available in public preview in Australia East, Central US, Sweden Central, West US 2, and West US 3 regions. Additionally, East US, Canada Central, Indonesia Central, Italy North, Japan East, Korea Central, and Poland Central will be available in the coming weeks.&lt;/P&gt;
&lt;P&gt;You can get started today by creating a new HorizonDB instance using the Azure portal, API’s, or the Visual Studio Code extension for PostgreSQL to begin exploring these capabilities firsthand.&lt;/P&gt;
&lt;P&gt;To learn more, dive deeper into our &lt;A href="https://aka.ms/HorizonDB-documentation" target="_blank" rel="noopener"&gt;documentation&lt;/A&gt; and &lt;A href="https://aka.ms/horizondb-aimm-preview" target="_blank" rel="noopener"&gt;sign-up today&lt;/A&gt; to try AI model management in a limited preview.&lt;/P&gt;</description>
      <pubDate>Tue, 02 Jun 2026 16:45:15 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-blog-for-postgresql/azure-horizondb-enterprise-ready-postgres-engineered-for-the-ai/ba-p/4524094</guid>
      <dc:creator>charlesfeddersenMS</dc:creator>
      <dc:date>2026-06-02T16:45:15Z</dc:date>
    </item>
  </channel>
</rss>

