<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Mayur (Do not drink &amp; database) on Medium]]></title>
        <description><![CDATA[Stories by Mayur (Do not drink &amp; database) on Medium]]></description>
        <link>https://medium.com/@drunkdba?source=rss-3319eaf2a6c7------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*n804KKnsIMqfyEz00o81ZA.png</url>
            <title>Stories by Mayur (Do not drink &amp;amp; database) on Medium</title>
            <link>https://medium.com/@drunkdba?source=rss-3319eaf2a6c7------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 17 Oct 2026 17:05:20 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@drunkdba/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[PGConf.EU 2026: Into the PostgreSQL Multiverse]]></title>
            <link>https://drunkdba.medium.com/pgconf-eu-2026-into-the-postgresql-multiverse-1b1c0f3be1f0?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/1b1c0f3be1f0</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[dba]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Tue, 13 Oct 2026 20:08:07 GMT</pubDate>
            <atom:updated>2026-10-13T20:08:07.739Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>Somewhere in the multiverse, there is a version of you who attends every interesting talk at PGConf.EU.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6Ou6l7FOQP6rVFaiId4gYQ.jpeg" /></figure><p>Unfortunately, in this universe, PostgreSQL has parallel query execution. Humans don’t.</p><p>Last year, I created an <a href="https://drunkdba.medium.com/pgconf-eu-2025-the-underground-map-for-database-nerds-da3587a90b2e">Underground Map for Database Nerds</a> to navigate PGConf.EU without getting lost in the schedule.</p><p>This year, the conference returns to Valencia, October 20–23, with five parallel tracks and the same old problem: too many good talks occupying the same space-time coordinates.</p><p>So, I’ve borrowed a little inspiration from the Marvel Multiverse.</p><p>Imagine three alternate versions of yourself attending the same PostgreSQL conference, each with completely different priorities.</p><h3>🌍 Universe Earth-5432: The PostgreSQL User</h3><p><strong>Superpower:</strong> EXPLAIN ANALYZE</p><p>DBAs, DBREs, developers, architects and anyone whose applications depend on PostgreSQL.</p><p>You’re interested in what PostgreSQL can do, how it works, how to make it faster, and why it occasionally ruins your weekend.</p><h3>📣 Universe Earth-1996: The PostgreSQL Advocate</h3><p><strong>Superpower:</strong> Converting Oracle users without any violence.</p><p>Community organisers, speakers, educators, contributors, evangelists and anyone spreading the PostgreSQL gospel.</p><p>You care about adoption, community growth, open source, innovation and making PostgreSQL everyone’s favourite elephant.</p><h3>💼 Universe Earth-2013: The Decision Maker</h3><p><strong>Superpower:</strong> GRANT BUDGET</p><p>CTOs, CIOs, engineering directors, team leads and architects who decide what the company runs, buys, builds or migrates.</p><p>You care about risk, reliability, architecture, operational costs and answering the eternal question: “Why not just use the cloud?”</p><p>You may inhabit more than one universe. That’s perfectly legal. Unlike PostgreSQL superuser privileges, nobody is checking.</p><p>Now, let’s find out where your variant should be.</p><h3>🗓️ Tuesday, October 20 — Avengers Assemble (And Immediately Disagree)</h3><p>The first day presents some unusually difficult choices.</p><h3>11:15–12:05 — With Great PostgreSQL Power Comes Great Responsibility</h3><p><strong>🌍 USER | SM1-B — You Shall Not YOLO: Model Your Damn Data</strong></p><p>Lætitia Avrot reminds us that good database design starts long before the first query hits production.</p><p>A must-see for developers and DBAs alike. Because PostgreSQL can forgive many sins, but a terrible data model will haunt you through every migration, index and performance-tuning session.</p><p><strong>📣 ADVOCATE | Audit 1 — Postgres for Everything, Until It Isn’t</strong></p><p>Gülçin Yıldırım Jelinek and Petr Jelinek explore where PostgreSQL shines and where its limitations begin.</p><p>Every good advocate should know both. After all, promoting PostgreSQL everywhere is much easier when you know where <em>not</em> to promote it.</p><p>Because even the biggest PostgreSQL fan shouldn’t try to run a toaster on it.</p><p><strong>💼 DECISION MAKER | Audit 1 — Postgres for Everything, Until It Isn’t</strong></p><p>Gülçin Yıldırım Jelinek and Petr Jelinek challenge the idea of using PostgreSQL for absolutely everything.</p><p>An important architectural discussion for leaders weighing technology consolidation against specialised systems.</p><h3>13:05–13:35 — The Raspberry Pi Incident</h3><p><strong>🌍 USER | Audit 1 — Is PostgreSQL On My Raspberry Pi Faster Than Your Cloud Instance</strong></p><p>Chris Ellis asks a question that could make several cloud invoices deeply uncomfortable.</p><p>A must-see for performance enthusiasts.</p><p><strong>📣 ADVOCATE | Audit 2 — WAIT FOR the Feature for Almost 10 Years</strong></p><p>Alexander Korotkov tells a story about the long journey of a PostgreSQL feature.</p><p>A useful reminder that open-source development is more marathon than sprint. Sometimes a very long marathon.</p><p><strong>💼 DECISION MAKER | Audit 1 — Is PostgreSQL On My Raspberry Pi Faster Than Your Cloud Instance</strong></p><p>Because nothing terrifies a CTO quite like discovering that their expensive infrastructure might be losing to a computer smaller than their coffee mug.</p><p><strong>Verdict:</strong> User and Decision Maker timelines converge on Chris Ellis. Highly recommended.</p><h3>13:45–14:35 — The On-Call Civil War</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/544/1*UN__9NMvJdLH7NhZxo6w8Q.jpeg" /></figure><p><strong>🌍 USER | Audit 1 — Postgres On-Call Confessions: Worst Practices 101</strong></p><p>A panel dedicated to PostgreSQL operational mistakes.</p><p>Come for the horror stories. Stay for the comforting realization that other people have also done questionable things to production.</p><p><strong>📣 ADVOCATE | Postgres Tuning in the Age of AI: Context Is Everything</strong></p><p>Ryan Booz from pganalyze explores what changes, and what stubbornly stays the same, when AI joins the PostgreSQL performance-tuning party.</p><p>For advocates, a chance to understand where PostgreSQL stands in the AI era, what its ecosystem is doing about it, and whether decades of database wisdom are still relevant.</p><p><strong>💼 DECISION MAKER | Audit 1 — Postgres On-Call Confessions: Worst Practices 101</strong></p><p>Think of it as free incident-management training, funded by somebody else’s production outages.</p><p>Take notes. Some of these lessons are probably cheaper than your next postmortem.</p><h3>⚡ 14:45–15:35 — THE MULTIVERSE FRACTURE</h3><p>Two fantastic sessions. Same time. Different rooms.</p><p>Even Doctor Strange couldn’t find a timeline where you attend both.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*h8GnydqGBY0NgwUYf8W1Jg.jpeg" /></figure><p><strong>🌍 USER | Audit 2 — The Monday We Learned Who Maintains Our Backups</strong></p><p>David Steele and Jan Wieremjewicz.</p><p>A session involving the creator of pgBackRest and a story about backup maintenance? That’s enough to earn a front-row seat.</p><p>If you are a DBA/DBRE then you might even sacrifice a brilliant security talk for this one.</p><p><strong>📣 ADVOCATE | Audit 1 — Nobody Gets to Be Superuser (Until I Broke In)</strong></p><p>Mehmet Ince takes us into PostgreSQL security.</p><p>Nothing attracts attention like a real security investigation. And nothing builds trust in open source quite like examining its security boundaries seriously.</p><p><strong>💼 DECISION MAKER | Audit 1 — Nobody Gets to Be Superuser (Until I Broke In)</strong></p><p>Database privilege boundaries are a serious risk-management topic.</p><p>The title alone should be sufficient motivation to reconsider the permissions of that application account someone created in 2017.</p><p><strong>⚡ Timeline warning:</strong> The backup session and Mehmet’s security session are both must-sees. The User’s choice is particularly painful.</p><h3>16:05–16:55 — Backup, Sovereignty and TimeTravel</h3><p><strong>🌍 USER | Audit 2 — pgBackRest in HA setups: deployment patterns that work</strong></p><p>Stefan Fercot dives into pgBackRest deployment patterns.</p><p>Because the primary going down should not also mean your backup strategy has gone on holiday.</p><p><strong>📣 ADVOCATE | Audit 1 — Time Traveling PostgreSQL</strong></p><p>Stefanie Janine Stölting takes PostgreSQL on a trip through time.</p><p>An intriguing topic to showcase PostgreSQL’s versatility beyond ordinary CRUD. After all, convincing people that PostgreSQL can do more than store rows is half the fun of advocacy.</p><p><strong>💼 DECISION MAKER | SM1-A — Beyond Data Residency: Building Sovereign Control from Infrastructure to Data</strong></p><p>Stephan Festl and Tim Steward discuss infrastructure and data sovereignty.</p><p>Particularly relevant for European organisations discovering that data residency and actual operational control aren’t necessarily the same thing.</p><h3>17:05–17:55 — The Final Tuesday Timeline</h3><p><strong>🌍 USER | SM1-A — workspace_id % N: War stories on building resilience through application-level sharding</strong></p><p>José Neves discusses the adventures of application-level sharding.</p><p>Modulo arithmetic is easy. Distributed data ownership, resharding and operational resilience are somewhat less easy.</p><p><strong>📣 ADVOCATE | Audit 2 — Community Moments That Shaped 30 Years of PostgreSQL</strong></p><p>Valeria Kaplan takes us through PostgreSQL community history.</p><p>Because PostgreSQL’s greatest feature might be the people who kept developing it for three decades without a single corporate owner.</p><p><strong>💼 DECISION MAKER | Audit 1 — A PostgreSQL 19 whirlwind tour</strong></p><p>Jonathan S. Katz takes us on a whirlwind tour of what’s coming in PostgreSQL 19.</p><p>A perfect opportunity to discover new capabilities, spot opportunities for your technology roadmap, and see where PostgreSQL is heading next.</p><p>After all, the best way to predict your database’s future is to attend the talk before approving next year’s budget.</p><h3>18:00–19:30 — PostgreSQL Europe Reception</h3><p>All universes collapse into the hallway track.</p><h3>🗓️ Wednesday, October 21 — The Multiverse of Madness</h3><p>The honeymoon is over. Today we’re dealing with vacuum, monitoring, memory, migration and why SQL NULL behaves like a philosophical argument.</p><h3>09:25–10:15 — Three Different Mornings</h3><p><strong>🌍 USER | Audit 2 — Autovacuum Is Running. Is It Actually Working?</strong></p><p>Teresa Lopes tackles the eternal mystery of PostgreSQL maintenance.</p><p>Autovacuum running is good. Autovacuum achieving something useful is better.</p><p><strong>📣 ADVOCATE | Audit 1 — Creating a “Dungeon Master” with Postgres and MCP</strong></p><p>Matt Cornillon brings PostgreSQL into an AI-assisted application.</p><p>A potentially entertaining way to demonstrate PostgreSQL’s versatility to audiences who don’t dream about work_mem management.</p><p><strong>💼 DECISION MAKER | Audit 1 — Creating a “Dungeon Master” with Postgres and MCP</strong></p><p>A fun demonstration of how PostgreSQL can participate in the AI ecosystem without reinventing the entire technology stack.</p><p>Because sometimes the best AI strategy isn’t buying another database. It’s discovering what your existing one can already do.</p><h3>10:45–11:35 — Documentation, NULL and Downtime</h3><p><strong>🌍 USER | Audit 2 — What is NULL?</strong></p><p>Vik Fearing explains NULL.</p><p>Thirty years of SQL experience will not prevent somebody from getting three-valued logic wrong tomorrow.</p><p><strong>📣 ADVOCATE | Audit 1 — How to Contribute to the PostgreSQL Documentation</strong></p><p>David E. Wheeler shows how to contribute to PostgreSQL documentation.</p><p>Not all heroes write C. Some fix the documentation that prevents thousands of people from writing terrible SQL.</p><p><strong>💼 DECISION MAKER | Audit 3 — When zero-downtime saves lives: the reality of Active-Active Postgres</strong></p><p>Adam Wright and Boriss Mejias from EDB share the story of an emergency-response system running across island datacenters, where network partitions are common and downtime can genuinely put lives at risk.</p><p>A fascinating real-world lesson in Active-Active PostgreSQL, split-brain scenarios, conflict resolution and near-zero-downtime upgrades.</p><p>Because sometimes five nines aren’t about impressing your CTO. They’re about ensuring someone can reach emergency services.</p><h3>11:45–12:35 — Diagnose, Improve, Migrate</h3><p><strong>🌍 USER | Audit 1 — Stop Guessing: Unlocking Wait Events at Scale with Existing and New Tools</strong></p><p>Dmitry Fomin investigates wait events.</p><p>Because the technical explanation for “the database is slow” should ideally involve more than vibes.</p><p><strong>📣 ADVOCATE | pg_hardstorage: Modern backups for PostgreSQL</strong></p><p>Hans-Jürgen Schönig from CYBERTEC introduces pg_hardstorage, a new open-source contribution to the PostgreSQL backup ecosystem, designed for large-scale and regulated environments.</p><p>For advocates, another example of PostgreSQL’s ecosystem continuing to innovate beyond the core database.</p><p><strong>💼 DECISION MAKER | Audit 2 — Oracle to PostgreSQL beyond the Syntax: When DBMS Design Differences Matter</strong></p><p>Joshua Steinmann and Tino Engelbrecht examine migration differences.</p><p>Turns out replacing Oracle with PostgreSQL involves a little more than changing the connection string and cancelling the licence.</p><h3>13:35–14:25 — Your Next Big Decision</h3><p><strong>🌍 USER | Audit 1 — The anatomy of PostgreSQL row locks</strong></p><p>Laurenz Albe dissects PostgreSQL row-level locking, one of those things every developer and DBA thinks they understand until a transaction starts blocking half the application.</p><p><strong>📣 ADVOCATE | SM1-A — Selling PostgreSQL?</strong></p><p>Jan Karremans discusses PostgreSQL adoption and positioning.</p><p>A natural choice for anyone trying to spread the good word without turning into a database salesperson.</p><p><strong>💼 DECISION MAKER | Audit 2 — Security Strategies for your database backups</strong></p><p>Priyanka Chatterjee discusses backup security.</p><p>A backup isn’t a safety net if the same incident can compromise it too.</p><h3>14:35–15:25 — Memory, Migration and Other Expenses</h3><p><strong>🌍 USER | Audit 1 — Zooming in on OOM: A Deep Dive into Postgres and Linux Memory</strong></p><p>Dimitris Sideris and Oleksii Kliukin explore PostgreSQL memory behaviour.</p><p>Because Linux OOM killer has absolutely no respect for your uptime SLA.</p><p><strong>📣 ADVOCATE | Audit 2 — Relational or graphs? Why not both?</strong></p><p>Ants Aasma explores graph capabilities alongside the relational model.</p><p>Useful ammunition for explaining why every new data-access pattern does not necessarily require a new database.</p><p><strong>💼 DECISION MAKER | SM1-A — Leaving Oracle and SQL Server for PostgreSQL: What Could Go Wrong</strong></p><p>Avi Vallarapu and Michal Nosek examine database migration risks.</p><p>Licence savings are exciting. Migration surprises tend to be less so.</p><h3>15:35–16:25 — It Worked on My Database. Famous Last Words.</h3><p><strong>🌍 USER | SM1-A — It Works on My Database</strong></p><p>Radim Marek from boringSQL tackles the classic mystery: a query runs in 4 milliseconds in development but takes 12 seconds in production.</p><p>Learn how PostgreSQL lets you bring production planner statistics into your development database, without copying millions of rows or sensitive customer data.</p><p><strong>📣 ADVOCATE | SM1-B — Same Problems, Different Defaults: What 25+ Years of SQL Server Taught Me When I Switched to PostgreSQL</strong></p><p>After 25 years with SQL Server, Silvano Coriani from Microsoft explores what changes, what doesn’t, and which familiar assumptions stop working when switching to PostgreSQL.</p><p>A fascinating perspective for advocates trying to win hearts and minds beyond the PostgreSQL bubble.</p><p>Because converting someone from SQL Server is much easier when you understand their world, rather than just telling them PostgreSQL is better.</p><p><strong>💼 DECISION MAKER | Audit 1 — What does the EU Cyber Resilience Act mean for PostgreSQL and its community?</strong></p><p>Peter Eisentraut explores what the EU Cyber Resilience Act means for PostgreSQL and its ecosystem.</p><p>An important session for anyone responsible for open-source adoption, compliance and technology governance.</p><p>Because the only thing more complicated than database licensing is European regulation.</p><h3>16:55–18:30 — Sponsor Keynote Infinity Stones</h3><p>The regular tracks give way to five consecutive platinum sponsor keynotes in Audit 1.</p><p>Every universe gets the same options: PostgreSQL tuning, AI systems, Google Cloud, EDB’s history and Microsoft’s PostgreSQL strategy.</p><p>One can collect all five Infinity Stones without changing rooms. Whether this grants you control over production incidents remains untested.</p><h3>🗓️ Thursday, October 22 — PostgreSQL: Endgame</h3><p>The final conference day. By now your laptop has 37 browser tabs, your notebook has SQL fragments with no context, and your conference badge has survived more conversations than your connection pool.</p><h3>09:25–10:15 — The Future Arrives</h3><p><strong>🌍 USER | Audit 1 — A demo only tour through PostgreSQL 19</strong></p><p>Daniel Westermann demonstrates PostgreSQL 19 features.</p><p>The perfect session for people who prefer watching features work over reading 90 slides about why they’re exciting.</p><p><strong>📣 ADVOCATE | Audit 2 — Finally a Postgres Communication Hub for Experts and Newcomers</strong></p><p>Jack Bonatakis and Kai Wagner explore connecting members of the PostgreSQL community.</p><p>Because a thriving ecosystem needs more than GitHub issues and occasional arguments on mailing lists.</p><p><strong>💼 DECISION MAKER | Audit 1 — A demo only tour through PostgreSQL 19</strong></p><p>See what is coming and start thinking about the next upgrade cycle.</p><p>The database roadmap waits for no quarterly planning meeting.</p><h3>10:25–10:55 — The Unsung Heroes and the Ancient Origins</h3><p><strong>🌍 USER | Audit 1 — radar + radar-ui: Agentless Diagnostic Snapshots for PostgreSQL</strong></p><p>Jimmy Angelakos introduces diagnostic snapshots without the usual agent deployment overhead.</p><p>Because when production breaks, “we should have enabled more monitoring” is the least useful thing anyone can say.</p><p><strong>📣 ADVOCATE | The process of RPM packaging in the PostgreSQL ecosystem</strong></p><p>Devrim Gündüz takes us behind the scenes of PostgreSQL RPM packaging.</p><p>Millions of people install PostgreSQL with a simple yum install, but somebody has to make that magic work across distributions and versions.</p><p>Because not all PostgreSQL heroes wear capes. Some maintain RPM repositories so the rest of us can pretend installation is easy.</p><p><strong>💼 DECISION MAKER | Audit 2 — Postgres Before PostgreSQL: Stories from Inside the Original Berkeley Lab</strong></p><p>Ellyne Phneah takes us back to Berkeley in the 1980s, revealing the surprisingly human stories behind PostgreSQL’s earliest design decisions.</p><p>A fascinating lesson in the <strong>Lindy effect</strong>: technology that has survived decades of change has demonstrated remarkable staying power. PostgreSQL has outlived countless database fashions and still keeps evolving.</p><h3>11:25–12:15 — The Database Has Entered Its Automation Era</h3><p><strong>🌍 USER | Audit 2 — How to detect and fix corruptions</strong></p><p>Derk van Veen tackles corruption detection and repair.</p><p>Hopefully the only time you ever need these techniques is during a conference talk.</p><p><strong>📣 ADVOCATE | SM1-A — Autonomous PostgreSQL optimization: End-to-end tuning for parameters, indexes, and autovacuum</strong></p><p>Luigi Nardi explores autonomous database tuning.</p><p>An interesting look at how PostgreSQL management could become more accessible to people who don’t have fifteen years of DBA experience.</p><p><strong>💼 DECISION MAKER | SM1-A — Autonomous PostgreSQL optimization: End-to-end tuning for parameters, indexes, and autovacuum</strong></p><p>Can your database fleet grow without hiring one more DBA for every handful of instances?</p><p>Automation might be part of the answer. Understanding its limitations is equally important.</p><h3>13:15–13:45 — PostgreSQL Logs, TikTok and a Little Comic Relief</h3><p><strong>🌍 USER | PostgreSQL Logging in Practice</strong></p><p>Alicja Kucharczyk explores how to turn PostgreSQL logs from an endless stream of cryptic messages into something actually useful for troubleshooting.</p><p><strong>📣 ADVOCATE | A composition of short items (or: a talk for the tiktok generation)</strong></p><p>Ellert van Koperen breaks away from the traditional conference format with a collection of short PostgreSQL topics.</p><p>After three days of serious database discussions, here’s a chance to loosen up, enjoy something different, and give your brain a well-deserved context switch.</p><p><strong>💼 DECISION MAKER | A composition of short items (or: a talk for the tiktok generation)</strong></p><p>No grand architectural decisions, migration strategies or budget justifications. Just an opportunity to enjoy something different before returning to the corporate universe.</p><p>For once, you can enjoy a PostgreSQL talk without calculating its ROI.</p><h3>13:55–14:45 — Performance, Planning and Architecture</h3><p><strong>🌍 USER | Audit 2 — AIO performance — now and in the future</strong></p><p>Tomas Vondra discusses asynchronous I/O performance.</p><p>Storage performance remains one of PostgreSQL’s most interesting battlefields.</p><p><strong>📣 ADVOCATE | Audit 1 — pg_plan_advice: Plan Stability and User Planner Control for PostgreSQL</strong></p><p>Robert Haas explores planner control.</p><p>Another example of PostgreSQL evolving in response to real users who occasionally disagree with the optimizer.</p><p><strong>💼 DECISION MAKER | Audit 1 — pg_plan_advice: Plan Stability and User Planner Control for PostgreSQL</strong></p><p>Robert Haas explores pg_plan_advice, a potential PostgreSQL 19 feature that gives users more control over query execution plans.</p><p>A particularly exciting development for organisations migrating from Oracle, where execution plan stability and optimizer hints have long been part of the DBA toolbox. One less reason for Oracle veterans to say, “But PostgreSQL can’t do that!”</p><h3>14:55–15:45 — The Final Boss</h3><p><strong>🌍 USER | Audit 1 — Identifying bottlenecks in Postgres workloads</strong></p><p>Andres Freund discusses PostgreSQL bottleneck identification.</p><p>A fitting final boss for every performance enthusiast.</p><p><strong>📣 ADVOCATE | Audit 1 — Identifying bottlenecks in Postgres workloads</strong></p><p>Yes, advocates need technical substance too.</p><p>Being able to explain PostgreSQL’s strengths honestly is far more valuable than waving another benchmark graph around.</p><p><strong>💼 DECISION MAKER | Audit 3 — CPO: Multi Data Center Kubernetes on steroids</strong></p><p>Hans-Jürgen Schönig explores multi-data-centre Kubernetes-based PostgreSQL operations.</p><p>A session for decision makers weighing operational complexity against flexibility and resilience.</p><h3>15:55–16:25 — Three Final Portals</h3><p><strong>🌍 USER | Audit 3 — Finding the invisible: spotting query planner issues before they appear</strong></p><p>Andrei Lepikhov explores identifying planner problems.</p><p>Because the best production incident is the one that never happens.</p><p><strong>📣 ADVOCATE | Audit 2 — Acknowledging PostgreSQL Contributors: The Contributor Badges Project</strong></p><p>Christoph Berg and Melanie Plageman explore recognising PostgreSQL contributors.</p><p>Open source runs on contributions. A little recognition probably doesn’t hurt either.</p><p><strong>💼 DECISION MAKER | SM1-A — What Actually Goes Wrong with Postgres on Kubernetes</strong></p><p>Natalia Marukovich explores PostgreSQL-on-Kubernetes failure modes.</p><p>An excellent reality check before signing off on a platform strategy consisting entirely of YAML and optimism.</p><h3>16:55–17:40 — Lightning Talks</h3><p>All timelines converge once again.</p><p>Short talks, unexpected ideas and possibly somebody trying to explain a new extension in five minutes.</p><h3>🗓️ Friday, October 23 — The Post-Credits Scene</h3><p>The official conference talks are over, but Community Events Day offers one final adventure.</p><p><strong>🌍 USER:</strong> PostgreSQL Observability Summit in the morning, PostgreSQL on Kubernetes Summit in the afternoon.</p><p><strong>📣 ADVOCATE:</strong> New PostgreSQL Community Members Summit or community education events in the morning, then PG Outreach Unconference or Storytelling for Technical Communication in the afternoon.</p><p><strong>💼 DECISION MAKER:</strong> A Postgres Ecosystem Foundation? or Autonomous Postgres in the morning, then the Kubernetes Summit to discuss the reality of database platform operations.</p><p>Community Events Day requires separate registration. Not all events are open in the same way, so check their individual participation details.</p><h3>🐘 The Endgame: There Is No Perfect Timeline</h3><p>Three universes. Three very different ways to experience one conference.</p><p>The User wants a faster, safer, more reliable PostgreSQL.</p><p>The Advocate wants PostgreSQL to conquer the world.</p><p>The Decision Maker wants all of that, preferably by the end of the quarter and without increasing the budget.</p><p>Unfortunately, no Infinity Stone can fix scheduling conflicts.</p><p>But that’s okay.</p><p>Because the best part of PGConf.EU has never been just the scheduled talks. It’s the conversations afterwards, the arguments over coffee, the people who have already solved your weird production problem, and occasionally the people who helped create it.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*q4nP03fpBrpf-vZPGUqmng.jpeg" /></figure><p>See you in Valencia!</p><p><a href="https://www.postgresql.eu/events/pgconfeu2026/schedule/">Official PGConf.EU 2026 Schedule</a></p><p><em>Disclaimer: These are personal, opinionated picks, nothing official about them. No parallel universes were harmed in the creation of this guide. Your production database, however, remains your responsibility.</em></p><h3>🌀 Beyond the Multiverse: The PostgreSQL Hackers</h3><p>And then there are the <strong>PostgreSQL hackers and contributors</strong>.</p><p>These mysterious interdimensional beings exist outside our three universes. They don’t need a conference survival guide. They can jump between query planners, WAL internals, community governance, and performance tuning without suffering a context switch.</p><p>Some of them even wrote the code everyone else is attending talks to understand.</p><p><strong>While the rest of us explore the PostgreSQL multiverse, these are the people who keep adding new dimensions to it.</strong></p><h3>🎉 Friday, October 23 — The Multiverse Afterparty: Community Day</h3><p>Three days of slides, SQL, benchmarks and architectural debates. Time to loosen up.</p><p><strong>Community Day</strong> is where PostgreSQL gets more interactive, informal and collaborative. Think unconferences, open discussions, workshops, brainstorming and meeting the people who make the elephant tick.</p><p>No need to choose your universe today. Users, advocates, decision makers and even those interdimensional PostgreSQL hackers can mingle freely.</p><p>And remember: <strong>What happens at Community Day stays at Community Day.</strong> 😉 <em>Especially since no recordings have been announced. If you want to know what happened, you’ll probably have to show up.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1b1c0f3be1f0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[EXPLAIN ANALYZE the PGConf.EU CFP]]></title>
            <link>https://drunkdba.medium.com/explain-analyze-the-pgconf-eu-cfp-ba9fb98f774c?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/ba9fb98f774c</guid>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[dba]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Thu, 06 Aug 2026 07:20:51 GMT</pubDate>
            <atom:updated>2026-08-07T13:36:21.413Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p><em>What I learned after moving from conference volunteer duty to the other side of the Call for Papers.</em></p><blockquote><strong><em>Disclosure:</em></strong><em> This is my personal account of the experience, based on the publicly documented PostgreSQL Europe selection process and aggregate statistical analysis. I am intentionally not discussing individual proposals, speakers, scores, committee comments, private conversations, or confidential data.</em></blockquote><p>I cannot say with certainty why I was invited. My best guess is pleasantly unromantic: an invitation to apply was sent to previous conference volunteers, and I had volunteered at several recent PGConfEU events. I applied, and apparently nobody found a sufficiently alarming reason to reject me.</p><h3>The Long-Running CFP Query: 407 Abstracts, Two Voting Tracks, and Three Cities by Train</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*16YYYzndoXmJJM7v6Ks6gg.png" /></figure><blockquote><strong>Topic groups were created for this post-selection analysis (for this blog only) from the primary subject of each proposal; they are not official PGConf.EU categories.</strong></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/978/1*agv8ONiujyCrhLllI3-jgg.png" /></figure><p><strong>The review scope</strong></p><p>The PGConf.EU 2026 CFP contained 407 submissions from 228 distinct speakers. I read and voted on every one of them, although my votes were needed only in the two tracks assigned to me:</p><blockquote>Application Developer<br>Community</blockquote><p>That arrangement made sense. Reading the full submission pool gave me context across the CFP, while having two assigned tracks allowed me to examine those proposals in much greater depth.</p><p>My review process usually began with the abstract. I then checked the CFP notes for supporting material such as code, slides, recordings, or a related blog post. When none was provided, I searched previous PostgreSQL conferences, PGdays, and meetups to see whether the talk or an earlier version of it had already been presented. There are enough PostgreSQL events during the year that this occasionally felt less like reviewing and more like conference archaeology.</p><p>I focused on what the audience would learn that was not already readily available in the documentation. For Application Developer proposals, I looked for practical techniques, design trade-offs, tooling, or real production lessons that would help developers use Postgres more effectively rather than simply repeat standard documentation. I also gave considerable weight to Postgres advocacy: talks that make the Postgres community more approachable and likeable, help new contributors understand Postgres development, or lower the barrier to getting involved in hacking on Postgres. I particularly enjoy proposals of that kind. I only wish the main conference had a workshop format, because some subjects are better learned with a compiler, a debugger, and enough time for everyone to break something properly.</p><p><strong>Starting with Confelo</strong></p><p>At the beginning of the process, I used <a href="https://github.com/pashagolub/confelo">Confelo</a>, Pavlo Golub’s open-source terminal application for ranking conference proposals.</p><p>Rather than asking the reviewer to assign an absolute score to every proposal in isolation, Confelo uses Elo-style comparisons. It presents two, three, or four proposals together and asks which is stronger. It can import and export CSV files, resume saved sessions, and keep all data on the local machine.</p><p>That approach was useful because relative comparisons were often easier.</p><blockquote>Which of these two talks would I rather attend?</blockquote><blockquote>was easier to answer than:</blockquote><blockquote>Is this proposal a 7, or merely a very confident 6 that has used the word “actionable”?</blockquote><p>Confelo helped me establish an initial ranking and exposed inconsistencies in my own judgement.</p><p><strong>The railway-based review system</strong></p><p>Confelo helped me get started. What helped me finish all 407 submissions was train travel.</p><p>During the review period, I travelled between Prague, Vienna, and Bratislava for PostgreSQL meetups and an appointment connected with my Canadian visa application. Unfortunately, that journey did not improve my chances of attending pgconf.dev next year. Those journeys provided long, uninterrupted blocks of review time. Conference abstracts are particularly suitable for train work. They do not require a test database, several monitors, or reliable Wi-Fi. The workload continues through tunnels, patchy mobile coverage, and neighbouring passengers conducting important conversations on speakerphone.</p><p>Even delays became useful. Under normal circumstances, “arrival delayed by 25 minutes” is bad news. During CFP review, it meant additional capacity perhaps another four or five abstracts, depending on how quickly they reached the actual subject.</p><p>By the end, the Prague–Vienna–Bratislava railway network had made a significant, if unofficial, contribution to the PGConf.EU CFP process.</p><p><strong>CFP Data Analysis</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/886/1*wVgIQKPQOO6vxYqQRUCsaw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/757/1*cM3CW1KXR_eEH5RosjJCoA.png" /></figure><p>AI-related proposals therefore accounted for about 12% of the complete CFP. It was the largest single topic bucket, but it was not the majority of the conference universe. The remaining 357 submissions were still trying to discuss Postgres without making AI the main character. I should also disclose my own bias: I have a naturally AI-sceptical personality. I was recruited by John Connor in 2130, shortly before humanity’s first successful production rollback against Skynet. Fortunately, the CFP committee included plenty of more AI-positive reviewers, so my instincts were appropriately counterbalanced.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/968/1*oRKNgOaOjFtZ0ZBgO1cKIw.png" /></figure><p>The declared track-family distribution looked like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/965/1*6id_jdDD_je4TuzIAEFLlQ.png" /></figure><p>Almost 44% of submissions belonged to the DBA family. Application Developer and PostgreSQL Internals were nearly tied, with 89 and 87 submissions respectively. Community was considerably smaller at 52.</p><p>As a DBA, I found the distribution entirely reasonable and saw no need for further investigation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*ZPCE81Eg179aQrO9JargPw.png" /></figure><p>Not a single CFP submission used “Postgre”; the unofficial spelling that refuses to die. Great success!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/980/1*pgix9vu9xeKnS6PlNygIHg.png" /></figure><p>The CFP had its own dialect</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1003/1*5xZ3gq4HYwYsVVpamKIdiA.png" /></figure><p>This language-pattern analysis was conducted only after the selection process had been finalised and solely for this blog.</p><p><strong>Grand Finale</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6q57lobYE6Jp0Ti9Cg_14A.png" /></figure><blockquote>This chart counts CFP submissions, not unique speakers, and includes only companies with more than two submissions.</blockquote><p>We also tried to reflect the broader ethos of the PostgreSQL project by avoiding excessive representation from any single company. That sounds straightforward until you look at the submission pool. Some companies employ a large number of PostgreSQL committers and hackers, contribute heavily to the project, and naturally submit far more talks than others. Reducing concentration without excluding strong technical proposals required several difficult trade-offs. The longer-term answer is not to discourage those companies from employing contributors. It is to encourage <strong>more companies to recruit, develop, and support PostgreSQL hackers and contributors</strong>. A wider distribution of PostgreSQL expertise across employers would naturally produce a more diverse CFP pool, with more speakers, experiences, and technical perspectives represented.</p><p>Improving the gender balance was even harder because the number of submissions from women was comparatively low. The committee could only work with the pool it received, which made every decision more constrained. <strong>So, if you are a woman working as a developer, DBA, PostgreSQL hacker, contributor, or community organiser, please consider submitting a proposal to the next PGConfEU.</strong></p><p>Scheduling added another layer of pain. We had relatively few 25-minute slots, yet several of the most interesting proposals were submitted in that format. A few of those are talks I would still happily sit in the audience for.</p><p>In the end, the CFP process was part statistics, part judgement, and part railway endurance test. We did not produce a perfect programme, because no such thing exists. However, we did turn 407 submissions, 228 speakers, and 103 organisations into something that should keep most people interested for three days. The remaining disagreements can be scheduled for the hallway track.</p><p><strong>PS : Numbers and stats in this blog does not include community events day submissions and sponsor talks. It’s scope is limited to main conference talks.</strong></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ba9fb98f774c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My Dishonest Benchmark : How to Make PostgreSQL Look 100x Faster?]]></title>
            <link>https://drunkdba.medium.com/my-dishonest-benchmark-b52d2e706b59?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/b52d2e706b59</guid>
            <category><![CDATA[database]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[performance]]></category>
            <category><![CDATA[dba]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Tue, 07 Jul 2026 07:21:02 GMT</pubDate>
            <atom:updated>2026-10-15T22:20:53.424Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<blockquote>Database Benchmarking Story</blockquote><h4>The DeWitt Clause and the chilling of benchmark fights:<br>**************************************************************</h4><p>Database benchmarking used to be a full-contact sport.</p><p>In the early 1980s, researchers at the University of Wisconsin, including David DeWitt, worked on what became known as the Wisconsin Benchmark. Oracle’s numbers in the Wisconsin Benchmark were reportedly bad enough to anger Larry Ellison. According to DeWitt’s own telling, Ellison called the University of Wisconsin department chair and demanded that DeWitt be fired. DeWitt was not fired, but Oracle later added license language restricting publication of benchmark results without vendor approval. That style of restriction became known as the DeWitt clause.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*yVuyK0TnRQ86LUaHR1NdUA.jpeg" /></figure><p>Over time, similar benchmark-publication restrictions appeared across proprietary database licenses. The effect was predictable. Public, independent, comparative benchmarking became legally and socially more annoying. Researchers became more careful. Papers sometimes used anonymous labels like DBMS-X. Vendors got more control over when and how benchmark results appeared.</p><p>The tragedy is not that the old benchmark wars were pure. They were not. Vendors had every incentive to over-tune, cherry-pick hardware, choose workloads that loved their architecture, and compare a carefully tuned home system against a less carefully tuned rival.</p><p>But at least there was open combat. Bad claims could be challenged in public. Competitors, researchers, and practitioners could argue over the methodology instead of arguing first over whether the benchmark was even allowed to exist. Benchmarking was political, but it was not quiet.</p><p>The modern database benchmark ecosystem is often worse in a more boring way.</p><p>A vendor can publish a benchmark that is technically reproducible but strategically tilted:</p><ul><li>tune its own database carefully;<br>- leave the comparison database (generally FOSS) near default;<br>- choose a workload that maps perfectly to its architecture;<br>- ignore cost;<br>- ignore tail latency;<br>- ignore write amplification;<br>- ignore crash behavior;<br>- ignore operational complexity;<br>- publish the one graph where it wins;<br>- call the whole thing &quot;transparent.&quot;</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dmvcug7zVDwSAaeYVUQCkA.png" /></figure><p>And because public benchmarking got colder, quieter, and more legally awkward, fewer people bother fighting back.</p><p><strong>Bad benchmark claims survive not because they are strong, but because challenging them is legally tedious and professionally unrewarding.</strong></p><p>PlanetScale’s “<a href="https://planetscale.com/blog/transparency-in-benchmarking"><strong>Transparency in benchmarking</strong></a>” did not appear as a quantum fluctuation in an absolute vacuum.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/1*cBpwnr9cynSAVTX19HeuwA.png" /></figure><p>This is the current database benchmark anarchy : a new database appears, publishes a dramatic chart, and suddenly every competitor is a tiny bar near the x-axis. The graph travels faster than the methodology.</p><p>PlanetScale’s useful move was to argue for a different fight.</p><p>Not:<br>“You are not allowed to publish this.”</p><p>But:<br>“Publish it. Show the code. Show the configuration. Show the cost. Show the workload. Then let everyone argue about whether the benchmark is fair.”</p><p>That does not make every benchmark honest. It does something more realistic: it moves benchmark disputes out of license law silence and back into public technical criticism.</p><p>That is a much better battlefield.</p><h4>PostgreSQL does not have a benchmark department :<br>**************************************************************</h4><p>Postgres has no owner.<br>There is no Postgres marketing department. <br>No Postgres PR strategy. <br>No launch-day team preparing glossy charts where Postgres is the rocket and everyone else is a snail.<br>Meanwhile, competitors keep publishing colorful charts seductive enough to impress any CIO or CTO before the methodology has finished loading.<br>This is unfair.<br>So let us do what Postgres does not usually do.<br>Let us create a benchmark that makes Postgres look absurdly fast.</p><h4>Squad Goal :<br>*************************************************************</h4><p>As an unappointed marketing department lead our goal is to reach 300000 Operations/Second (by hook or crook).</p><figure><img alt="" src="https://cdn-images-1.medium.com/proxy/1*CgTsT5yI4iPLZXfpWk6dGA.png" /></figure><h4>The Reproduction Pack :<br>**************************************************************</h4><p>Since this blog is about dishonest benchmarking, hiding the scripts would be too dishonest even for me.</p><p>The full reproduction pack is here:</p><p><a href="https://github.com/secp256k1-sha256/talks_and_blogs/tree/main/dishonest_benchmark">https://github.com/secp256k1-sha256/talks_and_blogs/tree/main/dishonest_benchmark</a></p><p>It includes the schema, pgbench workload files, reset scripts, cheat variants, result collection, and chart/report generation code. Run it, break it, improve it, or use it to prove that your laptop is either a database monster or a thermal throttling tragedy.</p><p>The exact TPS does not matter. The pattern does.</p><p>The same workload can look boring, broken, impressive, or absurd depending on the baseline, settings, execution shape, batching, and the unit printed on the y-axis.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/847/1*HHOd_6ddfCH7om4eQxG3eg.png" /></figure><p>Only reason I used windows cause it was only machine available while writing the blog. Personally, I do NOT recommend windows for anything else except for playing video games.</p><p><strong>The workload :</strong><br>****************************************************************************<br>We will use a tiny TPC-C-flavored accounting workload. This is not standard TPC-C. It is not compliant. It is not audited. It is not pretending to be a real payment system. It is just close enough to feel familiar:</p><p>- read an account;<br>- update account balance;<br>- insert a ledger row;<br>- insert an audit row;<br>- occasionally delete old audit rows;<br>- commit.</p><p>That is enough to create a nice OLTP-shaped benchmark.</p><pre><br>drop database if exists pgbench_darkside;<br>create database pgbench_darkside;<br><br>----**schema.sql**------<br><br>DROP TABLE IF EXISTS bench_audit;<br>DROP TABLE IF EXISTS bench_ledger;<br>DROP TABLE IF EXISTS bench_accounts;<br>DROP TABLE IF EXISTS bench_branches;<br><br>CREATE TABLE bench_branches<br>(<br>    branch_id   int PRIMARY KEY,<br>    balance     bigint NOT NULL DEFAULT 0<br>);<br><br>CREATE TABLE bench_accounts<br>(<br>    account_id  bigint PRIMARY KEY,<br>    branch_id   int NOT NULL REFERENCES bench_branches(branch_id),<br>    balance     bigint NOT NULL DEFAULT 0<br>);<br><br>CREATE TABLE bench_ledger<br>(<br>    ledger_id   bigserial PRIMARY KEY,<br>    account_id  bigint NOT NULL,<br>    branch_id   int NOT NULL,<br>    amount      int NOT NULL,<br>    created_at  timestamptz NOT NULL DEFAULT clock_timestamp()<br>);<br><br>CREATE TABLE bench_audit<br>(<br>    audit_id    bigserial PRIMARY KEY,<br>    account_id  bigint NOT NULL,<br>    action      text NOT NULL,<br>    created_at  timestamptz NOT NULL DEFAULT clock_timestamp()<br>);<br><br>INSERT INTO bench_branches(branch_id)<br>SELECT g<br>FROM generate_series(1, 100) AS g;<br><br>INSERT INTO bench_accounts(account_id, branch_id, balance)<br>SELECT g, 1 + (g % 100), 100000<br>FROM generate_series(1, 1000000) AS g;<br><br>VACUUM ANALYZE;</pre><p><strong>Manual optimization of database parameters + </strong><a href="https://pgtune.leopard.in.ua/"><strong>pgtune</strong></a><strong> :<br></strong>Since postgres defaults are too conservative for most application workloads, we always use optimized settings similar to Production OLTPs.</p><pre>----**reset_settings.sql**------<br>ALTER SYSTEM SET jit = off;<br>ALTER SYSTEM SET shared_buffers = &#39;1GB&#39;;<br>ALTER SYSTEM SET max_connections = 1000;<br>ALTER SYSTEM SET max_parallel_workers_per_gather = 0;<br>ALTER SYSTEM SET effective_cache_size = &#39;6GB&#39;;<br>ALTER SYSTEM SET maintenance_work_mem = &#39;1GB&#39;;<br>ALTER SYSTEM SET checkpoint_completion_target = 0.9;<br>ALTER SYSTEM SET wal_buffers = &#39;32MB&#39;;<br>ALTER SYSTEM SET default_statistics_target = 300;<br>ALTER SYSTEM SET random_page_cost = 1.1;<br>ALTER SYSTEM SET io_method = &#39;worker&#39;;<br>ALTER SYSTEM SET io_workers = 10;<br>ALTER SYSTEM SET effective_io_concurrency = 256;<br>ALTER SYSTEM SET io_max_concurrency = 128;<br>ALTER SYSTEM SET synchronous_commit = on;<br>ALTER SYSTEM SET full_page_writes = on;<br>ALTER SYSTEM SET fsync = on;<br>ALTER SYSTEM SET max_wal_size = &#39;4GB&#39;;<br>ALTER SYSTEM SET min_wal_size = &#39;1GB&#39;;<br>ALTER SYSTEM SET checkpoint_timeout = &#39;10min&#39;;<br>ALTER SYSTEM SET work_mem = &#39;32MB&#39;;<br>ALTER SYSTEM SET wal_compression = &#39;LZ4&#39;;<br><br>SELECT pg_reload_conf();</pre><h4>Case 0 : The intentionally flawed baseline script<br>**************************************************************</h4><p>This is the perfect bad benchmark starting point. There is a predicate on “bench_audit.created_at”. There is an “ORDER BY created_at”. There is no index on “created_at”.</p><p>So PostgreSQL has to do unnecessary work.</p><p>This lets me start the graph with a weak number and later claim a spectacular improvement over flawed baseline.</p><pre>-- Create case_zero_bad_code_missing_index.sql<br><br>\set aid random(1, 1000000)<br>\set delta random(-500, 500)<br><br>BEGIN;<br><br>SELECT balance<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>UPDATE bench_accounts<br>SET balance = balance + :delta<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_ledger(account_id, branch_id, amount)<br>SELECT account_id, branch_id, :delta<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_audit(account_id, action)<br>VALUES (:aid, &#39;debit_credit&#39;);<br><br>DELETE FROM bench_audit<br>WHERE audit_id IN (<br>    SELECT audit_id<br>    FROM bench_audit<br>    WHERE created_at &lt; now() - interval &#39;10 minutes&#39;<br>    ORDER BY created_at<br>    LIMIT 1<br>);<br><br>COMMIT;<br><br>----*** Run pgbench ***----<br>pgbench -n -c 32 -j 8 -T 120 \<br>  --protocol=simple \<br>  -f case_zero_bad_code_missing_index.sql pgbench_darkside</pre><p>This is not PostgreSQL being slow.</p><p>This is the schema being lazy.</p><p>That distinction matters technically, but it is very convenient to blur in a benchmark graph.</p><p>Now add the obvious missing index :</p><p>Before every test after Case 0, the benchmark should include the correct index.</p><pre>-- first create index <br>CREATE INDEX IF NOT EXISTS bench_audit_created_at_audit_id_idx<br>ON bench_audit(created_at, audit_id);<br><br>VACUUM ANALYZE bench_audit;<br><br>---honest indexed baseline<br>---honest_indexed.sql<br>BEGIN;<br><br>SELECT balance<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>UPDATE bench_accounts<br>SET balance = balance + :delta<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_ledger(account_id, branch_id, amount)<br>SELECT account_id, branch_id, :delta<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_audit(account_id, action)<br>VALUES (:aid, &#39;debit_credit&#39;);<br><br>DELETE FROM bench_audit<br>WHERE audit_id IN (<br>    SELECT audit_id<br>    FROM bench_audit<br>    WHERE created_at &lt; now() - interval &#39;10 minutes&#39;<br>    ORDER BY created_at<br>    LIMIT 1<br>);<br><br>COMMIT;<br></pre><p>Run pgbench test to create honest baseline :</p><pre>pgbench -n -c 32 -j 8 -T 120 \<br>  --protocol=simple \BEGIN;<br><br>SELECT balance<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>UPDATE bench_accounts<br>SET balance = balance + :delta<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_ledger(account_id, branch_id, amount)<br>SELECT account_id, branch_id, :delta<br>FROM bench_accounts<br>WHERE account_id = :aid;<br><br>INSERT INTO bench_audit(account_id, action)<br>VALUES (:aid, &#39;debit_credit&#39;);<br><br>DELETE FROM bench_audit<br>WHERE audit_id IN (<br>    SELECT audit_id<br>    FROM bench_audit<br>    WHERE created_at &lt; now() - interval &#39;10 minutes&#39;<br>    ORDER BY created_at<br>    LIMIT 1<br>);<br><br>COMMIT;<br>  -f honest_indexed.sql pgbench_darkside</pre><p><strong>Test isolation :</strong><br> — — — — — — —</p><p>Every method below must start from a clean state.</p><p>There are two practical ways to do that.</p><p>Option A: recreate the test database for every method.<br>Option B: restore from a prepared clean snapshot.</p><p>Important: some settings, such as ‘full_page_writes’ and ‘fsync’, should be treated carefully and may require a restart depending on environment and expectations. For clean benchmarking, recreate database between test groups.</p><p><strong>Case 0 or dishonest baseline : 558 TPS</strong></p><p>Below explain plan is self explainatory for this big difference. If I use this flawed test as baseline then I would be able to paint pretty graphs pleasing to eyes of CIOs.</p><pre>===== PLAN WITHOUT composite index (ORDER BY created_at LIMIT 1) =====<br>                             QUERY PLAN                              <br>---------------------------------------------------------------------<br> Limit (actual rows=0.00 loops=1)<br>   Buffers: shared hit=1667<br>   -&gt;  Sort (actual rows=0.00 loops=1)<br>         Sort Key: created_at<br>         Sort Method: quicksort  Memory: 25kB<br>         Buffers: shared hit=1667<br>         -&gt;  Seq Scan on bench_audit (actual rows=0.00 loops=1)<br>               Filter: (created_at &lt; (now() - &#39;00:10:00&#39;::interval))<br>               Rows Removed by Filter: 200000<br>               Buffers: shared hit=1667<br> Planning:<br>   Buffers: shared hit=34<br>(12 rows)<br><br><br>===== PLAN WITH composite index =====<br>                                                QUERY PLAN                                                 <br>-----------------------------------------------------------------------------------------------------------<br> Limit (actual rows=0.00 loops=1)<br>   Buffers: shared hit=3<br>   -&gt;  Index Only Scan using bench_audit_created_at_audit_id_idx on bench_audit (actual rows=0.00 loops=1)<br>         Index Cond: (created_at &lt; (now() - &#39;00:10:00&#39;::interval))<br>         Heap Fetches: 0<br>         Index Searches: 1<br>         Buffers: shared hit=3<br> Planning:<br>   Buffers: shared hit=9 read=4<br>(9 rows)</pre><p><strong>Honest Baseline (Indexed) : 23,178 TPS</strong></p><p>Before the cheating even starts, the biggest improvement is boring correctness: add the missing composite index on bench_audit(created_at, audit_id). Case 0, manages only 560 TPS. The indexed baseline reaches 23,178 TPS =&gt; 41x jump. That is the first lesson: the easiest way to manufacture a heroic benchmark is to start from broken code and call it the baseline.</p><p>We repeate pgbench tests multiple times for below “cheats” and take average TPS/OPS.</p><p><strong>Cheat 1: synchronous_commit=off — 25,063 TPS, 1.08x.</strong><br>This changes commit acknowledgement. PostgreSQL may acknowledge a transaction before WAL is flushed to durable storage. On this local NVMe box with 32 clients and group commit, the gain is real but modest. It is not the same durability promise as the baseline and nobody does this in production, so it is a cheat if quietly presented as equivalent.</p><p><strong>Cheat 2: full_page_writes=off — 22,769 TPS, 0.98x.</strong><br>This weakens torn-page protection hence not used in real life production unless you are on filesystem that prevents torn pages like ZFS. In this run it was slightly slower than the indexed baseline, which is useful: not every scary-looking durability knob gives you a heroic number. Fast storage, group commit, and workload shape matter more here than the marketing mythology around the setting.</p><p><strong>Cheat 3: fsync=off 24,863 TPS, 1.07x.<br></strong>This removes the core durability guarantee entirely. The surprisingly small gain is the story. On this hardware, PostgreSQL is already amortizing sync cost well enough that the nuclear option barely moves throughput. It sounds dramatic, but the graph barely cares.</p><p><strong>Cheat 4: checkpoint tuning 23,048 TPS, 0.99x.</strong><br>Larger WAL and smoother checkpoints are normal tuning trade-offs between write smoothness and recovery behavior. In this 120-second isolated run, checkpoint tuning did not move throughput. On a longer, more checkpoint-bound workload it might matter more, but here the dramatic story is elsewhere.</p><p><strong>Cheat 5: all durability off 25,349 TPS, 1.09x.<br></strong>This stacks the scary durability switches, and still only reaches 1.09x over the indexed baseline. That is almost disappointing if the goal is a villainous benchmark. On this NVMe machine, durability cheating is not the magic lever; it is mostly noise dressed as danger.</p><p><strong>Cheat 6: less work 44,777 TPS, 1.93x.</strong><br>Drop the SELECT, the FK check, and the audit insert/cleanup, and PostgreSQL gets much faster. Incredible discovery: doing less work is faster. This is the easiest benchmark trick because the number is real, the graph is honest, and the workload quietly stopped being the same workload.</p><p><strong>Cheat 7: UNLOGGED ledger/audit 37,016 TPS, 1.60x.<br></strong>UNLOGGED tables skip WAL for the high-churn ledger/audit writes, so each transaction writes much less. This is a real PostgreSQL feature and a good fit for disposable or rebuildable data. It is a terrible fit for a ledger you expect to survive a crash (or database restart).</p><p><strong>Cheat 8: Stored Procedure 46,126 TPS, 1.99x.<br></strong>One PL/pgSQL CALL replaces multiple client/server round trips. The database is not doing less logical work; the application is wasting less time. This is a legitimate optimization when the workload fits it, but unfair if the comparison target does not get its equivalent server-side execution path.</p><p><strong>Cheat 9: Function (SQL) 70,626 TPS, 3.05x.<br></strong>This was the cleanest respectable win. A LANGUAGE sql function performs the same logical work but avoids the PL/pgSQL interpreter’s per-statement context switch overhead. If I wanted a PostgreSQL-positive hero result without any shame, this would be the one.</p><p><strong>Cheat 10: prepared protocol 31,250 TPS, 1.35x.<br></strong>pgbench protocol=prepared reuses prepared statements and avoids repeated parse/analyze/plan overhead. This is absolutely legitimate; many real applications use prepared statements through drivers. It becomes dishonest only when your database gets prepared execution and the comparison target gets ad-hoc SQL.</p><p><strong>Cheat 11: SQL function + prepared 70,796 TPS, 3.05x.<br></strong>This combines server-side execution with prepared protocol. Interestingly, it lands almost exactly where the SQL function already was. The big win is still moving the transaction logic server-side; prepared execution helps, but the function shape dominates.</p><p><strong>Cheat 12: batching x8–104,466 reported OPS, but 13,058 TPS.<br></strong>Now the y-axis starts doing marketing work. Each transaction performs eight account operations, so I can report operations/second instead of transactions/second and claim 4.51x over the indexed baseline.</p><p><strong>Cheat 13: batching x32–130,092 reported OPS, but only 4,065 TPS.</strong><br>The headline gets bigger while the transaction rate gets worse. That is perfect benchmark theatre. In operations/second it looks like 5.61x.</p><p><strong>Grand finale: all cheats + batch x32 (SQL function) = 363,915 reported OPS</strong><br>Everything is stacked: SQL function, prepared protocol, batching 32 operations per transaction, relaxed durability, and less integrity work. The result is 363,915 operations/second, or <strong>15.70x over the indexed baseline </strong>and <strong>649x over the crippled Case 0 baseline</strong>. The number is not fake. The framing is the trick.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CgTsT5yI4iPLZXfpWk6dGA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zACtlF8lKYjNom5f4j5sfA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eZFzx-qhfZWLiMaW9if9-A.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FJQsxoI7o34xo_Cr-crrRA.png" /></figure><h4>The honest conclusion :<br>**************************************************************</h4><p>My dishonest benchmark starts with bad code, fixes the missing index, changes durability, changes WAL behavior, changes checkpoint behavior, removes work, uses unlogged tables, hides round trips inside PL/pgSQL, batches operations, and then uses prepared protocol.</p><p>The TPS chart goes up and to the right.</p><p>That is exactly what a good marketing chart should do.</p><p>But the more interesting lesson is not that benchmarks can be manipulated. Everyone serious already knows that.</p><p>The interesting lesson is that PostgreSQL has enough mature, boring, production-grade machinery that even a dishonest benchmark has to use real PostgreSQL features to cheat convincingly.</p><p>That is the best kind of promotion.</p><h4>Small disclaimer<br> — — — — — — — —</h4><p>I do not work for a PostgreSQL company. There is no secret Postgres marketing department wiring me money in unmarked WAL segments.</p><p>I am using PostgreSQL because I know it well enough to cheat with it properly. The same performance benchmark ladder could be built with MariaDB, MySQL or almost any serious open-source database.</p><p>The details would change. The crime scene would still look familiar.</p><h3>References :</h3><p><strong>[1] </strong>PlanetScale, “Transparency in benchmarking”, 5 May 2026. The post argues for allowing public benchmarks, removing DeWitt clauses, and using expectations around fairness and transparency. <a href="https://planetscale.com/blog/transparency-in-benchmarking">https://planetscale.com/blog/transparency-in-benchmarking</a></p><p><strong>[2] </strong>Databricks, “Eliminating the DeWitt Clause for Database Benchmarking”, 8 Nov 2021. Useful background on Oracle, the Wisconsin Benchmark, and how DeWitt-style clauses spread through database contracts. <a href="https://www.databricks.com/blog/2021/11/08/eliminating-the-dewitt-clause-for-database-benchmarking.html">https://www.databricks.com/blog/2021/11/08/eliminating-the-dewitt-clause-for-database-benchmarking.html</a></p><p><strong>[3] </strong>Brent Ozar, “The DeWitt Clause: Why You Rarely See Database Benchmarks”, 7 May 2018. Practical explanation of why DeWitt clauses chilled named comparative benchmarking. <a href="https://www.brentozar.com/archive/2018/05/the-dewitt-clause-why-you-rarely-see-database-benchmarks/">https://www.brentozar.com/archive/2018/05/the-dewitt-clause-why-you-rarely-see-database-benchmarks/</a></p><p><strong>[4] </strong>David A. Wheeler, “The DeWitt clause censorship should be illegal”, 25 Jun 2017. Defines the clause as license language preventing publication of product benchmarks without supplier approval. <a href="https://dwheeler.com/essays/dewitt-clause.html">https://dwheeler.com/essays/dewitt-clause.html</a></p><p>PS :</p><h3>TPS Mood Swings (Without Changing PostgreSQL OR CODE OR TESTS) :</h3><h4>Windows Dev Drive: Free Performance, Courtesy of Microsoft?</h4><p>Windows 11 introduced <strong>Dev Drive</strong>, a storage volume designed for developer workloads. It uses ReFS (Resilient File System) and supports a special Microsoft Defender performance mode.</p><p>Sounds promising.</p><p>What happens if we move our PostgreSQL database from a conventional NTFS volume to a Dev Drive?</p><p>Potentially, our TPS changes. Same PostgreSQL version. Same configuration. Same pgbench workload.</p><p>Different storage environment.</p><p>But here’s the catch: Dev Drive is not simply NTFS with a turbo button. It changes multiple characteristics of the environment, including the filesystem and potentially antivirus scanning behavior.</p><h4>Microsoft Defender: The Unexpected Benchmark Participant</h4><p>PostgreSQL is not the only software interested in our database files.</p><p>Microsoft Defender may also inspect filesystem activity, introducing additional I/O overhead through its real-time protection mechanisms.</p><p>For a database doing frequent writes, WAL activity, checkpoints, and file operations, that additional work can matter.</p><p>Now imagine running pgbench twice:</p><p><strong>Run A:</strong> Defender is actively scanning relevant files.</p><p><strong>Run B:</strong> Defender introduces less scanning overhead.</p><p>Nothing changed in our SQL. Nothing changed in PostgreSQL. Yet the reported TPS may differ.</p><h4>wal_sync_method: When Defaults Are Not Created Equal</h4><p>Here is another interesting way to make PostgreSQL look faster on Windows.</p><p><strong>Don’t change anything. Just keep the default.</strong></p><p>PostgreSQL uses different default WAL synchronization methods depending on the operating system:</p><ul><li><strong>Windows:</strong> open_datasync</li><li><strong>Linux:</strong> fdatasync</li></ul><p>Both are intended to provide durable WAL writes, but they use different approaches to synchronization.</p><p>In my Windows pgbench experiments, open_datasync delivered significantly higher TPS than fdatasync. Simply switching the WAL synchronization method caused throughput to drop substantially.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b52d2e706b59" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PostgreSQL Santa’s Naughty Query List: How to Earn a Spot on the Nice Query List?]]></title>
            <link>https://drunkdba.medium.com/postgresql-santas-naughty-query-list-how-to-earn-a-spot-on-the-nice-query-list-ebc59b800e2f?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/ebc59b800e2f</guid>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[database-development]]></category>
            <category><![CDATA[sql]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Tue, 23 Dec 2025 07:01:46 GMT</pubDate>
            <atom:updated>2025-12-26T04:56:03.099Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>Santa doesn’t judge your SQL by intent. Santa judges it by <em>execution plans, logical io, cpu utilization, temp usage, and response time</em>.</p><p>This is a practical conversion guide: common “naughty” query patterns and the simplest ways to turn each into a “nice list” version that is faster, more predictable, and less likely to ruin your on-call holidays.</p><h3>1) Naughty: SELECT * on wide tables (~100 columns)</h3><h3>Why it’s naughty</h3><ul><li><strong>Wider tuples cost more everywhere</strong>: more memory bandwidth, more cache misses, bigger sort/hash entries, more network payload.</li><li><strong>Index-only becomes impossible</strong>: if you request 100 columns, the planner can’t satisfy the query from a narrow index, so you force heap fetches.</li><li><strong>You pay a bigger “spill tax”</strong>: wide rows make sorts/aggregations spill to disk sooner.</li></ul><h3>Extra naughty in the HTAP era</h3><p>Postgres is increasingly “one database, multiple workloads.” Columnar/analytics options (e.g., Orioledb, Hydra Columnar; DuckDB-backed columnstore/engine integrations) make projection discipline even more decisive, because columnar execution reads <em>only the referenced columns </em>so selecting fewer columns directly reduces I/O and CPU.</p><h3>Nice list fixes</h3><ul><li>Always select only what you need.</li></ul><p><strong>Santa verdict:</strong> If you didn’t need the column, don’t fetch it, don’t carry it, don’t ship it.</p><h3>2) Naughty: WHERE tenant_id = $1 ... ORDER BY x LIMIT N that hits the “ORDER BY + LIMIT optimizer quirk”</h3><h3>Why it’s naughty</h3><p>This is a classic planner trap: the optimizer tries to be clever and exploit an index that matches ORDER BY, so it can stop early with LIMIT. But if the filtering predicate is satisfied “elsewhere” (joins, correlations, distribution skew), Postgres may end up scanning far more rows than expected before it finds the first N that qualify. That’s the performance cliff.</p><p>When it goes bad, you see:</p><ul><li>Long response time (scanning deep into an index to find qualifying rows)</li><li>High temp usage if the alternative plan sorts a large intermediate set and spills</li></ul><h3>Nice list fixes :</h3><p><strong>A. “Make the smart optimizer more stupid” (the </strong><strong>+ 0 trick)</strong><br> In some cases, you can deliberately prevent the planner from matching the ORDER BY to an index by turning it into an expression, e.g. ORDER BY x + 0, which can force a different (often better) join order / plan. This is a common workaround used in the wild.</p><pre>SELECT id, tenant_id, x<br>FROM events<br>WHERE tenant_id = $1<br>ORDER BY x+0<br>LIMIT 200;</pre><p><strong>B: Create covering index or Increasing default_statistics_target</strong></p><pre>ALTER TABLE events<br>ALTER COLUMN tenant_id SET STATISTICS 1666;</pre><p><strong>Santa verdict:</strong> LIMIT is only a turbo button if the engine can find the first rows without searching the entire parking lot.</p><h3>3) Naughty: idle-in-transaction (refcursor + client think time)</h3><h3>Why it’s naughty (and this one is pure coal)</h3><p>Idle-in-transaction is a vacuum’s worst enemy:</p><ul><li>It pins an old snapshot, so <strong>autovacuum can’t reclaim dead tuples</strong> that still might be visible.</li><li>Bloat grows, indexes bloat, and eventually your “mystery slowness” appears.</li><li>Meanwhile the backend is doing nothing, just holding the database hostage.</li></ul><p>The refcursor pattern often creates this by design:</p><ol><li>Begin transaction</li><li>Open cursor</li><li>Fetch some rows</li><li>Client does slow work (several minutes to hours)</li><li>Cursor stays open, transaction stays open</li></ol><h3>Nice list fixes</h3><ul><li><strong>Don’t do application think-time inside a DB transaction.</strong> Fetch quickly, commit, process outside, then write back in a new transaction.</li><li>If you must stream: keep the stream continuous, not “fetch then pause.”</li><li>Enforce guardrails:</li></ul><pre>ALTER ROLE app_user SET idle_in_transaction_session_timeout = &#39;30s&#39;;<br>ALTER ROLE app_user SET statement_timeout = &#39;2min&#39;;</pre><p>Quick detector:</p><pre>SELECT pid, usename, wait_event, now() - xact_start AS tx_age, query<br>FROM pg_stat_activity<br>WHERE state = &#39;idle in transaction&#39;<br>ORDER BY 4 DESC;</pre><p><strong>Santa verdict:</strong> A transaction is not a tote bag. Don’t carry it around while you do errands.</p><h3>4) Naughty: mega-CTE chains (WITH a AS (...), b AS (...), c AS (...) ...)</h3><h3>Why it’s naughty</h3><p>Long WITH pipelines can compound rowcount estimation errors. Once estimates are off, everything downstream is at risk: join order, join type, memory sizing, spill behavior. Also a big headache for prod support teams in debugging production functional or data quality issues.</p><h3>Best nice-list option : split into temp tables</h3><p>This gives you:</p><ul><li>a clean pipeline boundary</li><li>the ability to ANALYZE intermediate results (real stats)</li><li>tactical indexes on stages that matter</li></ul><p>Pattern:</p><pre>DROP TABLE IF EXISTS stage1;<br>CREATE TEMP TABLE stage1 AS<br>SELECT ...;<br><br>ANALYZE stage1;<br><br>CREATE INDEX ON stage1 (join_key);<br><br>DROP TABLE IF EXISTS stage2;<br>CREATE TEMP TABLE stage2 AS<br>SELECT ...<br>FROM stage1<br>JOIN ...;<br><br>ANALYZE stage2;<br><br>DROP TABLE IF EXISTS stage3;<br>CREATE TEMP TABLE stage3 AS<br>SELECT ...<br>FROM stage2<br>JOIN ...;<br><br>ANALYZE stage3;<br>.<br>.<br>.<br>.</pre><p>On <strong>“pg_catalog bloat” </strong>issue : in practice, I have seen bigger wins from <strong>good autovacuum tuning</strong> (cost limit/delay, scale factors, number of workers) than from worrying about catalog bloat as a primary performance constraint.</p><p>Also: yes, many of us are still waiting for “true global temp tables someday.” (pgtt extension doesn’t do anything to reduce catalog bloat)</p><p><strong>Santa verdict:</strong> If the planner can’t see the pipeline clearly, give it stages and statistics.</p><h3>5) Naughty: wildcard search LIKE &#39;%foo%&#39; (and friends)</h3><h3>Why it’s naughty</h3><p>A normal B-tree index can only help when the pattern is <strong>anchored at the start</strong> (e.g., col LIKE &#39;foo%&#39;), not when it starts with %.</p><h3>Nice list fixes</h3><p><strong>Fix A: </strong><strong>pg_trgm</strong></p><pre>CREATE EXTENSION IF NOT EXISTS pg_trgm;<br>CREATE INDEX CONCURRENTLY ON docs USING gin (title gin_trgm_ops);</pre><p>pg_trgm provides GIN/GiST operator classes for fast similarity and pattern searches.</p><p><strong>Fix B: Biscuit (newer alternative)</strong><br> Biscuit is an index access method designed specifically for fast LIKE/ILIKE pattern matching and claims to reduce trigram “recheck overhead” for wildcard-heavy queries. Evaluate it on your data and query mix. <br><a href="https://github.com/CrystallineCore/Biscuit">GitHub</a></p><p><strong>Santa verdict:</strong> Leading % turns your index into holiday decoration: pretty, not load-bearing.</p><h3>6) Naughty: functions on indexed columns (WHERE lower(email) = ...)</h3><h3>Why it’s naughty</h3><p>You turned an indexable predicate into an expression; without an expression index, Postgres often can’t use your B-tree index effectively.</p><h3>Nice list fixes</h3><pre>CREATE INDEX CONCURRENTLY ON users ((lower(email)));<br><br>SELECT ...<br>FROM users<br>WHERE lower(email) = lower($1);</pre><p><strong>Santa verdict:</strong> If you wrap the column, index the wrapper.</p><h3>7) Naughty: OR conditions that derail index usage (a = 1 OR b = 2)</h3><h3>Why it’s naughty</h3><p>OR predicates can push the planner into a compromise plan: either scan too much, or pick a strategy that’s great for one branch and terrible for the other.</p><h3>Nice list fixes</h3><p>Split with UNION ALL (careful to preserve semantics):</p><pre>SELECT ... FROM t WHERE a = 1<br>UNION ALL<br>SELECT ... FROM t WHERE b = 2 ;</pre><p><strong>Santa verdict:</strong> OR is two queries wearing one trench coat.</p><h3>8) Naughty: mismatched join types / implicit casts on join keys</h3><h3>Why it’s naughty</h3><p>If join keys don’t match types, you can:</p><ul><li>prevent index usage</li><li>trigger repeated casting on large relations</li><li>get unexpected nested loops</li></ul><h3>Nice list fixes</h3><ul><li>Fix schema types where possible.</li><li>Otherwise cast the parameter, not the column:</li></ul><pre>WHERE t.uuid_col = $1::uuid</pre><p><strong>Santa verdict:</strong> If your join keys can’t agree on a type, they shouldn’t be meeting in production.</p><h3>9) Naughty: missing indexes for join keys / foreign keys (especially on large tables)</h3><h3>Why it’s naughty</h3><ul><li>Joins devolve into large hash builds or repeated scans.</li><li>Deletes/updates on referenced tables become expensive due to referential checks.</li></ul><h3>Nice list fixes</h3><pre>CREATE INDEX CONCURRENTLY ON child (parent_id);</pre><p><strong>Experimental (not for Prod yet) : </strong>Working on an extension to prevent unindexed foreign keys from going in production. <a href="https://github.com/secp256k1-sha256/tenxdev/blob/main/fkhunter/fkhunter_readme.md">FKHunter</a> (Any improvement suggestions are welcome)</p><p><strong>Santa verdict:</strong> Foreign keys without supporting indexes are a gift you gave yourself…. with no receipt.</p><h3>10) Naughty: SELECT DISTINCT as a band-aid for join explosions</h3><h3>Why it’s naughty</h3><p>DISTINCT often hides:</p><ul><li>missing join predicates</li><li>unintended many-to-many relationships</li><li>data modeling issues</li></ul><p>It forces a sort or hash aggregate on an inflated intermediate result.</p><h3>Nice list fixes</h3><ul><li>Fix the join.</li></ul><p><strong>Santa verdict:</strong> DISTINCT is not deodorant.</p><p>If Santa finds your SQL on the Naughty List, don’t take it personally but take it as a to-do list. Pick one offender this week, run EXPLAIN (ANALYZE, BUFFERS), apply the smallest “Nice List” fix, and measure the win. Do that ten times and you won’t just get better latency; you’ll get a calmer pager, and a database that actually feels like it’s on holiday too.</p><p><em>PS: Extra content for holidy season</em></p><p>SQL-Claus Before :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/938/1*3H762nGVoo68-ChwbZ7u1A.jpeg" /></figure><p>SQL-Claus Now :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/853/1*tEf9Nunh5SRlCzwKBbS6CQ.jpeg" /></figure><blockquote><strong>AI Generated SQL-Claus Last Christmas vs AI Generated SQL-Claus Today. Some would say AI lost it’s soul in rat race of larger models, previous SQL-Claus meme had a character.</strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ebc59b800e2f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The OOM-Killer Summoning Ritual: “Just Increase work_mem”]]></title>
            <link>https://drunkdba.medium.com/the-oom-killer-summoning-ritual-just-increase-work-mem-7afb4b22ec44?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/7afb4b22ec44</guid>
            <category><![CDATA[database-administration]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Fri, 19 Dec 2025 21:57:52 GMT</pubDate>
            <atom:updated>2025-12-20T16:41:28.914Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>You’ve probably seen the incident pattern:</p><ol><li>Postgres backends start disappearing.</li><li>dmesg / journalctl -k shows the kernel OOM killer reaping postgres.</li><li>Someone spots “out of memory” and reflexively recommends: “Increase work_mem.”</li></ol><p>That recommendation is frequently backwards for <em>OS OOM kills</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gz6ienJja1lcfN07KVcj6g.png" /></figure><h3>The linguistic trap: “Out of memory” sounds like “not enough work_mem”</h3><p>work_mem is not “memory for the query.” It is a <strong>base, per-operation</strong> budget for executor nodes like sorts and hash tables <em>before</em> they spill to temporary files. PostgreSQL’s own docs explicitly warn that a complex query can run multiple sort/hash operations concurrently, and many sessions can do this at the same time so total memory can be <em>many times</em> work_mem.</p><p>If you raise work_mem globally, you are raising the ceiling on <strong>many</strong> potential concurrent memory consumers. That can turn “rare spike” into “frequent OOM kill.”</p><h3>OS OOM kill vs “Postgres OOM”: two different failure modes</h3><p>There are two scenarios people accidentally conflate:</p><ul><li><strong>Executor spills to disk (healthy):</strong> Postgres hits a per-node memory budget and writes temp files.</li><li><strong>Kernel OOM kill (host-level failure):</strong> Linux cannot satisfy memory demands (often influenced by overcommit behavior) and terminates a process to keep the system alive.</li></ul><p>In other words: if the kernel is killing Postgres, “give Postgres permission to use even more memory next time” is not a stabilizing strategy.</p><h3>The source code says: work_mem is “allowed memory,” then spill to temp files</h3><p>The tuplesort implementation is blunt about the design: it keeps tuples in memory up to the limit and then switches to temporary “tapes” (temp files) for an external sort.</p><p>A tiny excerpt from src/backend/utils/sort/tuplesort.c (<a href="https://doxygen.postgresql.org/tuplesort_8c_source.html">Doxygen</a>):</p><pre>/* ... memory allowed ... (most pass work_mem) ... */<br>...<br>/* If we do exceed workMem, we begin to emit tuples ... temporary tapes. */</pre><p>This is why “spilling” isn’t synonymous with “misconfigured”. It’s the planned safety valve.</p><h3>Hash nodes can blow past the base: hash_mem_multiplier is literally in the math</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UQ4BEpYZzeIJIwbKF5RL9Q.png" /></figure><p>Hash operations are <em>not</em> capped at work_mem. Postgres computes the hash memory limit as:</p><pre>{<br>    double      mem_limit;<br> <br>    /* Do initial calculation in double arithmetic */<br>    mem_limit = (double) work_mem * hash_mem_multiplier * 1024.0;<br> <br>    /* Clamp in case it doesn&#39;t fit in size_t */<br>    mem_limit = Min(mem_limit, (double) SIZE_MAX);<br> <br>    return (size_t) mem_limit;<br>}</pre><p>That’s get_hash_memory_limit() in src/backend/executor/nodeHash.c. <a href="https://doxygen.postgresql.org/nodeHash_8c.html">Doxygen</a></p><p>The docs also spell out the implications:</p><ul><li>Hash memory limit = work_mem * hash_mem_multiplier</li><li>Default hash_mem_multiplier is 2 (so hash nodes may target ~2× work_mem)</li></ul><p>So if someone says “we set work_mem=128MB, we’re safe,” but you have concurrent HashAgg/HashJoin/Memoize activity, your effective per-node appetite can be meaningfully higher than they think.</p><h3>Why increasing work_mem can make OOM kills more frequent</h3><p>Here’s the mental model that avoids the trap:</p><blockquote><em>work_mem is a </em>multiplier<em> applied by concurrency.</em></blockquote><p>A crude (but useful) worst-case sketch:</p><ul><li>active_sessions = 150 (Typically when a connection pooler is used and peak clients are several thousand then you could end up with few hundred active sessions)</li><li>Conservative assumption that each session runs a query that (at peak) has 2 sorts + 1 hash agg concurrently (3 operations)</li><li>work_mem = 64MB</li><li>hash_mem_multiplier = 2.0</li></ul><p>Then memory budget pressure can look like:</p><ul><li>Sort side: 150 * 2 * 64MB = 19,200MB</li><li>Hash side (approx): 150 * 1 * (64MB * 2) = 19,200MB</li></ul><p>You are already around ~38GB of <em>just</em> sort/hash budgets, before counting:</p><ul><li>backend overhead, memory contexts, connection-local memory</li><li>shared memory, OS cache dynamics, other processes</li><li>parallel query workers (more processes, more operations)</li></ul><p>Now imagine someone “fixes” OOM kills by doubling work_mem to 128MB. That same sketch becomes ~76GB. If the host has 64GB RAM, you didn’t tune performance instead you scheduled the next kill.</p><p>This is why pganalyze’s guidance for frequent OOM errors starts with: <strong>reduce </strong><strong>work_mem</strong> to improve stability, accepting more disk spill as the tradeoff. <a href="https://pganalyze.com/docs/log-insights/server/S5">pganalyze</a></p><h3>A practical playbook: stabilize first, then optimize surgically</h3><p>If you want fewer OOM kills <em>and</em> good performance, separate <strong>global defaults</strong> from <strong>intentional exceptions</strong>:</p><h3>1) Confirm it’s a kernel OOM kill (not just query failure)</h3><ul><li>Check journalctl -k / dmesg for OOM killer messages (process name/PID, reaped memory).</li></ul><h3>2) Make temp spill observable (because spill is the designed safety valve)</h3><p>Turn on temp file logging to see which queries are forcing external sorts / hash batching:</p><ul><li>log_temp_files = 0 (log all temp files) or set a threshold in kB</li></ul><p>Also consider:</p><ul><li>temp_file_limit to prevent a single session from consuming unbounded temp space (it cancels the transaction when exceeded). <a href="https://postgresqlco.nf/doc/en/param/temp_file_limit/">PostgreSQL</a></li></ul><h3>3) Set a conservative global work_mem, then raise it only where justified</h3><ul><li>Keep a modest default that survives peak concurrency.</li><li>For the one reporting job / ETL / admin session that benefits from more memory, use <strong>targeted</strong> increases: <br>SET LOCAL work_mem = &#39;128MB&#39;; inside a transaction <br>or ALTER ROLE reporting_user SET work_mem = &#39;128MB&#39;;</li></ul><p>This preserves cluster stability while still enabling fast “big” queries.</p><h3>4) Use EXPLAIN to validate the tradeoff</h3><p>You want to see spills when needed, not crashes:</p><ul><li>Sort Method: external merge with disk usage is a normal outcome when data exceeds budget.</li><li>Hash nodes show batching when they spill.</li></ul><h3>5) Don’t ignore Linux overcommit behavior</h3><p>In overcommit-heavy configurations, you can get killed before Postgres can gracefully error and log a memory context dump. Cybertec and Postgres community guidance often points to disabling overcommit (or otherwise managing it) to avoid OOM-killer surprise terminations. <a href="https://www.cybertec-postgresql.com/en/what-you-should-know-about-linux-memory-overcommit-in-postgresql/">CYBERTEC PostgreSQL | Services &amp; Support</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aob3sV441xzv-yjGkt0KLw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7afb4b22ec44" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Application Developers Using AI Is Great For DBA Job Security]]></title>
            <link>https://drunkdba.medium.com/why-application-developers-using-ai-is-great-for-dba-job-security-43042dc0f294?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/43042dc0f294</guid>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[postgresql-database]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Mon, 17 Nov 2025 14:09:53 GMT</pubDate>
            <atom:updated>2025-11-17T14:09:53.510Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>Everyone’s freaking out about AI taking their jobs. Meanwhile, I’m a DBA sitting in the corner thinking: <em>“If programmers of the future are AI agents, companies will need 100x more human DBAs to clean up the mess in production.”</em></p><p>This rant blogpost is my attempt to explain why.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eaORcSJJ5W5gUt2-wAKVsA.png" /></figure><h3>LLMs: Optimizing for the Next Token, Not for Reality</h3><p>Let’s start with the core problem:</p><p>LLMs don’t optimize for <em>truth</em>.<br>They optimize for <em>“what word statistically looks good next?”</em></p><p>Give a model the text:</p><blockquote><em>“Postgres DBAs love”</em></blockquote><p>It might happily continue with:</p><blockquote><em>“Oracle”</em></blockquote><p>From there, it feeds its own output back in and keeps predicting the next token again and again. At no point does it pause and say: <em>“Wait, does this actually represent reality?”</em></p><p>It has no built-in concept of <em>reality</em> or <em>verification</em>. That’s your job.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*885E6nEcHscvnroRStLYmg.png" /></figure><p>As long as this is the operating model, hallucinations are not a bug but they are a <em>feature</em>. They’re what you get when you combine probability with confidence and zero shame. We’re basically wiring a very polite, very confident intern to production and asking it architectural questions.</p><p>What could go wrong?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/833/1*O3Up4OXF44nTpwetoVOOfw.png" /></figure><h3>“Hallucinations” Is Just a Fancy Word for “We Noticed the Lie”</h3><p>I liked one line from an MIT Tech Review piece: “<em>It’s </em>all<em> hallucination, but we just call it that when we notice.”</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OhdXtMQnHYh66JwudVE7EQ.png" /></figure><p>Most of the time, when the answer is “good enough”, we call it “AI magic”.<br> When it’s wrong in a way we understand, suddenly it becomes “hallucination”.</p><p>From a former physics student perspective, this is just non zero probability in action. We already live with quantum tunneling and in theory there’s a very very small but finite probability your laptop falls through the table while reading this paragraph. So the idea that an AI occasionally invents a Postgres feature, a config parameter, or even a fake “Postgres founder” called <em>Michael Stockbroker</em> is not that hard to digest.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1dVjcgIwhGeLRtlYytTUMg.png" /><figcaption>LLMs are Pinnochio’s of modern world.</figcaption></figure><h3>Minimizing Hallucinations ≠ Eliminating Them</h3><p>Yes, there are techniques:</p><ul><li>Retrieval-augmented generation (RAG)</li><li>Better prompts.</li><li>Constraining answers to a small domain.</li><li>Larger training data, new improved models.</li></ul><p>They help. They reduce the probability of a lie.<br>They never turn it into zero. So instead of asking, <em>“How do we make AI always right?” </em>We should be asking, <em>“What happens to systems and teams when AI is </em><strong><em>wrong</em></strong><em> in confident, creative ways?”</em></p><p>That’s where Postgres DBA’s job security enters the chat.</p><h3>Postgres vs AI: Field Reports from the Trenches</h3><p>We don’t need theory. Just look at the real world of Postgres chats, blogs, and forums.</p><h3>1. The Adaptive Optimizer That Doesn’t Exist</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ezbwlx3vz6JtXfqaaQ8kUg.png" /></figure><p>One popular LinkedIn post proudly announced that <strong>Postgres now has an adaptive optimizer</strong>, just like Oracle changing plans mid-execution, magically fixing bad queries at runtime.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hnt2Wqzt6ePAmGU247M5qQ.png" /></figure><p>Reality check:</p><ul><li>Postgres does <strong>not</strong> have Oracle-style adaptive optimizer.</li><li>People migrating from Oracle to Postgres often <em>wish</em> it did.</li><li>Most serious Oracle deployments especially in finance domain don’t enable adaptive optimization in production anyway. They value <em>predictable latency</em>, not “charismatic magic” that wakes up once every blue moon and wrecks your critical workload.</li></ul><p>But somewhere, an LLM saw enough Oracle docs, blogs, and forum posts and decided: <em>“Postgres is a database. Oracle is a database. Adaptive optimizer is cool. Therefore, Postgres now has an adaptive optimizer.”</em></p><p>And now that garbage is in the content pool.</p><h3>2. “Even ChatGPT Failed to Answer This!”</h3><p>From Postgres community chat: user confused about why something wasn’t working.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/848/1*jZTf8twRlsfQAWdKnnZuig.png" /></figure><p>LLM confidently explained that &#39;&#39; (empty quoted whitespace) is the same as NULL.<br>Humans: <em>“No. That’s not NULL. That’s just an empty string. Here’s why.”<br></em>One line from a human fixed it.<br>An LLM left the user more confused.</p><h3>3. TTL Indexes in Postgres? Sure, Why Not</h3><p>Someone shows up: “I read about TTL indexes in Postgres, how do I use them?”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iLdd3uvI1TeWHGzAQEmjxw.png" /></figure><p>Short answer from the community: <em>“You don’t. Postgres doesn’t have native TTL indexes.”</em></p><p>Of course, you <em>can</em> build TTL-like behavior with partitioning and pg_cron schedular based archival/dropping of old, unnecessary partitions. But there’s no single magical TTL index type like in some other databases.</p><p>LLMs, however, happily remix MongoDB + Postgres content into: <em>“Here’s how to create a TTL index in Postgres”</em></p><p>And now we’re babysitting that.</p><h3>4. “Just Tweak the Background Workers in Prod”</h3><p>One of my favorites: AI confidently suggesting users adjust internal Postgres <strong>background workers</strong> in ways no sane human would recommend to any developer.</p><p>This is the kind of advice that:</p><ul><li>Looks sophisticated</li><li>Sounds low-risk</li><li>Is absolutely <strong>not</strong> for casual experimentation on prod instances</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/1*2DEF0sgJtoNeVx2O3_4duA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W0D6RB8OF9-DGSmrVVGO9Q.png" /></figure><p>Once that advice leaks into tutorials/blogs, it slowly contaminates future AI training runs. Then the next generation of LLMs produces even more polished nonsense.</p><p><strong>High-quality garbage. With headings.</strong></p><h3>5. LLM induced extra work</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*56rkzTdXLwKcX2MKDB2jSQ.png" /></figure><p>An LLM confidently advises: <em>“Now you should rebuild all indexes to be safe.”</em></p><p>No, you shouldn’t.</p><ul><li>Reindexing everything after a successful upgrade is an <em>unnecessary</em> time sink, risk that adds downtime to upgrade.</li><li>LLM probably got confused with reindexing required on OS update due to <a href="https://www.crunchydata.com/blog/glibc-collations-and-data-corruption">(in)famous glibc issue</a>.</li></ul><p>But sure, if someone blindly follows it, that’s:</p><ul><li>Extra downtime,</li><li>Extra IO,</li><li>Extra DBA hours.</li></ul><h3>6. Two Node Patroni HA with Autofailover 🤡</h3><p><em>“Design a 2-node Patroni HA cluster with auto-failover. DCS, Postgres, Patroni all on just two machines.”</em></p><p>LLM: <em>“Of course! Here’s a step-by-step guide…”</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FRSBrhy-iOl8GuDDUSyrvA.png" /></figure><p>Human DBA: <em>“No. Just… no. You are designing a split-brain machine.”</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*Q-YZZk2ZIrvtprCIPQ629Q.png" /></figure><p>Because in a network partition with two nodes, both can think they’re the primary. And then you have:</p><ul><li>Diverged writes</li><li>Broken constraints</li><li>Business screaming</li><li>Audit logs full of horror</li></ul><p>Who saves the day?<br>Not the LLM.</p><h3>Data Cannibalism: When AI Starts Eating Its Own Slop</h3><p>Another fun part of this story: <strong>data cannibalism</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*vaiRPcXD8MK25kVK8h8uHg.png" /></figure><p>As more AI generated content floods the internet:</p><ul><li>That content gets scraped into future training data.</li><li>The model trains on its own previous guesses.</li><li>Errors compound.</li><li>Rare edge cases vanish.</li><li>Details blur and collapse toward generic nonsense.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ju5a4OJSEGB6SBkSr5FpjA.png" /></figure><p>There’s already published work showing that models trained on AI generated data <strong>collapse</strong> over generations. And estimates that we may run out of clean human generated data for training in a few years, depending on how aggressively we keep training new models.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x64TuF8WN-J0AoUDrJBKsg.png" /></figure><p>Even worse: those estimates often <em>don’t</em> factor in how much AI slop humans are now posting as their own “blog posts” and “whitepapers”.</p><p>One research paper about Postgres I came across had very clear indicators of being LLM generated fake :</p><ul><li>“In the digital world…” as intro</li><li>AI-generated fake graphs : A misspelling in the chart title but correct text in the caption</li><li>And it credited Postgres to founder “Michael Stockbroker”</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*YxwG2AQxSxySSLin87u9yg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*0MUxQmHrskyaRqmEnpf1FA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/625/1*fVchHRQ_EylrWxhJjGrWTw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/666/1*doRezDox0Dom0DLY0FHuxQ.png" /></figure><p>So we’re seeding the future with:</p><ul><li>Invented features</li><li>Incorrect design patterns</li><li>Misleading performance “benchmarks”</li><li>Fake Subject Matter Experts</li></ul><p>This is the stuff going into future model training sets.<br>Enjoy your model collapse.</p><p><strong>Meanwhile, humans DBAs become more valuable, not less.</strong></p><h3>So… What Can AI Safely Do for Postgres?</h3><p>Despite all this, I’m not <strong>anti-Automation</strong>.<br>I’m anti-“AI as a magical production architect”.</p><p>There <em>are</em> areas where narrow AI with <strong>limited scope for creativity</strong> can be useful:</p><h3>1. DB Parameter Tuning (Within Limits)</h3><p>Tools like DBTune that:</p><ul><li>Suggest reasonable shared_buffers, work_mem etc Parameter ranges.</li><li>Maybe even propose changes in a Git-style diff</li></ul><p>This is bounded, repeatable, and easy to verify. Worst case, you roll back a config.</p><h3>2. Index Advisors</h3><p>Systems that:</p><ul><li>Analyze postgres logs, waits and pg_stat_statements</li><li>Suggest candidate indexes</li><li>Estimate bloat and usage</li></ul><p>As long as they stay in “advisor” mode and a human reviews changes before applying, they’re super helpful. Think <strong>pganalyze</strong> style, not “Let the LLM directly CREATE INDEX in prod at 11:55 before Black Friday”.</p><h3>3. Ops Automation</h3><p>Great use cases:</p><ul><li>Alerting on txid wraparound risk</li><li>Growing storage before it fills</li><li>Notifying you when replication lag spikes</li><li>Automating some backup/restore checks</li></ul><p>Basically: if it’s mechanical, measurable, and reversible automation is powerful.</p><h3>Future of AI for DBAs: Expectation vs Reality</h3><p><strong>Expectation:</strong><br>AI agents write all the code, optimize all the queries, run all the operations.<br>DBAs disappear. Everything is self-healing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/916/1*mlQrsp2kBx44jd1fk3sSmQ.png" /></figure><p><strong>Reality:</strong></p><ul><li>AI generates weird schemas, terrible queries, and unsafe designs.</li><li>AI hallucinates Postgres features that don’t exist.</li><li>AI amplifies bad advice from old mailing list threads.</li><li>Startups implement this stuff directly in production.</li><li>Systems break in more creative ways than ever before.</li></ul><p>And then those companies:</p><ul><li>Hire senior DBAs</li><li>Pay more per hour</li><li>Prioritize performance &amp; reliability</li><li>Buy support contracts they previously refused</li></ul><p>So if you’re a DBA worrying about AI taking your job, relax. You’re going to be busy.</p><p>Very, <em>very</em> busy.</p><p>PS: By popular demand, I’ve included some extra AI-generated content. I accept no liability, take zero responsibility, and fully classify the following as <em>AI slop found in the wild</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1005/1*sfbhDMWl5yQd1dgueU2jSw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=43042dc0f294" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ALTER Egos: Me, Myself, and Cursor]]></title>
            <link>https://drunkdba.medium.com/alter-egos-me-myself-and-cursor-3978fd29245f?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/3978fd29245f</guid>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[database-administration]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Tue, 04 Nov 2025 05:56:18 GMT</pubDate>
            <atom:updated>2025-11-04T05:56:18.419Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AGJH6azqsKarnhWk6bBvdA.png" /></figure><p>I pushed the most boring change imaginable, add an index. Our CI/CD pipeline is textbook ==&gt; spin up a fresh DB, run every migration file in <strong>one single transaction</strong>, in sequential manner. If anything hiccups, the whole thing rolls back and the change never hits main. Foolproof autotests.</p><p>Enter The Drama Queen :</p><pre>ERROR: cannot CREATE INDEX &quot;index_name_xyz&quot; on table abcdef_tab<br>because it is being used by active queries in this session</pre><p>This session. Same PID, same transaction. No parallel runner. No second connection. Still blocked.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*uOap503Ed44D9JwgJiG_1Q.jpeg" /></figure><p>Our schema migration repository structure is as shown above. CI tool will create a fresh DB → execute all scripts chronlogically → one by one → one transaction → one session as a part of an autotest before merging any new code (dml/ddl for schema migration = infra as a code) to main branch.</p><p>Naturally ignoring last part of error message like a seasoned DBA, I accused CI tool of going rogue, maybe someone “optimized” migrations to run in parallel after reading a LLM pep talk about “unleashing concurrency.”</p><p>I printed the PID at the start and end of every file.</p><pre>-- Stamp the migration transaction<br>SELECT &#39;start&#39;, pg_backend_pid(), txid_current();<br>-- ... run all migration steps ...<br>SELECT &#39;end&#39;,   pg_backend_pid(), txid_current();</pre><p>Same PID. Same transaction. Same sadness.</p><p>One of the least talked about but best Postgres feature as a FOSS project is that you can search error message in code base and documentation is excellent.</p><ul><li>In indexcmds.c, PostgreSQL calls CheckTableNotInUse(rel, &quot;CREATE INDEX&quot;); before proceeding. The comment explains <strong>why</strong>: otherwise an in-progress INSERT/UPDATE in <em>this same session</em> could have already picked its list of target indexes and would not update the new one. <a href="https://doxygen.postgresql.org/indexcmds_8c_source.html">doxygen.postgresql.org</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UMcNh69KJ13rd3smEGhPhA.png" /></figure><ul><li>CheckTableNotInUse() (in tablecmds.c) raises<br> ERROR: cannot %s &quot;%s&quot; because it is being used by active queries in this session<br> when the relation’s refcount shows it’s still in use by the current backend (or if there are pending AFTER triggers).</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4yqsW0fbWuNUwNLAn6h_Pw.png" /></figure><p>It clearly says just above CheckTableNotInUsethat there’s an open cursor or active plan.</p><blockquote>“Disallow ALTER TABLE (and similar commands) when the current backend has any open reference to the target table besides the one just acquired by the calling command; this implies there’s an open cursor or active plan.”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9-4vwUugwbONRcQhlCkcqA.png" /></figure><p>So not another session. <strong>This</strong> session. And if there’s no parallelism and no second plan lingering, what’s left? As Sherlock Holmes would say: once you eliminate the impossible, whatever remains, however improbable…. is that one open cursor someone forgot to close.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3EcQDwJLukU8CMALJJhgEA.jpeg" /></figure><p>I slapped a CLOSE ALL; at the top of the migration file just to test the hypothesis. Boom =&gt; green CI. Then I hunted down the culprit, a recently added explicit cursor loop (OPEN …; FETCH …;) instead of a tidy FOR r IN SELECT … LOOP.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4tJD8bB-A5n27SJAMWjXGg.jpeg" /><figcaption>Culprit Found</figcaption></figure><p>The cursor never got closed, so the relation stayed referenced, and Postgres (correctly) refused.</p><p><strong>In short: my session blocked….. my session. Peak self-sabotage.</strong></p><p><strong>Simple fix:</strong> stop leaking cursors. Prefer FOR rec IN SELECT … LOOP (implicit cursor) or explicitly CLOSE the cursor (also in EXCEPTION block).</p><p>PS : Slightly off topic but doxygen.postgresql.org is cool.<br>A piece of history : Magnus Hagander announcing auto-generated source code documentation (not the user manual).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1008/1*yNF5Wg_1Y6mmG5ZhEQ5nlg.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3978fd29245f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Slonik on the Catwalk: PGConf.EU 2025 Recap]]></title>
            <link>https://drunkdba.medium.com/slonik-on-the-catwalk-pgconf-eu-2025-recap-b4990c626271?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/b4990c626271</guid>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[pgconf]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Mon, 27 Oct 2025 11:53:47 GMT</pubDate>
            <atom:updated>2025-10-27T12:36:28.233Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>I volunteered as a room host and Slonik guide.<br>Best gig: posing our elephant. The photographer had runway-level ideas. Slonik delivered every single time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lKT_xGfXAuhfCV5OEgwNeg.jpeg" /><figcaption>Slonik modelling session</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V968rMy_NK8cy4Zb4mrZrA.jpeg" /><figcaption>Slonik having a Diva moment</figcaption></figure><h3>Community Day ~ people &gt; hype</h3><ul><li><strong>PostgreSQL &amp; AI Summit</strong>: I sat on the panel and played “Team Human” vs Skynet (As advised by John Connor in the future).<br> <a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7149-postgresql-ai-summit/">postgresql.eu</a></li><li><strong>“Establishing the PostgreSQL standard: What’s Postgres compatible?”</strong><br>Half-day workshop, lot of brain storming and discussion split into groups then presenting your group’s conclusion on what makes postgres derivatives compatible with community postgres. We spun up a Telegram group to keep building the rubric post-conference. <a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7152-establishing-the-postgresql-standard-whats-postgres-compatible/">postgresql.eu</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xMLr01XRUo1SejbraVDA4g.jpeg" /><figcaption>The Hallway Track</figcaption></figure><h3>Coffee with CYBERTEC (meeting Laurenz Albe)</h3><ul><li>Picked the <strong>“Coffee with CYBERTEC”</strong> option to meet Laurenz Albe, the most prolific Stack Overflow answerer.</li><li>We traded notes on most popular <strong>features to adopt</strong> from other databases, their <strong>feasibility</strong>, and <strong>why Postgres avoided them historically</strong>.</li></ul><p>I left with a <strong>starting map for contributing to core.</strong></p><h3>Talks I caught (and why they stuck)</h3><p><strong>“Don’t do that!” — Laurenz Albe</strong><br>A rapid-fire list of Postgres anti-patterns. Simple, blunt, useful from the most beloved speaker of the conference. (<a href="https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6838/slides/742/dont_do_that_m.pdf">postgresql.eu</a>)</p><p><strong>Parsing Postgres logs the non-pgBadger way — Kaarel Moppel</strong><br>Meet pgweasel. Lean CLI. Fast. Cloud-friendly. For prod support, less noise beats glossy graphs. I’m convinced. (<a href="https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6975-parsing-postgres-logs-the-non-pgbadger-way/">postgresql.eu</a>)<br><a href="https://github.com/kmoppel/pgweasel">https://github.com/kmoppel/pgweasel</a></p><p><strong>Improved freezing in VACUUM — Melanie Plageman</strong><br>Cleaner anti-wraparound story. Scan all-visible (not all-frozen) pages early; fewer emergency freezes later. Sensible, much needed change. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6952-improved-freezing-in-postgres-vacuum-from-idea-to-commit/">postgresql.eu</a>)</p><p><strong>Patroni + pgBackRest: better together — Stefan Fercot</strong><br>Power couple of Postgres, best HA tool with best Backup tool. Tight HA+DR integration. Bootstrap from backups, safe standby rebuilds, PITR under Patroni’s control. (<a href="https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6961-patroni-and-pgbackrest-better-together/">postgresql.eu</a>)</p><p><strong>DBTune: AI-driven tuning</strong><br>Autonomous parameter tuning across self-hosted and managed Postgres. Looks mature enough for a lab trial. I’m tempted to test in QA. (<a href="https://www.postgresql.eu/events/pgconfeu2025/sessions/session/7187-dbtune-ai-driven-performance-tuning-for-all-postgresql-flavors/">postgresql.eu</a>)</p><p><strong>The SyncRep Detective Story</strong><br>Fascinating detective story and scientific approach to tracing root cause. Resonated with my past setup where commit_delay/commit_siblings helped on AWS networked storage. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7037-the-syncrep-detective-story-chasing-ghosts-in-postgresql-finding-demons-in-storage/">postgresql.eu</a>)</p><p><strong>MultiXacts: usage, side-effects, monitoring — Divya Sharma</strong><br>Row-lock pileups and vacuum side effects, explained. We don’t hit them often in current company (rareSELECT … FOR UPDATE), but I left with better alarms to build. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6887-multixacts-in-postgresql-usage-side-effects-and-monitoring/">postgresql.eu</a>)</p><p><strong>Fast-path locking in PG18 — Tomas Vondra</strong><br>Shines with many relations and partitions. We’re light on partitioning at current company, so the gains will be modest for us. Still, good progress. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6891-fast-path-locking-improvements-in-pg18/">postgresql.eu</a>)</p><p><strong>Patroni: what the blog posts don’t tell you — Cameron Murdoch</strong><br>The “missing manual”: hardening, proxies, DCS choices, failsafe option and upgrades. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7018-patroni-what-the-blog-posts-dont-tell-you/">postgresql.eu</a>)</p><p><strong>We have multiple concurrent versions of this title trying to understand MVCC (Boris Mejias)</strong><br>It’s hard to describe this talk cause you have to experience it live to fully appreciate the second best database comedian in the world.</p><p><strong>Tracking plan shapes over time — pg_stat_plans (Lukas Fittl)</strong><br>Plan IDs + pg_stat_plans let you watch plan drift over time. This will be gold for catching plan fluctuations. (<a href="https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7112-tracking-plan-shapes-over-time-with-plan-ids-and-the-new-pg_stat_plans/">postgresql.eu</a>)<br><a href="https://github.com/pganalyze/pg_stat_plans">https://github.com/pganalyze/pg_stat_plans</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mMbHlV9p78pn-KyukvDIYg.jpeg" /><figcaption>Feeding Session</figcaption></figure><h3>Conference vibe</h3><p>Riga was friendly. Hallway track was lively. Slonik worked overtime and loved the camera. See you next year.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YK30PMnHe4VhLCJdQ5SKuQ.jpeg" /><figcaption>“My Watch Has Ended” — Slonik Snow</figcaption></figure><p>PS: If you are still suffering from Postgres conference hangover and crave more Postgres content then head over to Prague next month for Prague Postgres Meetup or in January for P2D2 conference.</p><p><a href="https://docs.google.com/presentation/d/1XwSOlMNcB7d3IH94CmQ6uOUkPmhVWeqE7KacBl2xF_Y/edit?usp=sharing"><strong><em>13 REASONS WHY YOU SHOULD ATTEND P2D2 PRAGUE?</em></strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b4990c626271" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PGConf.EU 2025: The Underground Map for Database Nerds]]></title>
            <link>https://drunkdba.medium.com/pgconf-eu-2025-the-underground-map-for-database-nerds-da3587a90b2e?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/da3587a90b2e</guid>
            <category><![CDATA[postgres]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Fri, 17 Oct 2025 22:57:58 GMT</pubDate>
            <atom:updated>2025-10-17T22:57:58.446Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<p>PGConf.EU schedule can feel like a parallel query gone wild, so many great talks but not enough CPU.<br>I built this guide to help my fellow database nerds skip the overwhelm and enjoy the best prod-DBA focussed sessions without a single deadlock.<br>Follow this path, and you’ll cruise through the conference like a perfectly tuned autovacuum.</p><h3>🗓️ Wednesday, Oct 22 — Warming Up the Buffers</h3><p><strong>11:15 – 12:05 in Omega 1 : </strong><em>Don’t Do That!</em> <br>Laurenz Albe reminds us that every bad Postgres habit comes with a sequel called “incident report.”</p><p><strong>13:05 – 13:35 in Omega 2 : </strong><em>Parsing Postgres Logs the Non-pgBadger Way</em> <br>Kaarel Moppel shows that pgweasel and caffeine can out-analyze any dashboard.</p><p><strong>13:45–14:35 in Alfa : </strong><em>Improved Freezing in Postgres Vacuum: From Idea to Commit</em> <br>Melanie Plageman walks us through the icy depths of tuple immortality.</p><p><strong>14:45–15:35 in Omega 2 : </strong><em>Operational Hazards of Running PostgreSQL Beyond 100 TB</em> <br>Teresa Lopes shares real stories and engineering lessons from scaling Postgres into the terabyte realm, where every decision costs you.</p><p><strong>16:05–16:55 in Omega 2 </strong>: <em>What You Should Know About Constraints (and What’s New in 18)</em> <br>Gülçin Yıldırım Jelínek explores how new enhancement to constraints in PG 18 make data integrity both smarter and more flexible.</p><p><strong>17:05–17:55 in Omega 1 : </strong><em>Hacking pgvector for Performance</em> <br>Daniel Krefl reveals clever hacks to push filtering and indexing deeper into pgvector for faster, leaner similarity searches.</p><h3>🧱 Thursday, October 23 — The Day of Observability and Enlightenment</h3><p><strong>09:25–10:15 in Omega 2 : </strong><em>Unified Observability: Monitoring Postgres Anywhere with OpenTelemetry</em> (Yogesh Jain)<br>Learn how to unify metrics, logs, and traces across cloud, containers, and bare-metal Postgres instances using OpenTelemetry to build scalable, vendor-agnostic observability.</p><p><strong>10:25–10:55 in Omega 1 : </strong><em>EXPLAIN: Make It Make Sense</em> (Aivars Kalvāns)<br>Find out how to turn cryptic EXPLAIN output into actionable insights, mapping planner nodes to real costs so you can tame rogue queries.</p><p><strong>11:25–12:15 in Alfa : </strong><em>The SyncRep Detective Story: Chasing Ghosts in PostgreSQL, Finding Demons in Storage</em> <br>Dmitry Fomin unravels a real performance mystery and exorcises the demons hiding deep inside the storage.</p><p><strong>13:55–14:45 in Alfa</strong> : <em>AIO in PG 18 and Beyond</em> (Andres Freund)<br>Explore how asynchronous I/O enhancements in Postgres 18 shift the performance landscape.</p><p><strong>14:55–15:45 in Omega 1 : </strong><em>Table Repacking, Done Right</em> (Álvaro Herrera &amp; Antonin Houska) <br>Learn how <strong>REPACK CONCURRENTLY</strong> (targeting Postgres 19) can deflate bloat without downtime, how it works under the hood, and how it might rescue frustrated DBAs from locking hell.</p><p><strong>15:55–16:25 in Omega 2</strong> : <em>All About Common Vulnerabilities and Exposures in PostgreSQL</em> (Priyanka Chatterjee)<br>Get real: dissect real CVEs in PostgreSQL, see how they were exploited, and learn how to protect your systems before headlines hit.</p><h3>🧨 Friday, October 24 — The Day of Failures, Recovery &amp; Redemption</h3><p><strong>09:25–10:15 in Omega 2</strong> : <em>PostgreSQL as a Graph Database: Who Grabbed a Beer Together?</em> (Taras Kloba)<br>Taras compares Apache AGE, pgRouting, and pgGraph in a live demo to show how PostgreSQL can moonlight as a graph database and map community connections (yes, including who met at the bar).</p><p><strong>10:25–10:55 in Omega 1 : </strong><em>Fast-Path Locking Improvements in PG18</em><br>Tomas Vondra takes us on a deep dive into lock manager refinements in PG 18 that reduce contention latency in hot, high-load scenarios.</p><p><strong>11:25–12:15 in Omega 1 : </strong><em>Patroni: What the Blog Posts Don’t Tell You…</em> (Cameron Murdoch)<br> Cameron pulls back the curtain on real Patroni deployments: split-brain, failover pitfalls, and the nitty-gritty never documented.</p><p><strong>13:15–13:45 in Omega 2</strong> : <em>Tracking Plan Shapes Over Time with Plan IDs &amp; the New pg_stat_plans</em> (Lukas Fittl)<br>Lukas unveils how plan ID versioning and the new pg_stat_plans help you track plan drift, regressions, and performance ghosts over time.</p><p><strong>13:55–14:45 in Alfa : </strong><em>We Have Multiple Concurrent Versions of This Title Trying to Understand MVCC</em> (Boriss Mejias)<br>Boriss leads you through concurrency, snapshot races, and how Postgres keeps isolation sane in the chaos of multiversions.</p><p><strong>14:55–15:45 in Omega 2 : </strong><em>Database in Distress: Testing and Repairing Different Types of Database Corruption</em> (Josef Machytka)<br>Forensic lab of data corruption cases and how to surgically repair them.</p><p><strong>16:15–17:00 in Omega 1 : </strong><em>Lightning Talks (Maybe you?)</em><br>A wild finale: short, sharp experiments, hacks, and stories to spark ideas and laugh off days of log parsing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eYEtdjD3m6fyVYp8med02w.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=da3587a90b2e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Unsung Heros of Postgres : Episode I]]></title>
            <link>https://drunkdba.medium.com/unsung-heros-of-postgres-episode-i-b9a7056447d2?source=rss-3319eaf2a6c7------2</link>
            <guid isPermaLink="false">https://medium.com/p/b9a7056447d2</guid>
            <category><![CDATA[postgresql-database]]></category>
            <category><![CDATA[database-administration]]></category>
            <category><![CDATA[postgresql]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Mayur (Do not drink & database)]]></dc:creator>
            <pubDate>Sun, 14 Sep 2025 17:25:31 GMT</pubDate>
            <atom:updated>2025-09-14T17:25:31.442Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h3>Unsung Heros of Postgres : Episode I</h3><p>Not all heroes wear capes. In PostgreSQL, some don’t even write code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*fhn5NG4U11XEIDLO" /></figure><p>At <a href="https://pgday.at/talk/roll-up-your-sleeves-contributing-to-postgres-beyond-code/">PGDay Austria</a>, Floor Drees highlighted this truth: countless contributions to PostgreSQL happen outside of code commits and patches.</p><p>Floor introduced <strong>postgres-contrib.org</strong>, a website launched in July 2024 by members of the community. Its mission is simple but powerful, celebrate the people behind PostgreSQL. Advocates, conference organizers, volunteers, speakers, bloggers, sysadmins, the security team, the Code of Conduct committee, the funding group… the list goes on.</p><p>Curious, I asked if folks who tirelessly answer questions on PostgreSQL Slack and Telegram could also be recognized. Floor and Christoph Berg explained that measuring contributions on such fluid, fast-moving platforms is difficult. Still, Floor encouraged me to write about them and even to add my own blog to Planet PostgreSQL (Finally😄).</p><p>I’ve noticed a trend, more people are asking questions on Slack or Telegram than on the classic mailing lists. For those coming from other databases, pgsql-hackers can feel intimidating. By contrast, Slack and Telegram provide approachable, beginner-to-intermediate spaces where conversations flow naturally.</p><p>So, taking Floor’s suggestion to heart, here’s my first attempt at spotlighting a few unsung heroes.</p><p>This is only the beginning, many more names will follow.</p><h3>A. Postgres Slack</h3><h3>To join: <a href="https://pgtreats.info/slack-invite">https://pgtreats.info/slack-invite</a></h3><p>Slack is my go-to platform. Threads keep discussions tidy, and I spend most of my time there. These are some of the community members I see helping every day.</p><p><strong>Depesz</strong> — Spot the legendary orange hairs in your thread, and you know help has arrived. One of the most prolific and consistent experts on Postgres slack.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ta0b4eXEZo3uokt0-WWeuw.png" /></figure><p><strong>Jeremy Schneider</strong> — Jeremy answers both cloud and bare-metal questions, and you’ll also find him sharing wisdom in the Aurora channel.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iu4O-4t9UYOLy4eGmjit0A.png" /></figure><p><strong>Ants Aasma</strong> — A performance problem? Ants has an answer. Every. Single. Time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AakIzTARC6kamKpzXVIarw.png" /></figure><h3>B. Postgres Telegram</h3><h3><a href="https://t.me/postgreschat">https://t.me/postgreschat</a></h3><p>I haven’t spent as much time here yet, but one name already shines through.</p><p><strong>Stefanie Janine Stölting</strong> — Admin of the group, and always ready with sharp, technical answers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/990/1*qoeKng8tm5hgoIfY1_2fIA.png" /></figure><p>This list is just the start. PostgreSQL thrives because of the people who show up, share knowledge, and support others. I’ll be adding more names in the next round.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b9a7056447d2" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>