<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Data Bene</title>
  <subtitle>Relational database, open-source and scalable.</subtitle>
  <link href="https://www.data-bene.io/en/blog.xml" rel="self" type="application/atom+xml" />
  <updated>2026-01-27T00:00:00Z</updated>
  <id>https://www.data-bene.io/en/blog.xml</id>
    <entry>
      <title>IvorySQL 5.0+: a game changer for Oracle to PostgreSQL transitions</title>
      <link href="https://www.data-bene.io/en/blog/ivorysql-5/" />
      <updated>2026-01-27T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/ivorysql-5/</id>
     <content type="html"><![CDATA[ <p>IvorySQL: “advanced, fully featured, open source Oracle compatible PostgreSQL with a firm commitment to always remain 100% compatible and a Drop-in replacement of the latest PostgreSQL.” (<a href="https://github.com/IvorySQL/IvorySQL" rel="noopener">GitHub</a>)</p>
<p>Also, it’s our team’s favorite engine to translate both foreign SQL and foreign applications for PostgreSQL! We believe in transitions, not migrations - a gradual shift from the old database engine to the new, specifically to reduce risk and optimize results. Using a project like this makes a huge difference in achieving both these goals.</p>
<p>It’s been a little bit since the latest major version was released, but we’re still excited about what’s new and wanted to share.</p>
<h2 id="whats-new"><a class="heading-anchor" href="#whats-new">What’s new</a></h2>
<p>Version 5.0 (<a href="https://github.com/IvorySQL/IvorySQL/releases/tag/IvorySQL_5.0" rel="noopener">release notes</a>) came out on November 25, 2025 and there’s already been a minor version released since then (<a href="https://github.com/IvorySQL/IvorySQL/releases/tag/IvorySQL_5.1" rel="noopener">5.1 release notes</a>) on December 18, 2025. These editions of the project were the direct result of massive efforts from the IvorySQL team to provide a lot of quality feature improvements as well as implement PostgreSQL 18 compatibility.</p>
<p>IvorySQL 5 brought a lot of necessary changes with it, including:</p>
<ul class="list">
<li><strong>PLiSQL</strong> - a compatible subset of Oracle PL/SQL</li>
<li><strong>Oracle-Compatible Package Support</strong></li>
<li><strong>Oracle-Style Sequence Support</strong></li>
<li>v5.0 enhancements such as <strong>ROWID</strong>, <strong>%TYPE</strong>, <strong>%ROWTYPE</strong>, and <strong>nested subfunctions</strong></li>
</ul>
<p>In particular, we really enjoy a lot of the functionality upgrades.</p>
<p>For example, IvorySQL now has <strong>better NULL handling</strong>, where NULL is now treated like an empty string in compatible mode (matching Oracle behavior) to avoid bugs during migration. So, when you have situations such as <code>SELECT CONCAT('a' || NULL)</code>, IvorySQL will now return <code>'a'</code> instead of following PostgreSQL’s behavior of returning <code>NULL</code>.</p>
<p>One enhancement we really enjoy is that you can now <strong>nest functions and procedures</strong>. Functions are able to be embedded inside other functions (like Oracle packages, but simpler, using only private methods). This lets you organize complex logic in one place.</p>
<p>Along the same lines, support was also added for <code>DO [ LANGUAGE lang_name ] code [USING IN | OUT | IN OUT, ...]</code>.</p>
<h2 id="trying-it-out"><a class="heading-anchor" href="#trying-it-out">Trying it out</a></h2>
<p>Currently, we’re ingesting applications that range from only a few packages, procedures, and functions (around 10-50 objects) to massive data loads that include around 50,000 objects (10,000+ procedures and hundreds of packages).</p>
<p>While there are still many features that will need to be added over time, it considerably reduces the effort taken to complete the transition from Oracle to PostgreSQL successfully.</p>
<p>If you’re thinking about testing it for yourself, there are a plethora of options to get started (including building it from source, using containers, etc.)… and even a WASM build! This in particular allows IvorySQL to be run directly in the browser without having to fully install it locally; it’s very convenient to look at syntax support and take the first step into the world of PostgreSQL.</p>
<p>You can deploy the IvorySQL-WASM project locally in just a few steps, following the <a href="https://www.ivorysql.org/blog/ivorysql-wasm/" rel="noopener">blog post IvorySQL published</a> on the subject.</p>
<p>Or, you can <a href="https://trial.ivorysql.org/" rel="noopener">try out the hosted WASM</a> on the IvorySQL website.</p>
<h2 id="whats-next"><a class="heading-anchor" href="#whats-next">What’s next</a></h2>
<p>Hoping to learn more about how to use IvorySQL yourself? Keep an eye out for recorded webinars on their website (<a href="https://www.ivorysql.org/webinars-page" rel="noopener">coming soon!</a>), or <a href="https://www.youtube.com/@ivorysql" rel="noopener">check out recordings</a> from the HOW2025 conference in Jinan, China in the meantime.</p>
<p><a href="https://ivorysql.io/" rel="noopener">The next conference in Jinan</a> is already scheduled, from April 26th to the 28th! (By the way, the <a href="https://sessionize.com/how2026" rel="noopener">Call for Proposals is open</a> until February 27th, 2026.)</p>
<p>Our team is happy to employ contributors to the IvorySQL project. Some of our team members (Cédric Villemain, Yasir Hussain Shah) have been recognized in the release notes for 5.0 and 5.1 - and we have more additions planned. For the next release, we have planned some exciting developments, including:</p>
<ul class="list">
<li><code>ENABLE/DISABLE</code> constraint syntax</li>
<li><code>UTL_FILE</code> package addition</li>
<li>Oracle-style <code>CREATE TRIGGER</code> body (without needing to create a function beforehand)</li>
<li>Support for Oracle’s legacy join operator <code>(+)</code></li>
</ul>
<p>We’re looking forward to seeing the result of ongoing community work for the next release as well. Many great features are actively being added; for example, recently a new contributor to the project, Rophy Tsai, added the <code>DBMS_OUTPUT</code> and <code>DBMS_UTILITY</code> packages: something widely used across Oracle-based SQL codebases. It was recently merged to IvorySQL’s main branch, and will likely be included in the next minor or major release.</p>
<p>For those looking to transition to or explore PostgreSQL without extensive modifications to their existing database logic and applications, IvorySQL (specially v5.x) offers a practical solution. A direct migration to PostgreSQL could, in some cases, require significant changes to both database objects and application code. IvorySQL helps bridge this gap, allowing a smoother adoption of PostgreSQL with greater compatibility.</p>
<h2 id="additional-resources"><a class="heading-anchor" href="#additional-resources">Additional resources</a></h2>
<ul class="list">
<li><a href="https://www.postgresql.org/about/news/ivorysql-50-released-major-oracle-compatibility-expansion-on-postgresql-180-foundation-3180/" rel="noopener">PostgreSQL.org announcement for IvorySQL 5</a></li>
<li><a href="https://github.com/orgs/IvorySQL/projects/19" rel="noopener">IvorySQL 5.0 roadmap on GitHub</a></li>
</ul>
 ]]></content>
			<author>
				<name>Yasir Hussain Shah</name>
			</author>
    </entry>
    <entry>
      <title>CERN PGDay: an annual PostgreSQL event in Geneva, Switzerland</title>
      <link href="https://www.data-bene.io/en/blog/cern-pgday-2026/" />
      <updated>2026-01-22T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/cern-pgday-2026/</id>
     <content type="html"><![CDATA[ <p>If you’re located near Western Switzerland and the Geneva region (or you just want to visit!), you might find it well worth your time to attend <a href="https://www.swisspug.org/cern-pgday-2026.html" rel="noopener">CERN PGDay 2026</a>. It’s an annual gathering (this year occurring on February 6th, 2026) for anyone interested in learning more about PostgreSQL that takes place at CERN, the world’s largest particle physics laboratory.</p>
<p><em>If you find the subject of particle physics interesting, you may want to visit anyways! They offer free access to many activities that run from Tuesday to Sunday; <a href="https://visit.cern/programme" rel="noopener">you can view the full programme here</a>.</em></p>
<p>Here, you’ll be able to attend a single track of seven English-language sessions, with a social gathering afterwards to enjoy CERN while continuing to connect with the rest of the attendees.</p>
<p>This year, there’ll be:</p>
<ol class="list">
<li><strong>A new PostgreSQL backend for CERN Tape Archive scheduling for LHC Run 4</strong> - Konstantina Skovola, CERN</li>
<li><strong>DCS Data Tools - PostgreSQL/TimescaleDB Implementation for ATLAS DCS Time-Series Data</strong> - Dimitrios Matakias, Paris Moschovakos, CERN</li>
<li><strong>Operational hazards of managing PostgreSQL DBs over 100TB</strong> - Teresa Lopes, Adyen</li>
<li><strong>Vacuuming Large Tables: How Recent Postgres Changes Further Enable Mission Critical Workloads</strong> - Robert Treat, AWS</li>
<li><strong>The (very practical) Postgres Sharding Landscape</strong> - Álvaro Hernández, OnGres</li>
<li><strong>The Alchemy of Shared Buffers: Balancing Concurrency and Performance</strong> - Josef Machytka, credativ</li>
<li><strong>When Kafka Met Elephant: A Love Story about Fast Ingestion</strong> - Barbora Linhartova, Jan Suchanek, Baremon</li>
</ol>
<p>The first talk of the day is of particular note…</p>
<blockquote>
<p>The CERN Tape Archive (CTA) stores over one exabyte of scientific data. To orchestrate storage operations (archival) and access operations (retrieval), the CTA Scheduler coordinates concurrent data movements across hundreds of tape servers, relying on a Scheduler Database (Scheduler DB) to manage the metadata of the in-flight requests. The existing objectstore-based design of the CTA Scheduler DB is a complex transactional management system. This talk presents the development of a new PostgreSQL-based backend for the CTA Scheduler as an off-the-shelf solution which simplifies implementation and is expected to significantly reduce future development and operational costs. We describe the implementation of all main CTA workflows and explain how PostgreSQL addresses the limitations of the objectstore-based system, providing the foundation for the tenfold increase in data throughput expected during LHC Run 4.</p>
</blockquote>
<p><em>(<a href="https://indico.cern.ch/event/1504097/contributions/6833857/" rel="noopener">link to talk description</a>)</em></p>
<p>In a world where ever larger amounts of digital information must be stored, learning more about how CERN manages over one exabyte of scientific data is sure to be an interesting experience.</p>
<p>Geneva is home to many international organizations across the public, private, and scientific sectors. If you’d like to explore the topic of PostgreSQL in more depth through engaging in discussion or attending sessions, it’s a fun location to meet and learn. Thinking of coming by? You can <a href="https://indico.cern.ch/event/1504097/registrations/114102/" rel="noopener">register until February 1st</a>.</p>
<p>Last year’s session recordings can be viewed by <a href="https://indico.cern.ch/event/1471762/timetable/#20250117" rel="noopener">visiting the 2025 schedule</a> and selecting the paperclip symbol next to the talk you’re interested in.</p>
<p>Stop by and see us in the catering area; we’re proud to be sponsoring the event again this year and will have a table or booth where you can visit. We’d love to talk about what PostgreSQL and open-source innovation, development, &amp; whatever questions you have.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Database optimization and the importance of reducing global digital pollution</title>
      <link href="https://www.data-bene.io/en/blog/database-optimization-and-global-pollution/" />
      <updated>2026-01-19T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/database-optimization-and-global-pollution/</id>
     <content type="html"><![CDATA[ <p>I’ve been thinking back to <a href="https://pgibz.io/" rel="noopener">Postgres Ibiza (PGIBZ)</a> that took place a few weeks ago… And not just because I miss the warmth and sunshine of Ibiza as winter as arrived in Cognac! No, I was remembering how the island was still bearing some signs of the recent floods, even though the islanders were actively working on erasing and repairing the impacts it had caused. The latest news from the Caribbeans and from Asia made me realize that Ibiza had been, relatively speaking, quite lucky.</p>
<p>That particular atmospheric event followed major heatwaves and broken records across the U.S., Europe, and Asia in the past few years. Just this last week at the time of this article, there has been historic flooding with profound damage in Washington state (U.S.)… more than nine million acre-feet of water dumped on the state over ten days… with the torrential downpour predicted to continue throughout the West Coast the rest of the year.</p>
<p>I don’t know if the relevancy of Ibiza’s floods in particular played a part in the way my short talk at the conference was received, but I am still grateful the topic at hand was not only heard, but listened to - even thought about and discussed. I must admit I was not expecting that.</p>
<p>I am part of those who believe that global environmental challenges are about to completely transform our societies on every level as resources get more limited and redistributed. I am the one asking around if anyone else wonders “what good will my comfortable salary do me if potatoes can’t grow anymore?”. Maslow clearly illustrated that it is less necessary to be rich than fed. Yet, as we all know, the environment is still not priority one, even after all this time and all the lessons we’ve experienced.</p>
<p>So, for me it made sense to discuss the topic at a PostgreSQL conference, because it should simply be discussed everywhere. It is a topic that is relevant to each and every one of us, because it involves the Earth itself that we reside on and take for granted. Yet, was I confident about finding a receptive audience? Nope!</p>
<p>I felt slightly uncomfortable – I usually do as a non-tech person at a technical event… – for taking the audience into a space they were not necessarily there for. I was hoping I would not bore, or bother, or even annoy. But after only the first few slides I saw that people were taking pictures of the data I was sharing, some were nodding, some were seeing those figures for the first time and raised an eyebrow. And when I linked it all with what we do daily and the impact of the digital pollution we produce, instead of facing disinterest or disapproval I got “why not!” looks in the room.</p>
<h2 id="so-what-digital-pollution-do-we-produce"><a class="heading-anchor" href="#so-what-digital-pollution-do-we-produce">So what digital pollution do we produce?</a></h2>
<p>According to Greenpeace, digital pollution refers to all forms of pollution caused by the IT sector: greenhouse gas emissions, chemical contamination, erosion of biodiversity, and production of electronic waste.</p>
<p>Yes, there are some innovative solutions being designed to handle some of this digital pollution. For example, some situations are ideal for creating data centers that are able to use the heat they produce in order to heat nearby offices or homes. Projects such as Amazon’s Tallaght project is “the first large-scale district heating network of its kind in Ireland”, helping to “significantly reduce emissions in the area by almost 1,500 tonnes of CO2/year, establishing Tallaght as a leader in local energy action” (<a href="https://www.seai.ie/case-studies/tallaght-district-heating" rel="noopener">source</a>).</p>
<p>However, the growth in the number of users equipped with at least one connected terminal (especially in developing countries), the increase in the ratio of the number of connected terminals per individual (from 2.1 in 2015 to 3.3 in 2020 on average worldwide), the increase in video traffic coupled with the increasing share of HD and UHD quality images and the shift of usage to consumption on demand (streaming, VOD, cloud gaming) have resulted in an explosion of traffic on networks (more than 25% per year) and in data centers (more than 35% per year). This growth is occurring at a rate that surpasses energy efficiency gains in equipment, networks and data centers. These traffic forecasts are also regularly revised upwards.</p>
<p>Although the number of “standard” devices (excluding connected objects) has increased significantly between 2000 and 2015, it stabilises between 2015 and 2025 because the market is saturated.</p>
<p>Although the mass per user decreases slightly, from 63 kg CO2 emmissions to 58 kg between 2010 and 2025, the total mass (user equipment, networks, data centres) is multiplied by more than 2.5 in 15 years: it increases from 128 million tonnes in 2010 to 317 million tonnes in 2025.</p>
<p>This explains the stress on raw materials, especially “conflict minerals” and other rare earths.</p>
<h2 id="the-key-to-a-greener-world"><a class="heading-anchor" href="#the-key-to-a-greener-world">The key to a greener world</a></h2>
<p>Performance optimization for databases doesn’t just result in improved costs and speed. When we work on improving a query, we save that little bit of extra energy that would have been used to read/write, that extra disk movement that was always unnecessary. Other essential responsible practices that in a clever way allow you to better harness the power of technology results not just in a more technically efficient result but also - without realizing or thinking about it - doing some good for the planet.</p>
<p>For example, some actions we commonly consider for our own good that have an equally beneficial result for our planet include:</p>
<ul class="list">
<li>query optimization</li>
<li>index optimization</li>
<li>conducting performance audits to see bottlenecks and identify problems</li>
<li>selecting less energy-intensive technologies</li>
<li>reducing your data footprint (removing redundant, corrupt, or unnecessary data)</li>
<li>optimizing the storage infrastructure and computing power to reduce energy consumption</li>
</ul>
<p>We need to think about digital sobriety, thoughtful coding practices and considerate energy consumption as being the key to greener coding and integrate that parameter in the way we work every day and in the way we build, manage and develop database solutions in order to minimize our environmental footprints as much as possible. These kinds of actions can generate significant cost savings for our own companies and for our customers, which can then be reinvested in R&amp;D projects to increase energy efficiency. It’s a virtuous circle.</p>
<p>A closing thought to this section: AI in particular drives far higher water usage, emissions, and e-waste (training AI models is one of the most resource-intensive computing tasks on the planet!). In a world where it has become common to integrate AI into every corner of applications and day-to-day coding practices, being deliberate in how such technologies are used to ensure they are truly the best solution for the problem at hand has a huge impact. Is AI really the most appropriate solution for that issue you’ve been thinking about? Or are you considering its usage merely because it’s easier to implement than something more technically involved?</p>
<h2 id="back-to-you"><a class="heading-anchor" href="#back-to-you">Back to you</a></h2>
<p>And that’s an interesting twist to consider regarding our day-to-day. We sometimes complain about needing to know there’s meaning to what we do; well here’s some food for thought to fuel your complaints!</p>
<p><strong>A brief note from our Marketing team here at Data Bene</strong>: our team of experienced PostgreSQL engineers can help with improving your own energy efficiency, database optimizations, and thoughtful coding practices that will result in direct benefits to you: speedier database operations, decreased resource usage, lessened costs, and a greener planet. Curious about what we offer? <a href="https://data-bene.io/en/#contact" rel="noopener">Get in touch - we’d love to chat.</a></p>
 ]]></content>
			<author>
				<name>Catherine Bouxin</name>
			</author>
    </entry>
    <entry>
      <title>Open Source Experience 2025</title>
      <link href="https://www.data-bene.io/en/blog/open-source-experience-2025/" />
      <updated>2026-01-03T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/open-source-experience-2025/</id>
     <content type="html"><![CDATA[ <p>The 2025 edition of the <a href="https://www.opensource-experience.com/" rel="noopener">Open Source Experience (OSXP)</a> took place on December 10th and 11th under the theme “Open Source, key to Europe’s strategic autonomy.” As you might expect, the focus was entirely on redefining Europe’s digital future as being driven by open source innovations across all technologies (including data management, cloud computing, and cybersecurity). This year, many of the talks were largely focused on the intersection between open source and AI technologies (in alignment with the focus the technology industry has had on AI in general, in 2025).</p>
<h2 id="the-event"><a class="heading-anchor" href="#the-event">The event</a></h2>
<p>The event lasted two days, featuring 90 exhibitors, 130 sessions, 150 speakers, and over 4,000 participants – a truly large-scale conference held at the Cité des Sciences et de l’Industrie in Paris.</p>
<p>This particular venue was smaller than last year’s venue (Le Palais de Congrés) and the rooms we went to were all full as a result of being very small (about 20 or 30 seats or so at most).</p>
<h2 id="the-talk-format"><a class="heading-anchor" href="#the-talk-format">The talk format</a></h2>
<p>Presentations were given in both English and French. Interestingly, there were no “silent rooms” this year (where headphones are provided to each attendee). Not everyone enjoyed that format last year, but it was a useful one for following two talks, or switching between them depending on the content or questions.</p>
<p>Two of our team members were in attendance and had the opportunity to explore various exhibitors and event rooms spread across three floors. The talks lasted 20 minutes. While too short to delve into details, this format was excellent for discovering new technologies and piquing our interest at a glance.</p>
<h2 id="the-talk-content"><a class="heading-anchor" href="#the-talk-content">The talk content</a></h2>
<p>There were six tracks that talks were categorized by:</p>
<ul class="list">
<li>Economic models and governance for sustainable open strategies</li>
<li>Artificial intelligence and scientific computing for data analysis</li>
<li>Cloud architecture and virtualization for an autonomous future</li>
<li>Development - software innovation in action</li>
<li>Cybersecurity and the software production chain: Open Source as a foundation of trust</li>
<li>Collaborative tools and business applications: regaining digital autonomy</li>
</ul>
<p>We found the topic of open source solutions within the public sector to be the most interesting. In particular, it was easy to see our reliance as a global society on the big five tech companies (GAFAM: Google, Apple, Facebook, Amazon, and Microsoft) has grown significantly in the past few years. Open source software is a direct solution for protecting our collective right to privacy in the digital age, which is exactly why conferences such as this are so important for the discovery of OSS alternatives and innovation that leads to further development within this sector.</p>
<h2 id="attendance"><a class="heading-anchor" href="#attendance">Attendance</a></h2>
<p>Attendance was particularly high from the very first day. We were delighted to have the opportunity to interact in person and meet our partners, especially <a href="https://www.ow2.org/" rel="noopener">OW2</a>, which also organizes an annual Open Source event in June. (The call for presentations is open until February 14, 2026 – see the OW2Con’26 call for proposals <a href="https://www.ow2con.org/view/2026/Call_For_Presentations" rel="noopener">here</a>.)</p>
<p>Since the event was entirely focused on open source technologies, we were able to discuss with numerous participants topics such as PostgreSQL support, along with the challenges and organizational impacts for companies wishing to innovate and adopt PostgreSQL, against the backdrop of market demand to break free from proprietary software licensing constraints.</p>
<p>We also had the pleasure of meeting key players in open source hardware innovation, which resonates with our own R&amp;D on RISC-V processors.</p>
<p>Many free software and open source projects were represented. Some examples include <a href="https://nextcloud.com" rel="noopener">Nextcloud</a> (a self-hosted cloud collaboration platform that we personally use for hosting here at Data Bene) and <a href="https://opentalk.eu/en" rel="noopener">OpenTalk</a>, a video-conferencing solution that is GDPR-compliant, operating within German data centers.</p>
<h2 id="closing-thoughts"><a class="heading-anchor" href="#closing-thoughts">Closing thoughts</a></h2>
<p>The event was successful and well-organized. The only thing that would have improved the experience would have been longer presentations to explore the various topics discussed in more depth. If you want to discover new open source projects, note that this event is also a great opportunity to freely exchange ideas on these topics.</p>
<p>The video replays for 2025 have not yet been published, but past conference recordings can be found on the <a href="https://www.opensource-experience.com/en/video-replays" rel="noopener">official website, here</a>.</p>
<p>Overall, we thoroughly enjoyed the event and hope to attend next year!</p>
 ]]></content>
			<author>
				<name>Grégory Tiram</name>
			</author>
    </entry>
    <entry>
      <title>PGIBZ 2025: An Event for the Postgres Community in Ibiza</title>
      <link href="https://www.data-bene.io/en/blog/postgres-ibiza-2025/" />
      <updated>2025-12-11T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/postgres-ibiza-2025/</id>
     <content type="html"><![CDATA[ <p><a href="https://pgibz.io/" rel="noopener">Postgres Ibiza (PGIBZ)</a>: An open source conference designed to bring together people with a love for PostgreSQL in Ibiza, a relaxed place for fresh and innovative discussions. An international event run by the nonprofit PostgreSQL España.</p>
<p>This was the first time that the Data Bene team attended the event, and we’re happy to share that it was a very positive experience.</p>
<h2 id="the-conference"><a class="heading-anchor" href="#the-conference">The Conference</a></h2>
<h3 id="location-and-venue"><a class="heading-anchor" href="#location-and-venue">Location and Venue</a></h3>
<p>As its name suggests, this conference takes place on the Mediterranean island of Ibiza. For those who are less familiar, the Official Tourism Site provides <a href="https://ibiza.travel/en/know-ibiza/where-we-are/" rel="noopener">a nice overview</a> that you may refer to. While it should go without saying, this <a href="https://whc.unesco.org/en/list/417" rel="noopener">UNESCO World Heritage Site</a> has incredible offerings outside of the conference itself. Combined with a potentially long-haul flight, it’s strongly recommended to plan an extra day or two (or more) to explore the island and enjoy the local experience.</p>
<p>The event itself is hosted at the <a href="https://www.palaciocongresosibiza.com/ibiza-congress-center/#main_english" rel="noopener">Palacio de Congresos de Ibiza</a>; a two-story conference center with multiple rooms and catering. Though located outside of the capital city, the venue can be reached by car in good timing (~15 minutes). To add, the venue is situated within walking distance of numerous hotels, restaurants, and a beach! We happened to have stayed at <a href="https://www.hoteltrestorresibiza.com/" rel="noopener">Hotel Tres Torres</a>, which we can recommend, though admittedly it’s difficult to make a wrong decision, especially following a sprinkle of background research.</p>
<p>Briefly, on the topic of extracurriculars, our go-to recommendation would be to visit the capital city, Ibiza. There you will be able to find a surprisingly large amount of shopping, restaurants, and sightseeing. Adding to that a walk through the historic neighborhood and you’ve got quite the memorable experience.</p>
<h3 id="attendance"><a class="heading-anchor" href="#attendance">Attendance</a></h3>
<p>This year’s PGIBZ welcomed about 30-40 attendees from across the globe, including China and the United States. And while there are certainly two sides to the coin, I consider this group size as more of a positive. Indeed, during both the presentation Q/A sessions, as well as the coffee breaks, I felt interactions were more engaging overall. This was especially true when meeting and reconnecting with members of both more modest and global enterprise-scaled companies.</p>
<h2 id="presentations-from-our-team"><a class="heading-anchor" href="#presentations-from-our-team">Presentations from our team</a></h2>
<h3 id="catherine"><a class="heading-anchor" href="#catherine">Catherine</a></h3>
<p>The first of the Data Bene speakers, and indeed the keynote of the first day, was Catherine Bouxin. Her presentation addressed the environmental impact of technology, and reflected the philosophy that important topics are not always the ones being discussed, and often aren’t considered a concern at all! Indeed, Catherine framed this conversation primarily as a reminder of the responsibility we as PostgreSQL community members share. There have been many exciting inventions of late, some with societal-changing implications, but we can not ignore the resource intensity that many of them require.</p>
<p>We stand confidently with Catherine’s message about contributing towards a greener future and making thoughtful decisions to this end, and we are excited that this was very well-received by the audience.</p>
<h3 id="cedric"><a class="heading-anchor" href="#cedric">Cedric</a></h3>
<p>On second day, our founder and CEO, Cédric Villemain, presented on the statistics-based highlights of the PostgreSQL major release version 18 (<a href="https://www.postgresql.org/docs/release/18.0/" rel="noopener">official notes linked here</a>). (After the event, he created a blog post on the topic of Cumulative Statistics in Postgres 18 - <a href="https://www.data-bene.io/en/blog/cumulative-statistics-in-postgresql-18/" rel="noopener">check it out here</a>!) Our team here at Data Bene are a fan of stats and surfacing data, which is what led us to create the PostgreSQL extension, <a href="https://codeberg.org/Data-Bene/StatsMgr" rel="noopener">StatsMgr</a>. <em>If you previously missed information on StatsMgr and would like to learn more, <a href="https://www.data-bene.io/en/blog/postgres-cafe-expand-monitoring-capabilities-with-statsmgr/" rel="noopener">check out our previous blog and Postgres Café podcast episode on the topic.</a></em></p>
<h3 id="evan"><a class="heading-anchor" href="#evan">Evan</a></h3>
<p>Directly after Cedric, I had the opportunity to present on developing and maintaining a Rust-based PostgreSQL extension (currently still very early stage) that helps facilitate the transition from Oracle to PostgreSQL. This project, named <code>pgtap_gen</code>, leverages the pre-existing <a href="https://github.com/theory/pgtap" rel="noopener">pgTAP</a> project to automate unit test creation on IvorySQL (100% open-source forked PostgreSQL with Oracle-analogous components). It was very encouraging to hear audience engagement and feedback. What’s more, it feels great to participate in the PostgreSQL ecosystem, even if it’s for proof-of-concept initiatives!</p>
<h3 id="frederic"><a class="heading-anchor" href="#frederic">Frédéric</a></h3>
<p>Towards the end of the second day, Frédéric delievered a talk on transaction isolation levels in PostgreSQL (that you may get the chance to see later on, as he’s submitted the same talk to pgDay Paris 2026 and PGDay CERN 2026!). He delved into each isolation level in Postgres with practical examples, and explained how everything works behind the scenes to define real steps for confidently choosing the right level for the right context. The attendees seemed to find the talk interesting and educational, so we may yet see further content on this topic and similar to help others who missed the opportunity to learn about the subject.</p>
<h2 id="concluding-thoughts"><a class="heading-anchor" href="#concluding-thoughts">Concluding Thoughts</a></h2>
<p>We chose to sponsor and attend PGIBZ 2025 as we believe it is important to further the PostgreSQL community across the world. No matter what, this is an event that is seeking to further Postgres education for the better. Profits from the event are used by the parent nonprofit organization, PostgreSQL España, to invest in translations of the official PostgreSQL documentation into Spanish.</p>
<p>Further breakdowns of each of the talk topics mentioned above are in-the-works; feel free to follow us on <a href="https://www.linkedin.com/company/91744288/" rel="noopener">LinkedIn</a> and <a href="https://fosstodon.org/@data_bene" rel="noopener">Mastodon</a> to keep an eye out for them when they’re published on our blog.</p>
<p>We very much enjoyed our time at PGIBZ 2025, and are honored to have had the opportunity to present and participate. Looking forward to returning next year!</p>
<h2 id="references"><a class="heading-anchor" href="#references">References</a></h2>
<ul class="list">
<li><a href="https://ibiza.travel/en/know-ibiza/where-we-are/" rel="noopener">https://ibiza.travel/en/know-ibiza/where-we-are/</a></li>
<li><a href="https://pgibz.io/" rel="noopener">https://pgibz.io/</a></li>
<li><a href="https://whc.unesco.org/en/list/417" rel="noopener">https://whc.unesco.org/en/list/417</a></li>
<li><a href="https://www.hoteltrestorresibiza.com/" rel="noopener">https://www.hoteltrestorresibiza.com/</a></li>
</ul>
 ]]></content>
			<author>
				<name>Evan Stanton</name>
			</author>
    </entry>
    <entry>
      <title>How to Transition Easily to PostgreSQL from Oracle</title>
      <link href="https://www.data-bene.io/en/blog/transition-easily-to-postgresql-from-oracle/" />
      <updated>2025-12-10T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/transition-easily-to-postgresql-from-oracle/</id>
     <content type="html"><![CDATA[ <p>If you need to transition easily from Oracle to PostgreSQL without worrying about type conversions or other Oracle packages that require modifications to be PostgreSQL-compatible, a useful solution is IvorySQL!</p>
<h2 id="introduction"><a class="heading-anchor" href="#introduction">Introduction</a></h2>
<p>More and more companies are seeking to free themselves from the costs and constraints of Oracle by migrating to PostgreSQL. But how can this transition be achieved without spending months on it? Here is a proven, fast and secure method, based on feedback and open source tools.</p>
<h3 id="start-by-assessing-and-mapping"><a class="heading-anchor" href="#start-by-assessing-and-mapping">Start by assessing and mapping</a></h3>
<p>Before migrating, it is essential to take stock of the situation: we start by listing Oracle objects through performing a complete extraction (including tables, views, sequences, procedures, functions, and packages).</p>
<p>It is also important to communicate regularly with the client to refine findings and validate directions, as well as to identify dependencies (applications connected with which technology, jobs, interfaces, etc.).</p>
<p>Finally, identify the client’s Oracle-specific features (specific functions such as ROWID, DUAL, DBMS_XXX, etc.) and any other keywords requiring special attention.</p>
<h3 id="choosing-the-right-open-source-tools"><a class="heading-anchor" href="#choosing-the-right-open-source-tools">Choosing the right open source tools</a></h3>
<p>The success of a transition to PostgreSQL – because it is indeed a gradual transition and not a migration – depends as much on strategy as it does on tools.</p>
<p>It is not enough to simply copy objects: you need to understand the subtleties of the Oracle engine and intelligently transpose them into the PostgreSQL universe.</p>
<p>Among the essential tools, Ora2Pg plays a central role. Not only does it generate clear inventory reports, it also automates the conversion of schemas, data and PL/SQL code. It is a valuable accelerator for well-structured projects.</p>
<p>But in some contexts, the reality is more complex. Many customers accumulate significant technical debt, with thousands of lines of procedural code. Attempting to rewrite everything in PL/pgSQL in a short period of time would exhaust teams and compromise the migration itself. Maintaining two code bases— one in PL/SQL, the other in PL/pgSQL— during a complete transition phase is often organisationally untenable.</p>
<p>This is precisely where IvorySQL offers a powerful alternative. This fork of PostgreSQL, enhanced with Oracle compatibilities (PL/SQL, ROWID, DUAL, etc.), significantly reduces the need for immediate rewriting. By combining IvorySQL with targeted documentation and business validation scripts, the transition is easier, more reliable, and above all, more controlled.</p>
<p>Once in production, teams have the time they need to gradually rewrite their procedural and remaining application code in PL/pgSQL, without pressure or functional disruption.</p>
<h3 id="integration-and-tests"><a class="heading-anchor" href="#integration-and-tests">Integration and tests</a></h3>
<p>One of the great advantages of IvorySQL is that it performs part of the integration upstream. Thanks to its native support for PL/SQL, Oracle objects and Oracle-compatible syntax, many elements migrated via Ora2Pg work immediately without any major adaptation.</p>
<p>Of course, this does not eliminate the need for testing. On the contrary, it is essential to validate business behaviour in an IvorySQL pre-production environment. Procedures, functions, packages, triggers, and views must be tested with real-world cases, comparing the results between Oracle and IvorySQL to ensure functional equivalence.</p>
<p>Comparison scripts can be used to verify query responses, transaction effects, or the behaviour of migrated functions. But in many cases, IvorySQL significantly reduces the need for patches or rewrites, speeding up production and securing the transition.</p>
<h3 id="document-and-support"><a class="heading-anchor" href="#document-and-support">Document and support</a></h3>
<p>A successful transition is not limited to technical aspects; it also relies on clear documentation and appropriate support. It is essential to write comprehensive test specifications for each complex object and module (procedure, package, trigger, etc.) in order to keep track of technical choices, adaptations made, and points of attention.</p>
<p>Support for client teams is just as important. Targeted workshops are used to share best practices, explain the differences between Oracle and PostgreSQL, and facilitate the adoption of IvorySQL.</p>
<p>Finally, a successful transition to PostgreSQL also depends on support for technical and functional teams. Targeted training sessions enable developers, DBAs, and project managers to learn the specifics of IvorySQL, understand the differences with Oracle, and quickly develop their skills.</p>
<p>This system also relies on structured technical support, which helps resolve issues, secure implementation choices, and facilitate communication between project teams and migration experts.</p>
<h2 id="ivorysql-in-the-real-world"><a class="heading-anchor" href="#ivorysql-in-the-real-world">IvorySQL in the real world</a></h2>
<p>During a recent assignment for a private sector company, we supported the transition from an Oracle database to IvorySQL in a challenging context: where there was significant technical debt, high volume, and tight deadlines.</p>
<p>Thanks to IvorySQL and our ability to automate this transition, it was completed quickly and almost all objects were integrated without rewriting.</p>
<p>The switch from IvorySQL to PostgreSQL can be carried out smoothly, as long as the application is fully functional and meets business expectations.</p>
<p>The teams were able to focus on business testing, while targeted training and technical support enabled rapid skill development.</p>
<p>It is essential to succeed in this type of project in order to build confidence and roll out this operation across your entire Oracle instance fleet!</p>
<p>Are you considering a transition from Oracle to PostgreSQL? Let’s talk about it.</p>
<p>Contact our team of experts at any time: <a href="mailto:contact@data-bene.io">contact@data-bene.io</a></p>
<p>On November 26, 2025 IvorySQL 5.0 was released - <a href="https://www.postgresql.org/about/news/ivorysql-50-released-major-oracle-compatibility-expansion-on-postgresql-180-foundation-3180/" rel="noopener">view the announcement here</a> for more information about this open-source project.</p>
 ]]></content>
			<author>
				<name>Stéphane Carton</name>
			</author>
    </entry>
    <entry>
      <title>Did you know? Tables in PostgreSQL are limited to 1,600 columns</title>
      <link href="https://www.data-bene.io/en/blog/did-you-know-tables-in-postgresql-are-limited-to-1600-columns/" />
      <updated>2025-11-13T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/did-you-know-tables-in-postgresql-are-limited-to-1600-columns/</id>
     <content type="html"><![CDATA[ <p><strong>Did you know a table can have no more than 1,600 columns?</strong> This blog article was inspired by a conversation Pierre Ducroquet and I had.</p>
<h2 id="first-the-documentation"><a class="heading-anchor" href="#first-the-documentation">First, the documentation</a></h2>
<p>The PostgreSQL documentation <a href="https://www.postgresql.org/docs/current/limits.html" rel="noopener">Appendix K</a> states a table can have a maximum of 1,600 columns.</p>
<p>This is a <strong>hard coded limit</strong> that can be found in the source code at <code>src/include/access/htup_details.h</code>:</p>
<pre class="language-plaintext"><code class="language-plaintext">#define MaxTupleAttributeNumber 1664
#define MaxHeapAttributeNumber	1600</code></pre>
<h2 id="reaching-the-limit-the-expected-way"><a class="heading-anchor" href="#reaching-the-limit-the-expected-way">Reaching the limit the expected way</a></h2>
<p>Let’s fully validate the claim and test accordingly.</p>
<h3 id="playing-with-table-definition"><a class="heading-anchor" href="#playing-with-table-definition">Playing with table definition</a></h3>
<p>Here, we’ll use a simple bash script because it is easy to adapt while testing.</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Classic example</span>

<span class="token keyword">DO</span> $$             
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1601;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1601(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1601</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1601 ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>The typical output is as follows:</p>
<pre class="language-plaintext"><code class="language-plaintext">NOTICE:  table "tint_1600" does not exist, skipping
ERROR:  tables can have at most 1600 columns
CONTEXT:  SQL statement "ALTER TABLE tint_1600 ADD COLUMN i_1601 int;"
PL/pgSQL function inline_code_block line 8 at EXECUTE</code></pre>
<p>So far so good (or at least, all is working as expected).</p>
<p>You might have the idea to try replacing <code>int4</code> with <code>int2</code> type to create a 1,600+ column table. It will not work as this is a hard coded limit.</p>
<h3 id="playing-with-table-content"><a class="heading-anchor" href="#playing-with-table-content">Playing with table content</a></h3>
<p>Let’s build a 1,600 column table with the same demonstrated code.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">DO</span> $$             
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1600;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1600(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1600</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1600 ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>Another sql script can be used to produce a valid 1,600 column tuple:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    s <span class="token keyword">TEXT</span><span class="token punctuation">;</span>
    rows_inserted <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    s :<span class="token operator">=</span> <span class="token function">format</span><span class="token punctuation">(</span>
                 <span class="token string">'INSERT INTO tint_1600 VALUES (1%s);'</span>
               <span class="token punctuation">,</span> <span class="token keyword">repeat</span><span class="token punctuation">(</span> <span class="token string">',1'</span> <span class="token punctuation">,</span> <span class="token number">1599</span> <span class="token punctuation">)</span> 
               <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> s<span class="token punctuation">;</span>

    GET DIAGNOSTICS rows_inserted <span class="token operator">=</span> ROW_COUNT<span class="token punctuation">;</span>
    RAISE NOTICE <span class="token string">'Rows inserted: %'</span><span class="token punctuation">,</span> rows_inserted<span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>The output is:</p>
<pre class="language-plaintext"><code class="language-plaintext">NOTICE:  Rows inserted: 1
DO</code></pre>
<p>Another success with no surprise.</p>
<h3 id="testing-the-limits"><a class="heading-anchor" href="#testing-the-limits">Testing the limits</a></h3>
<p>Let us continue pushing to the limits.</p>
<p>We now create another 1,600 column table using the <code>char(127)</code> data type.</p>
<p>We reuse our sql script with some modifications:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Create a table with 1,600 columns: 1 x int + 1599 x char(127)</span>
<span class="token keyword">DO</span> $$             
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tint_1600;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tint_1600(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1600</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tint_1600 ADD COLUMN c_%s char(127) NOT NULL;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span>

<span class="token comment">-- Insert a tuple - 1 x int + 1599 x char(127)</span>
<span class="token keyword">DO</span> $$
<span class="token keyword">DECLARE</span>
    s <span class="token keyword">TEXT</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    s :<span class="token operator">=</span> <span class="token function">format</span><span class="token punctuation">(</span> 
                 <span class="token string">'INSERT INTO tint_1600 VALUES (1%s);'</span>
               <span class="token punctuation">,</span> <span class="token keyword">repeat</span><span class="token punctuation">(</span> $q$<span class="token punctuation">,</span><span class="token string">'1'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">127</span><span class="token punctuation">)</span>$q$ <span class="token punctuation">,</span> <span class="token number">1599</span> <span class="token punctuation">)</span> 
               <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> s<span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>The output is:</p>
<pre class="language-plaintext"><code class="language-plaintext">ERROR:  row is too big: size 25616, maximum size 8160</code></pre>
<p>As we can see, the table has 1,600 columns but this time the tuple cannot fit a single heap page which explains the error “row is too big: size 25616, maximum size 8160”. If you paid attention to the modified script, you can see columns are defined as <code>NOT NULL</code> so at table creation PostgreSQL could have proven data insertion was impossible.</p>
<h2 id="what-about-joins"><a class="heading-anchor" href="#what-about-joins">What about JOINs?</a></h2>
<p>To keep things simple, let us auto-join:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">SELECT</span> a<span class="token punctuation">.</span><span class="token operator">*</span><span class="token punctuation">,</span>b<span class="token punctuation">.</span><span class="token operator">*</span> <span class="token keyword">FROM</span> tint_1600 a<span class="token punctuation">,</span> tint_1600 b<span class="token punctuation">;</span>
ERROR:  target lists can have at most <span class="token number">1664</span> entries</code></pre>
<p>Now the <code>SELECT</code> clause (<code>a.*,b.*</code>) is reaching its own limit (<code>MaxTupleAttributeNumber = 1664</code>).</p>
<h2 id="reaching-the-column-limit-the-unexpected-way"><a class="heading-anchor" href="#reaching-the-column-limit-the-unexpected-way">Reaching the column limit the unexpected way</a></h2>
<p>Sometimes, you have to modify your application and it generates schema modifications.<br>
Most of the time, there are table modifications like adding or dropping columns.</p>
<h3 id="exploring-add-/-drop-column"><a class="heading-anchor" href="#exploring-add-/-drop-column">Exploring <code>ADD</code> / <code>DROP COLUMN</code></a></h3>
<p>Let us see what happens from the SQL side when we add, then drop, a column.</p>
<pre class="language-sql"><code class="language-sql"><span class="token operator">=</span><span class="token comment"># CREATE TABLE tadc_1600(i_1 int NOT NULL);</span>

<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE tadc_1600 ADD COLUMN i_2 int NOT NULL;</span>

<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped </span>
   <span class="token keyword">FROM</span> pg_attribute 
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid 
                   <span class="token keyword">FROM</span> pg_class 
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc_1600'</span>
                   <span class="token punctuation">)</span> 
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>
     
 attname <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped 
<span class="token comment">---------+--------+------------+------------+--------------</span>
 i_1     <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 i_2     <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE tadc_1600 DROP COLUMN i_2;</span>

<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span>

<span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped </span>
   <span class="token keyword">FROM</span> pg_attribute 
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid 
                   <span class="token keyword">FROM</span> pg_class 
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc_1600'</span>
                   <span class="token punctuation">)</span> 
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>

           attname            <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped 
<span class="token comment">------------------------------+--------+------------+------------+--------------</span>
 i_1                          <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">2.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>When dropping a column,</p>
<ul class="list">
<li>the name becomes ‘.’ + ‘pg.dropped.’ + attnum + ‘.’,</li>
<li>the column becomes NULLable,</li>
<li>the column is marked as dropped.</li>
</ul>
<h3 id="iterating-add-/-drop-column"><a class="heading-anchor" href="#iterating-add-/-drop-column">Iterating ADD / DROP COLUMN</a></h3>
<p>One can wonder if there is a limit to the number of add/drop operations that can be run on a given table.</p>
<p>As usual, let us try:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- ADD / DROP COLUMN example</span>
<span class="token keyword">DO</span> $$             
<span class="token keyword">DECLARE</span>
    i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">BEGIN</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'DROP TABLE IF EXISTS tadc;'</span><span class="token punctuation">;</span>
    <span class="token keyword">EXECUTE</span> <span class="token string">'CREATE TABLE tadc(i_1 int);'</span><span class="token punctuation">;</span>
    <span class="token keyword">FOR</span> i <span class="token operator">IN</span> <span class="token number">2.</span><span class="token number">.1601</span> <span class="token keyword">LOOP</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tadc ADD COLUMN i_%s int;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">EXECUTE</span> <span class="token function">format</span><span class="token punctuation">(</span><span class="token string">'ALTER TABLE tadc DROP COLUMN i_%s;'</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">END</span> <span class="token keyword">LOOP</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> $$<span class="token punctuation">;</span></code></pre>
<p>The output is:</p>
<pre class="language-plaintext"><code class="language-plaintext">ERROR:  tables can have at most 1600 columns
CONTEXT:  SQL statement "ALTER TABLE tadc ADD COLUMN i_1601 int;"
PL/pgSQL function inline_code_block line 8 at EXECUTE</code></pre>
<p>Oh oh! We reached the 1,600 limit here as well.</p>
<p>Let us explore a bit after add/drop column 1,599 times:</p>
<pre class="language-sql"><code class="language-sql"><span class="token operator">=</span><span class="token comment"># SELECT attname,attnum,attstorage,attnotnull,attisdropped </span>
   <span class="token keyword">FROM</span> pg_attribute 
   <span class="token keyword">WHERE</span> attrelid<span class="token operator">=</span><span class="token punctuation">(</span>
                   <span class="token keyword">SELECT</span> oid 
                   <span class="token keyword">FROM</span> pg_class 
                   <span class="token keyword">WHERE</span> relname<span class="token operator">=</span><span class="token string">'tadc'</span>
                   <span class="token punctuation">)</span> 
     <span class="token operator">AND</span> attnum <span class="token operator">></span> <span class="token number">0</span> <span class="token keyword">ORDER</span> <span class="token keyword">BY</span> attnum<span class="token punctuation">;</span>

             attname             <span class="token operator">|</span> attnum <span class="token operator">|</span> attstorage <span class="token operator">|</span> attnotnull <span class="token operator">|</span> attisdropped 
<span class="token comment">---------------------------------+--------+------------+------------+--------------</span>
 i_1                             <span class="token operator">|</span>      <span class="token number">1</span> <span class="token operator">|</span> p          <span class="token operator">|</span> t          <span class="token operator">|</span> f
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">2.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">2</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">3.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">3</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">4.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">4</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">5.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>    <span class="token operator">|</span>      <span class="token number">5</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t

 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">1599.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>   <span class="token number">1599</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
 <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>pg<span class="token punctuation">.</span>dropped<span class="token punctuation">.</span><span class="token number">1600.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token operator">|</span>   <span class="token number">1600</span> <span class="token operator">|</span> p          <span class="token operator">|</span> f          <span class="token operator">|</span> t
<span class="token punctuation">(</span><span class="token number">1600</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>Well, table <code>tadc</code> has 1,600 columns. You can see this as modifications are appending and table content rewriting is avoided.</p>
<p>At this point, further column add &amp; drop modifications will fail.</p>
<p>Is there anything I can do to escape this situation?</p>
<h4 id="the-vacuum-knight-shall-save-the-postgresql-princess-right"><a class="heading-anchor" href="#the-vacuum-knight-shall-save-the-postgresql-princess-right">The VACUUM knight shall save the PostgreSQL princess, right?</a></h4>
<p>The <code>VACUUM</code> command operates at the tuple level so even if you run a <code>VACUUM FULL</code> the table structure will not change.</p>
<h4 id="so-the-dragon-ate-the-knight-whats-next"><a class="heading-anchor" href="#so-the-dragon-ate-the-knight-whats-next">So, the dragon ate the knight, what’s next?</a></h4>
<p>This is not an issue with dead tuples but rather an issue with the catalog.<br>
You’ll need to create a new table definition.</p>
<p>Here are some solutions, from simple to complex:</p>
<ol class="list">
<li>
<p>Build a new table (requires service downtime)</p>
<ul class="list">
<li><code>CREATE TABLE (LIKE INCLUDING ALL)</code></li>
<li><code>COPY</code> data from old to new table</li>
<li>Rename tables</li>
<li>Drop old table</li>
</ul>
</li>
<li>
<p>Leverage logical replication (minimize service downtime)</p>
<ul class="list">
<li><code>CREATE TABLE LIKE (INCLUDING ALL)</code></li>
<li><code>CREATE local PUBLICATION/SUBSCRIPTION</code></li>
<li>Once data is synchronized, stop/pause application service</li>
<li>Drop subscription</li>
<li>Rename tables</li>
<li>Restart/resume application</li>
<li>Drop old table</li>
</ul>
</li>
</ol>
<h4 id="what-about-foreign-keys"><a class="heading-anchor" href="#what-about-foreign-keys">What about Foreign Keys?</a></h4>
<p>The above solution <em>works</em> fine for simple cases. But real life tables often<br>
use integrity constraints. Let’s explore a bit using foreign keys.</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Foreign key case</span>

<span class="token operator">=</span><span class="token comment"># CREATE TABLE colors (id int, name text );</span>
<span class="token operator">=</span><span class="token comment"># CREATE TABLE objects ( id int, color_id int, name text );</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE colors ADD PRIMARY KEY (id);</span>
<span class="token operator">=</span><span class="token comment"># ALTER TABLE objects ADD CONSTRAINT fk_color</span>
                       <span class="token keyword">FOREIGN</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span>color_id<span class="token punctuation">)</span> <span class="token keyword">REFERENCES</span> colors <span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token operator">=</span><span class="token comment"># INSERT INTO colors </span>
   <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">'red'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">'green'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token string">'blue'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token operator">=</span><span class="token comment"># INSERT INTO objects </span>
   <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'red object'</span><span class="token punctuation">)</span>
         <span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">'green object'</span><span class="token punctuation">)</span>
         <span class="token punctuation">,</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token string">'blue object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Let’s apply the recipe:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Duplicate table structure (valid columns only)  and copy data</span>
<span class="token operator">=</span><span class="token comment"># CREATE TABLE tmp_colors (LIKE colors INCLUDING ALL);</span>
<span class="token operator">=</span><span class="token comment"># INSERT INTO tmp_colors SELECT * FROM colors;</span>

<span class="token comment">-- Do the DROP/RENAME trick</span>
<span class="token operator">=</span><span class="token comment"># BEGIN;</span>
<span class="token operator">=</span><span class="token comment"># DROP TABLE colors;</span>
<span class="token operator">=</span><span class="token comment"># ALTER TABLE tmp_colors RENAME TO colors;</span>
<span class="token operator">=</span><span class="token comment"># COMMIT;</span></code></pre>
<p>The <code>DROP TABLE</code> command issued an error:</p>
<pre class="language-plaintext"><code class="language-plaintext">ERROR:  cannot drop table colors because other objects depend on it
DETAIL:  constraint fk_color on table objects depends on table colors
HINT:  Use DROP ... CASCADE to drop the dependent objects too.</code></pre>
<p>As we can see, the recipe has to be changed to include dependent tables as well.</p>
<p>Adding <code>CASCADE</code> will drop FK constraints on dependent tables.</p>
<p>Let’s run a modified version of the recipe:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Do the DROP/RENAME trick</span>
<span class="token operator">=</span><span class="token comment"># BEGIN;</span>

<span class="token operator">=</span><span class="token comment"># DROP TABLE colors CASCADE;  -- DROP related FOREIGN KEY constaints</span>

<span class="token operator">=</span><span class="token comment"># ALTER TABLE tmp_colors RENAME TO colors;</span>

<span class="token comment">-- Recreate FK contraint</span>
<span class="token operator">=</span><span class="token comment"># ALTER TABLE objects ADD CONSTRAINT fk_color</span>
                       <span class="token keyword">FOREIGN</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span>color_id<span class="token punctuation">)</span> <span class="token keyword">REFERENCES</span> colors <span class="token punctuation">(</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">COMMIT</span><span class="token punctuation">;</span></code></pre>
<p>We have to check the behaviour is the expected one:</p>
<pre class="language-sql"><code class="language-sql"><span class="token operator">=</span><span class="token comment"># INSERT INTO objects VALUES (5,5,'ro');</span>
ERROR:  <span class="token keyword">insert</span> <span class="token operator">or</span> <span class="token keyword">update</span> <span class="token keyword">on</span> <span class="token keyword">table</span> <span class="token string">"objects"</span> violates <span class="token keyword">foreign</span> <span class="token keyword">key</span> <span class="token keyword">constraint</span> <span class="token string">"fk_color"</span>
DETAIL:  <span class="token keyword">Key</span> <span class="token punctuation">(</span>color_id<span class="token punctuation">)</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token operator">is</span> <span class="token operator">not</span> present <span class="token operator">in</span> <span class="token keyword">table</span> <span class="token string">"colors"</span><span class="token punctuation">.</span>

<span class="token operator">=</span><span class="token comment"># INSERT INTO objects VALUES (5,3,'ro');</span>
<span class="token keyword">INSERT</span> <span class="token number">0</span> <span class="token number">1</span></code></pre>
<p>Success!</p>
<p>When integrity constraints are too numerous or you find it difficult to follow,<br>
you may use pg_dump/pg_restore to rebuild all automatically. If service downtime<br>
is an issue, you may use logical replication to perform like pg_dump/pg_restore.</p>
<h2 id="best-is-to-avoid-having-to-deal-with-this"><a class="heading-anchor" href="#best-is-to-avoid-having-to-deal-with-this">Best is to avoid having to deal with this</a></h2>
<p>As you can see, having to deal with the 1,600 column limit is not something you would<br>
like to do just for fun (usually). Notably, it can lead to service downtime.</p>
<h2 id="talk-to-us"><a class="heading-anchor" href="#talk-to-us">Talk to us</a></h2>
<p>Do you have other ideas of how to address this situation? Have you run into odd ways of reaching this hard-coded limit? <a href="https://www.data-bene.io/en/#contact" rel="noopener">Contact us</a>! We always love a good discussion about PostgreSQL.</p>
 ]]></content>
			<author>
				<name>Frédéric Delacourt</name>
			</author>
    </entry>
    <entry>
      <title>Cumulative Statistics in PostgreSQL 18</title>
      <link href="https://www.data-bene.io/en/blog/cumulative-statistics-in-postgresql-18/" />
      <updated>2025-09-29T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/cumulative-statistics-in-postgresql-18/</id>
     <content type="html"><![CDATA[ <p>In <strong>PostgreSQL 18</strong>, the statistics &amp; monitoring subsystem receives a significant overhaul - extended cumulative statistics, new per-backend I/O visibility, the ability for extensions to export / import / adjust statistics, and improvements to GUC controls and snapshot / caching behavior. These changes open new doors for performance analysis, cross‑environment simulation, and tighter integration with extensions. In this article I explore what’s new, what to watch out for, Grand Unified Configuration (GUC) knobs, and how extension authors can leverage the new C API surface.</p>
<h2 id="introduction-and-motivation"><a class="heading-anchor" href="#introduction-and-motivation">Introduction &amp; motivation</a></h2>
<p>Statistics (in the broad sense: monitoring counters, I/O metrics, and planner / optimizer estimates) lie at the heart of both performance tuning and internal decision making in PostgreSQL. Transparent, reliable, and manipulable statistics, among other things, allow DBAs to address the efficiency of PostgreSQL directly, as well as enable “extensions” to improve the user experience.</p>
<p>That said, the historic statistics system of PostgreSQL has not been without points of friction. These include limited ability to clear (relations) statistics, metrics with units that don’t always align with user goals, and no C API for using the PostgreSQL Cumulative Stats engine. PostgreSQL 18 addresses these concerns head on.</p>
<p>Below is a summary of the key enhancements.</p>
<h2 id="a-warning-on-stats"><a class="heading-anchor" href="#a-warning-on-stats">A warning on stats</a></h2>
<p>While statistics offer incredible value, their collection can take up significant time and resources. PostgreSQL 18 introduces an important consideration: with the expanded range of collectible metrics, the hash table maximum size has been increased. Do keep in mind, especially if you’re designing large-scale systems with table-per-customer architectures, that 1GB ceilings have been shown to be hit with some millions of tables.</p>
<h2 id="whats-new-with-postgresql-18-and-stats"><a class="heading-anchor" href="#whats-new-with-postgresql-18-and-stats">What’s new with PostgreSQL 18 and “stats”</a></h2>
<p>Here are the major new or improved features relating to statistics and monitoring. Each item links to the relevant documentation or code where possible.</p>
<p>Generally, <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-IO-VIEW" rel="noopener">pg_stat_io</a> now reports I/O activity in bytes rather than pages, which is more convenient for analysis. Moreover, WAL statistics were moved here from <code>pg_stat_wal</code>, providing a single, comprehensive view.</p>
<h3 id="upgrades"><a class="heading-anchor" href="#upgrades">Upgrades</a></h3>
<p><a href="https://www.postgresql.org/docs/18/pgupgrade.html" rel="noopener">pg_upgrade</a> is now able to retain optimizer statistics, removing the need to run a full <code>ANALYZE</code> on the databases to get good planning of queries after the upgrade; this is a very welcome update for large databases! Be aware that custom statistics added by an extension along with those created with <a href="https://www.postgresql.org/docs/18/sql-createstatistics.html" rel="noopener">CREATE STATISTICS</a> won’t be retained.</p>
<p>You will surely want to look at new options in <a href="https://www.postgresql.org/docs/18/app-vacuumdb.html" rel="noopener">vacuumdb</a> (<code>--missing-stats-only</code>) to, well, analyze only what’s needed.</p>
<p>On a similar note, the <code>--[no-]statistics</code> flag has been added to <a href="https://www.postgresql.org/docs/18/app-pgdump.html" rel="noopener">pg_dump</a>, <a href="https://www.postgresql.org/docs/18/app-pgdumpall.html" rel="noopener">pg_dumpall</a>, and <a href="https://www.postgresql.org/docs/18/app-pgrestore.html" rel="noopener">pg_restore</a>.</p>
<h3 id="maintenance"><a class="heading-anchor" href="#maintenance">Maintenance</a></h3>
<p>It’s now easier to know the maintenance effort on objects with total time spent on VACUUM and ANALYZE operation (and automatic ones) now reported into <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW" rel="noopener">pg_stat_all_tables</a> and variants.</p>
<p>A new GUC to not forget is <a href="https://www.postgresql.org/docs/18/runtime-config-statistics.html#GUC-TRACK-COST-DELAY-TIMING" rel="noopener">track_cost_delay_timing</a>. It collects time spent sleeping (due to delayed operations) for <code>VACUUM</code> and <code>ANALYZE</code>. While very interesting, like other <code>track_io*</code> GUCs, it implies a lot of extra calls to the system clock which on some platforms can lead to a severe performance impact. Always check with tool like <a href="https://www.postgresql.org/docs/18/pgtesttiming.html" rel="noopener">pg_test_timing</a> to ensure your system can afford it!</p>
<p>No more questions about checkpointer activity when using <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-CHECKPOINTER-VIEW" rel="noopener">pg_stat_checkpointer</a>. The new attribute <code>num_done</code> lets us know the number of <strong>completed</strong> checkpoints. You can also get what kind of buffers were written with <code>slru_written</code> and <code>buffers_written</code> now only matching <code>shared_buffers</code>: previously log and view were not providing the same counts because there was a SLRU counter <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=17cc5f666" rel="noopener">in one case and not the other</a>.</p>
<h3 id="analysis"><a class="heading-anchor" href="#analysis">Analysis</a></h3>
<p>Want to know more about the I/O handled by the backend (PID)? Call <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#PG-STAT-GET-BACKEND-IO" rel="noopener">pg_stat_get_backend_io(int)</a> and you’ll get output similar to what the <code>pg_stat_io</code> view provides, for this process (excluding those already). As for the WAL stats for this PID: call <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#PG-STAT-GET-BACKEND-WAL" rel="noopener">pg_stat_get_backend_wal(int)</a>.</p>
<p>New attributes <code>parallel_workers_to_launch</code> and <code>parallel_workers_launched</code> were introduced in <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" rel="noopener">pg_stat_database</a>. The ratio lets us know if we have enough slots for parallel workers.</p>
<p>Interesting changes on <a href="https://www.postgresql.org/docs/18/pgstatstatements.html" rel="noopener">pg_stat_statements</a>: more queries will be grouped under the same identifier. For example, patterns <code>IN (1,2,3, ...)</code> as only first and last constant will be used. A more counter-intuitive change is related to the table name used in a query. Only the name is used, not the schema or relation OID. This last change allows us to track dropped or recreated tables for example, but it will group statistics from unrelated tables if they have just the same name. The way to keep separate statistics for tables with same name is to alias them in the queries (<code>FROM my.table mt, other.table ot</code>)…</p>
<p>Finally, additions to <a href="https://www.postgresql.org/docs/18/view-pg-backend-memory-contexts.html" rel="noopener">pg_backend_memory_contexts</a> with <code>path</code> (to get parent/child) and <code>type</code> to segregate <code>AllocSet</code>, <code>Generation</code>, <code>Slab</code> and <code>Bump</code> contexts… and what exactly are <code>Slab</code> and <code>Bump</code>? They are not documented; for these you’ll want to <a href="https://github.com/postgres/postgres/tree/master/src/backend/utils/mmgr" rel="noopener">read headers of C files here</a>. They exist to optimize memory allocation, reallocation, and reset, depending on expected memory usage. For example, <code>Slab</code> is defined as a «MemoryContext implementation designed for cases where large numbers of equally-sized objects can be allocated and freed efficiently with minimal memory wastage and fragmentation».</p>
<p>Ah, no, a last one, <code>wal_buffers_full</code> was added to <code>pg_stat_statements</code> to allow us to tune for <code>wal_buffers</code> with better insights.</p>
<h3 id="replication"><a class="heading-anchor" href="#replication">Replication</a></h3>
<p>There are now better insights for conflict management when using logical replication that leverage new attributes in <a href="https://www.postgresql.org/docs/18/monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS" rel="noopener">pg_stat_subscription_stats</a>. As reference, this excerpt from <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=6c2b5edec" rel="noopener">the commit entry</a> lists the following attributes that were introduced:</p>
<ul class="list">
<li>
<p><code>confl_insert_exists</code>:<br>
Number of times a row insertion violated a NOT DEFERRABLE unique<br>
constraint.</p>
</li>
<li>
<p><code>confl_update_origin_differs</code>:<br>
Number of times an update was performed on a row that was<br>
previously modified by another origin.</p>
</li>
<li>
<p><code>confl_update_exists</code>:<br>
Number of times that the updated value of a row violates a<br>
NOT DEFERRABLE unique constraint.</p>
</li>
<li>
<p><code>confl_update_missing</code>:<br>
Number of times that the tuple to be updated is missing.</p>
</li>
<li>
<p><code>confl_delete_origin_differs</code>:<br>
Number of times a delete was performed on a row that was<br>
previously modified by another origin.</p>
</li>
<li>
<p><code>confl_delete_missing</code>:<br>
Number of times that the tuple to be deleted is missing.</p>
</li>
</ul>
<h3 id="advanced"><a class="heading-anchor" href="#advanced">Advanced</a></h3>
<p>There is now a <a href="https://www.postgresql.org/docs/18/functions-admin.html#FUNCTIONS-ADMIN-STATSMOD" rel="noopener">new set of functions</a> to manage relation and attributes stats (<code>relpages</code>, <code>avg_width</code>, and so on). This gives you the freedom to export, import, and adjust stats as you want, so you can replicate planner behavior outside of “production”, maintain patched stats, and so on.</p>
<h3 id="my-favorite-for-extension-authors-the-new-c-stats-api"><a class="heading-anchor" href="#my-favorite-for-extension-authors-the-new-c-stats-api">My favorite for extension authors: the new C stats API</a></h3>
<p>One of the most exciting parts is what PostgreSQL 18 <em>opens up</em> for extension authors.</p>
<p>This tiny line at bottom of section <a href="https://www.postgresql.org/docs/18/release-18.html#RELEASE-18-MODULES" rel="noopener">E.1.3.9 Modules</a> is what concerns these changes:</p>
<blockquote>
<p>Allow extensions to use the server’s cumulative statistics API (Michael Paquier)</p>
</blockquote>
<p>Previously statistics manipulation was an internal-only affair; now there is an official, structured API surface you can build on (or wrap).</p>
<p>The <a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=7949d9594" rel="noopener">commit message</a> is well written, and covers most of the new functionality. A subset of the options is <a href="https://www.postgresql.org/docs/18/xfunc-c.html#XFUNC-ADDIN-CUSTOM-CUMULATIVE-STATISTICS" rel="noopener">detailed in the documentation</a>. However, you will need to go into source code to know more at this stage; in particular, it’s worth having a look at the <code>injection points</code> extension (provided in core) which uses the new API.</p>
<p>For a deeper dive into how an extension can leverage these new capabilities, soon you will be able to see <strong>PACS (PostgreSQL Advanced Cumulative Statistics)</strong> on Codeberg - my project that provides a wrapper library and helper utilities around the new PostgreSQL 18 statistics APIs.</p>
<p>In the meantime, the talk I gave at <a href="https://archive.fosdem.org/2025/schedule/event/fosdem-2025-4496-stats-roll-baby-stats-roll-/" rel="noopener">FOSDEM 2025</a> explores these topics in greater detail.</p>
 ]]></content>
			<author>
				<name>Cédric Villemain</name>
			</author>
    </entry>
    <entry>
      <title>Most Desired Database Three Years Running: PostgreSQL's Developer Appeal</title>
      <link href="https://www.data-bene.io/en/blog/most-desired-database-three-years-running-postgresqls-developer-appeal/" />
      <updated>2025-08-09T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/most-desired-database-three-years-running-postgresqls-developer-appeal/</id>
     <content type="html"><![CDATA[ <p>PostgreSQL is having more than just a moment—it’s establishing a clear pattern of sustained excellence. For the third consecutive year, this community-driven database has claimed the top spot in the 2025 results for <a href="https://survey.stackoverflow.co/2025/" rel="noopener">Stack Overflow’s Annual Developer Survey</a>, and the results reveal both what developers value today and where the database landscape is heading.</p>
<p>The survey results show that PostgreSQL is ranked the highest among all database technologies for developers that want to use it in the next year (47%) or have used it this year and want to continue using it next year (66%) for the third year in a row.</p>
<h2 id="the-numbers-tell-a-compelling-story"><a class="heading-anchor" href="#the-numbers-tell-a-compelling-story"><strong>The Numbers Tell a Compelling Story</strong></a></h2>
<p>The survey data from over 49,000 developers across 177 countries provides clear evidence of PostgreSQL’s sustained appeal. Since 2023, PostgreSQL has consistently ranked as both the most desired and most admired database technology among developers.</p>
<p>Looking at the specific metrics from the survey visualizations, PostgreSQL leads with 46.5% of developers wanting to work with it in the coming year, while an impressive 65.5% of those who have used it want to continue doing so. These aren’t just impressive numbers—they represent a consistency that’s rare in the rapidly changing technology landscape.</p>
<p>The survey data also reveals an interesting pattern among developers currently using other database technologies. Developers working with MongoDB and Redis show a particularly strong desire to add PostgreSQL to their toolkit next year, seeing the value in adding relational database skills to their repertoire.</p>
<h2 id="the-community-advantage-in-action"><a class="heading-anchor" href="#the-community-advantage-in-action"><strong>The Community Advantage in Action</strong></a></h2>
<p>Why has PostgreSQL achieved this level of sustained success? The answer lies in its community-driven development model. As an open source project, PostgreSQL benefits from collaborative development that is both transparent and responsive to real-world needs.</p>
<p>The PostgreSQL project represents the best of what community-driven development can achieve. With over 400 code contributors across more than 140 supporting companies, the project boasts over 55,000 commits and more than 1.6 million lines of carefully crafted code. This diverse, globally distributed approach to development results in more thorough testing, faster bug fixes, and more innovative features than traditional commercial development models typically achieve.</p>
<p>Major versions are released annually with approximately 180 features per release, complemented by quarterly minor releases that include numerous improvements and fixes. This steady cadence of innovation consistently contributed by individuals all over the world ensures PostgreSQL doesn’t just keep pace with developer needs—it anticipates them. More than that, every individual has the agency to contribute to the project to ensure that anywhere the software is lagging behind, functionality changes to address modern demands.</p>
<h2 id="more-than-just-a-relational-database"><a class="heading-anchor" href="#more-than-just-a-relational-database"><strong>More Than Just a Relational Database</strong></a></h2>
<p>One key factor in PostgreSQL’s broad appeal is that it’s not limited to being just a relational database system. PostgreSQL is object-relational by design, capable of handling diverse data types including JSON/JSONB, XML, Key-Value, geometric, geospatial, native UUID, and time-series data. This versatility explains why developers from NoSQL backgrounds find PostgreSQL attractive—it offers relational reliability while maintaining the flexibility they’re accustomed to.</p>
<p>The extensive support for different data types, combined with ACID (Atomicity, Consistency, Isolation, Durability) characteristics, enables optimized, performant, and reliable data handling regardless of the specific requirements in place. Additionally, PostgreSQL’s huge community-driven extension network builds on its native extensibility, providing solutions for geospatial handling, disaster recovery, high availability infrastructure, monitoring, auditing, and much more.</p>
<h2 id="the-broader-database-landscape"><a class="heading-anchor" href="#the-broader-database-landscape"><strong>The Broader Database Landscape</strong></a></h2>
<p>While PostgreSQL dominates the top positions, the survey reveals a healthy, competitive database ecosystem. The complete rankings show:</p>
<p><strong>Most Desired Databases:</strong></p>
<ul class="list">
<li>PostgreSQL: 46.5%</li>
<li>SQLite: 28.3%</li>
<li>Redis: 23.5%</li>
<li>MySQL: 20.5%</li>
<li>MongoDB: 17.6%</li>
</ul>
<p><strong>Most Admired Databases:</strong></p>
<ul class="list">
<li>PostgreSQL: 65.5%</li>
<li>SQLite: 59%</li>
<li>Redis: 54.9%</li>
<li>MongoDB: 45.7%</li>
<li>MySQL: 43.2%</li>
</ul>
<p>These numbers reflect a diverse ecosystem where different databases serve specific purposes. SQLite’s strong performance highlights the continued importance of lightweight, embedded solutions. Redis maintains its position as a highly regarded specialized database for caching and real-time applications. Traditional databases like MySQL and Microsoft SQL Server continue to hold significant positions, while newer technologies like DuckDB show impressive admiration scores despite lower usage rates.</p>
<h2 id="the-foundation-of-postgresqls-enduring-success"><a class="heading-anchor" href="#the-foundation-of-postgresqls-enduring-success"><strong>The Foundation of PostgreSQL’s Enduring Success</strong></a></h2>
<p>Three consecutive years at the top of developer preferences doesn’t happen by accident. PostgreSQL’s sustained dominance stems from fundamental strengths that continue to serve developers well as technology landscapes shift. The resilience built into PostgreSQL through its community-driven development model means it adapts without losing stability. Its extensibility sets it apart in practical ways—rather than waiting for vendor roadmaps or worrying about feature gaps, developers can build what they need or leverage the extensive ecosystem of community extensions. The open source nature ensures PostgreSQL remains focused on developer needs rather than business models, with bug fixes happening quickly and features developing based on real-world use cases.</p>
<p>After 35 years of active development and three consecutive years as the most desired database technology, PostgreSQL has proven that community-driven open source development can deliver both immediate utility and long-term value. For developers and organizations looking at their database choices, PostgreSQL offers something increasingly rare: a technology that gets better over time without leaving its users behind.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Return of HOW2025</title>
      <link href="https://www.data-bene.io/en/blog/return-of-how2025/" />
      <updated>2025-07-15T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/return-of-how2025/</id>
     <content type="html"><![CDATA[ <p>The Highgo Open World conference, dedicated to the PostgreSQL ecosystem and the IvorySQL project, was held on June 27 and 28. The event was a resounding success: nearly 1,000 attendees on site, up to 8,000 simultaneous connections to the streams, and approximately 25,000 viewers in total.</p>
<p>The program featured 101 technical talks led by 105 speakers. The majority of sessions were in Mandarin, with an English track offered with simultaneous translation. You can view the full program at <a href="https://ivorysql.io/schedule/" rel="noopener">IvorySQL.io</a> and find the replays on Weibo via <a href="https://ivorysql.io/2025/06/27/live-access-june27/" rel="noopener">this link.</a></p>
<p>There was a small group of the international community present, including <a href="https://postgresql.life/post/grant_zhou/" rel="noopener">Grant Zhou</a>, who liaises and collaborates with the PostgreSQL association in China and the rest of the world.</p>
<p>On a technical level, the content was dense and particularly interesting. I particularly noted:</p>
<ul class="list">
<li>
<p>Alena Rybakina’s presentation on the PostgreSQL query planner and strategies for circumventing certain limitations.</p>
</li>
<li>
<p>A clear and concrete focus on Patroni (High Availability) by Alexander Kukushkin and Polina Bungina.</p>
</li>
<li>
<p>Florentz Tselai presented two topics applying his principles: simplicity and efficiency, using “AI” with PostgreSQL, and data management with Sun Tzu and the 36 Stratagems as support.</p>
</li>
<li>
<p>Also a very good introduction to Bazel and its use for Monogres (to be officially announced soon) presented energetically by Alvaro Hernandez.</p>
<p>Monogres is a very interesting initiative that should help strengthen control over the software supply chain, a major theme in IT today. And I also saw it as a great opportunity to showcase PostgreSQL variations with features and fixes that aren’t always possible to include in PostgreSQL itself or backport to previous major releases.</p>
</li>
<li>
<p>Michael Meskes had the honor of giving a plenary lecture on a topic that richly deserves it: “From Code to Commerce: Open Source Business Models Today,” a keynote on open-source and free software, applied to the PostgreSQL ecosystem.</p>
</li>
<li>
<p>My colleague Andrea presented the developments and trends of companies moving to IvorySQL and PostgreSQL.</p>
</li>
<li>
<p>For my part, I presented Linux PSI in the PostgreSQL context.</p>
</li>
</ul>
<p>Since everything is recorded, I encourage you to explore and watch the topics that interest you. There were also pre-recorded lectures in English during the event, but I admit that I took advantage of the time during the sessions to interact with participants.</p>
<p>Aside from the conferences, I had the chance to meet several members of the Chinese PostgreSQL community who are very well-known for their involvement in the success of PostgreSQL locally. I also had the opportunity to learn more about Cloudberry, replacing Greenplum, thanks Dianjin Wang!</p>
<hr>
<p>Data Bene also planned a time to meet with the IvorySQL team, based largely in Shandong, the province where Jinan, the host city of the conferences, is located. Ivory is a project in which we are actively involved and which allows companies to move away from Oracle “smoothly.” This is an important topic for our clients and one that occupies a prominent place in our partnership with Highgo: they have been working on this project for several years now, and we want to enable companies everywhere to benefit from it with appropriate support and expertise.</p>
<hr>
<p>The conferences were very well organized and the welcome was wonderful, the “Social Event” at the local “beer garden” perfectly suited to the heat of Jinan at the end of June!</p>
<p>Given the conference program, I bitterly regretted not understanding anything (there was 1 track in English and 5 in Mandarin)… but it is already being said that next year the Mandarin conferences could perhaps be translated (into English), and the date brought forward to May to take advantage of a milder climate.</p>
<p>There is so much to learn there that I will gladly return.</p>
 ]]></content>
			<author>
				<name>Cédric Villemain</name>
			</author>
    </entry>
    <entry>
      <title>A visit to PGConf.DE 2025 and discussion of PostgreSQL within the context of life sciences</title>
      <link href="https://www.data-bene.io/en/blog/a-visit-to-pgconfde-2025-and-discussion-of-postgresql-within-the-context-of-life-sciences/" />
      <updated>2025-06-06T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/a-visit-to-pgconfde-2025-and-discussion-of-postgresql-within-the-context-of-life-sciences/</id>
     <content type="html"><![CDATA[ <p>It’s always a pleasure to attend Postgres events, and <a href="http://PGConf.DE" rel="noopener">PGConf.DE</a> 2025 in Berlin was no different. This year’s event reunited old friendships and offered an open and welcoming environment to form new ones. And, of course, it also boasted numerous exciting talks!</p>
<p>At the conference I had the opportunity to present on Postgres within the context of the life sciences (discussed in the next section). And, altogether, I felt this conference had a nice diversity of talks: a selection that spanned Postgres core, its ecosystem, and beyond.</p>
<p>I’m confident that by the end, most if not all attendees left more enriched in some way relative to when they arrived.</p>
<h2 id="presentations"><a class="heading-anchor" href="#presentations">Presentations</a></h2>
<p>Leading up to this event I had the honor of one of my talks being accepted. The title was “<a href="https://www.postgresql.eu/events/pgconfde2025/schedule/session/6541-postgres-and-life-science-from-cells-to-stars/" rel="noopener">Postgres and Life Science: From Cells to Stars</a>” and it was organized as a meta-analysis / homage to the extensibility of Postgres and its various applications to the natural world.</p>
<p>In order to best tell this story, I walked the audience through the following five topics of increasing scope:</p>
<ul class="list">
<li>Neuronal mapping with a PostGIS-supported GUI
<ul class="list">
<li><a href="https://github.com/catmaid/CATMAID" rel="noopener">CATMAID source code</a></li>
</ul>
</li>
<li>Hydrological examination of rivers with the PgHydro extension
<ul class="list">
<li><a href="https://github.com/pghydro/pghydro" rel="noopener">PgHydro source code</a></li>
</ul>
</li>
<li>Fish biomass meta-analysis leveraging vanilla Postgres
<ul class="list">
<li><a href="https://www.nature.com/articles/s41597-024-04026-0" rel="noopener">Link to peer-reviewed publication</a></li>
</ul>
</li>
<li>COVID-19 dashboard using the Citus extension
<ul class="list">
<li><a href="https://www.citusdata.com/blog/2021/12/11/uk-covid-19-dashboard-built-using-postgres-and-citus/" rel="noopener">Link to blog post</a></li>
</ul>
</li>
<li>Star classification built on forked Postgres and altered extensions
<ul class="list">
<li><a href="https://indico.cern.ch/event/1471762/contributions/6280216/" rel="noopener">Link to presentation at Cern PGDay - 2025</a></li>
</ul>
</li>
</ul>
<p>I enjoyed putting together and presenting the talk, and there was nice discussion afterwards. Two points stood out in particular that I felt would be interesting to address here:</p>
<ol class="list">
<li>
<p>What three technologies (tools / workflows) would benefit most greatly, in terms of increased impact or adoptability, if their complexities were significantly reduced / abstracted away?</p>
</li>
<li>
<p>During my talk I made a claim that the brain was ACID compliant. While I was referring mostly to the action potentials of neurons, this was rightfully challenged.</p>
</li>
</ol>
<h3 id="1-identified-tools-/-workflows"><a class="heading-anchor" href="#1-identified-tools-/-workflows">1. Identified Tools / Workflows</a></h3>
<p><em>1. What three technologies (tools / workflows) would benefit most greatly, in terms of increased impact or adoptability, if their complexities were significantly reduced / abstracted away?</em></p>
<h4 id="1-image-vectorization"><a class="heading-anchor" href="#1-image-vectorization">1. Image vectorization</a></h4>
<p>Right out of the gate I thought about magnetic resonance scanner image classification. There’s quite a lot of conversation surrounding this topic within the medical community and there are plenty of startups in this space as well. My personal opinion is that there is momentum in the direction of accessibility, but there is still a strong separation between developer and end user. While I don’t know the answer at this point, I would look into <a href="https://github.com/pgvector/pgvector" rel="noopener">pgvector</a> and <a href="https://github.com/postgresml/postgresml" rel="noopener">postgresml</a> as a starting point. Due to this challenge’s involvement of vectors and machine learning, I would consider leveraging an image embedding service to turn the raw MRI output into a format that pgvector might be able to work with.</p>
<h4 id="2-data-management-and-version-control"><a class="heading-anchor" href="#2-data-management-and-version-control">2. Data management and version control</a></h4>
<p>As a former academic, I can speak to the ubiquitousness of the common spreadsheet (.csv format being less common, but still utilized). What’s more is that files are typically stored in local directories / private server / shared infrastructure, but nevertheless a vanilla folder architecture. One can imagine the potential frictions as the conversation scales to include multiple researchers across multiple groups. Factor in a naturally high student turnover, paired with an “I like doing it my way” mentality, and one could appreciate the value of standards. While improvements could be approached from a number of different angles, I’d like to focus on data management and version control.</p>
<p>Tidy data and good organizational hygiene are hallmarks of success in any field of study. However, tracking changes are most often, if not exclusively limited to text documents. While it might be surprising to the reader, “code repository” is not part of the common academic lexicon. Even the term “Linux” evokes an air of “mysterium tremendum et fascinans” (Otto, 1923). With data security at the top of the mind, self hosted options such as <a href="https://forgejo.org/" rel="noopener">forgejo</a> could potentially benefit life scientists greatly - particularly if there are reservations about storing data online. Instead of having multiple file drafts, e.g., “draft-1_final”, “draft_final_final”, etc, tools such as forgejo can help track progress and give researchers more transparency into past changes (leading into easier cross-team collaboration).</p>
<h4 id="3-compliance-and-auditing"><a class="heading-anchor" href="#3-compliance-and-auditing">3. Compliance and auditing</a></h4>
<p>Trust is a central topic in any field of research, and in certain circumstances, auditing (or otherwise some form of proof of work) may take center stage. In this case, Postgres and one of its companion extensions, <a href="https://github.com/pgaudit/pgaudit" rel="noopener">pgaudit</a>, can offer a nice step towards compliance. Due to Postgres’ capabilities, it can sometimes be viewed as intimidating and only suitable for large projects. I think there could be a lot of ubiquity with the publication of a “Postgres for small scale projects” type guide.</p>
<h4 id="discovery-and-exposure"><a class="heading-anchor" href="#discovery-and-exposure">Discovery and exposure</a></h4>
<p>At the end of the day, no one will willingly use something unless they know it exists. That’s why discoverability is one of the most fundamental concepts when discussing impact and adoptability. It’s up to the maintainers, contributors, and communities behind these open source tools to share what they’re up to on multiple platforms, as well as different conferences. Honestly, the easiest way to help is to just talk about it and get hands-on.</p>
<h3 id="2-the-brain-and-acid-compliance"><a class="heading-anchor" href="#2-the-brain-and-acid-compliance">2. The Brain and ACID Compliance</a></h3>
<p><em>2. During my talk I made a claim that the brain was ACID compliant. While I was referring mostly to the action potentials of neurons, this was rightfully challenged.</em></p>
<p>This was another exciting conversation in the post-presentation discussion, and while this really warrants its own blog post, I wanted to quickly share my thoughts. Within one of my slides, I made the claim that the brain is ACID compliant, at least in the sense of transactions being all-or-nothing. Neurons, which are a common cell type in the brain, have a characteristic whereby they receive signals which compile until a threshold is reached and then the neuron sends a signal of its own, or “fires.” This is a gross oversimplification: here’s a quick <a href="https://en.wikipedia.org/wiki/Action_potential" rel="noopener">Wikipedia link</a> for more information.</p>
<p>However, astute audience members righty noted that the brain is complex and has different regions. There is memory loss and there are activities that can alter function and consciousness. However, to what extent do external influences on the brain correspond to a database system? If something corrupts a Postgres database, it is no longer ACID compliant, but it was beforehand. All these points are both valid and interesting. It will be interesting to think on this and write a more formal response.</p>
<h2 id="concluding-thoughts"><a class="heading-anchor" href="#concluding-thoughts">Concluding Thoughts</a></h2>
<p>To sum things up, this was great conference. I know I speak for all attendees when I extend a thank you to all involved, whether they be staff, volunteers, speakers, or otherwise.</p>
<h2 id="references"><a class="heading-anchor" href="#references">References</a></h2>
<p>Foote, K. J., Grant, J. W. A., &amp; Biron, P. M. (2024). A global dataset of salmonid biomass in streams. Scientific data, 11(1), 1172. <a href="https://doi.org/10.1038/s41597-024-04026-0" rel="noopener">https://doi.org/10.1038/s41597-024-04026-0</a></p>
<p>Giordano, C., &amp; Hadjibagheri, P. (2021, December 11). UK COVID-19 dashboard built using Postgres and Citus for millions of users. Microsoft TechCommunity Blog. <a href="https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/uk-covid-19-dashboard-built-using-postgres-and-citus-for/ba-p/3039052" rel="noopener">https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/uk-covid-19-dashboard-built-using-postgres-and-citus-for/ba-p/3039052</a></p>
<p>Kazimiers, T., et al. (2021). CATMAID (Collaborative Annotation Toolkit for Massive Amounts of Image Data) [Computer software]. GitHub. <a href="https://github.com/catmaid/CATMAID" rel="noopener">https://github.com/catmaid/CATMAID</a></p>
<p>Krefl, D., &amp; Nienartowicz, K. (2025, January 17). Harnessing Postgres and HPC for petabyte-scale variable star classification in astronomy [Conference presentation]. CERN PGDay 2025, Geneva, Switzerland. <a href="https://indico.cern.ch/event/1336647/contributions/5660229/" rel="noopener">https://indico.cern.ch/event/1336647/contributions/5660229/</a></p>
<p>Otto, R. (1923). The idea of the holy: An inquiry into the non-rational factor in the idea of the divine and its relation to the rational (J. W. Harvey, Trans.). Oxford University Press. (Original work published 1917)</p>
<p>Teixeira, A. de A., &amp; PgHydro Project. (2022). pghydro (Version 6.6) [Computer software]. GitHub. <a href="https://github.com/pghydro/pghydro" rel="noopener">https://github.com/pghydro/pghydro</a></p>
<p>Wikipedia contributors. (2025, May 16). Action potential. Wikipedia, The Free Encyclopedia. <a href="https://en.wikipedia.org/wiki/Action_potential" rel="noopener">https://en.wikipedia.org/wiki/Action_potential</a></p>
 ]]></content>
			<author>
				<name>Evan Stanton</name>
			</author>
    </entry>
    <entry>
      <title>SCaLE 22x: Bringing the Open Source Community to Pasadena</title>
      <link href="https://www.data-bene.io/en/blog/scale-22x-bringing-the-open-source-community-to-pasadena/" />
      <updated>2025-06-02T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/scale-22x-bringing-the-open-source-community-to-pasadena/</id>
     <content type="html"><![CDATA[ <p>The Southern California Linux Expo (SCaLE) 22x, recognized as being North America’s largest community-run open source and free software conference, took place at the Pasadena Convention Center from March 6-9, 2025. <em>When I say community-run, I mean it—no corporate overlords dictating the agenda, just pure open source enthusiasm driving four days of technical discussions and collaboration.</em></p>
<p>This year’s conference focused around the topics of AI, DevOps and cloud-native technologies, open source community engagement, security and compliance, systems and infrastructure, and FOSS @ home (exploring the world of self-hosted applications and cloud services).</p>
<p>The conference drew attendees from around the world to talk about everything open-source, revolving around Linux at the core (of course) while continuing the discussion across topics such as embedded systems &amp; IoT. As always, there was a unique blend of cutting-edge tech talk and practical problem-solving within every space that is what makes SCaLE special.</p>
<h2 id="herding-elephants-postgresql@scale22x"><a class="heading-anchor" href="#herding-elephants-postgresql@scale22x"><strong>Herding Elephants: PostgreSQL@SCaLE22x</strong></a></h2>
<p>PostgreSQL@SCaLE22x ran as a dedicated two-day, two-track event on March 6-7, 2025, recognized under the PostgreSQL Global Development Group community event guidelines. The selection team included Gabrielle Roth, Joe Conway, and Mark Wong, ensuring the quality you’d expect from the PostgreSQL community.</p>
<p>The speaker lineup was impressive: Magnus Hagander, Christophe Pettus, Peter Farkas, Devrim Gündüz, Hamid Akhtar, Henrietta Dombrovskaya, Shaun Thomas, Gülçin Yıldırım Jelínek &amp; Andrew Farries, Nick Meyer, and Jimmy Angelakos. One particularly memorable session was titled “Row-Level Security Sucks. Can We Make It Usable?”—a refreshingly honest take on PostgreSQL’s RLS feature that probably resonated with more than a few database administrators in the audience.</p>
<p>The community “Ask Me Anything” panel was hosted by Stacey Haysler and featured Christophe Pettus, Devrim Gündüz, Jimmy Angelakos, Magnus Hagander, and Mark Wong. These sessions are where the real knowledge transfer happens—no marketing speak, just practitioners talking shop about PostgreSQL internals, performance, best practices, and the future of the database.</p>
<p>Behind the scenes, volunteers Derya Gumustel, Erika Miller, Hamid Akhtar, Jennifer Scheuerell, Mark Wong, and Roberto Mello kept everything running smoothly, with PGUS hosting the booth in the expo hall.</p>
<p>Personally, I had the pleasure of collaborating with Jimmy Angelakos during his <a href="https://vyruss.org/blog/scale-22x-live-streams-row-level-security-sucks.html" rel="noopener">live streaming sessions</a> featuring other guests like Henrietta Dombrovskaya, Mark Wong, Gülçin Yıldırım Jelínek, and even a brief cameo from Devrim Gündüz.</p>
<p><em>One of the topics discussed with Gülçin Yıldırım Jelínek on the podcast is whether or not there’s any community interest in continuing <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Postgres Café</a>. What do you think? Do you want to see more episodes from this podcast series, expanding discussions on extension and open source development to the rest of the community and beyond? Let us know: <a href="mailto:contact@data-bene.io">contact@data-bene.io</a></em></p>
<h2 id="something-for-everyone"><a class="heading-anchor" href="#something-for-everyone"><strong>Something for Everyone</strong></a></h2>
<p>There are a lot of co-located events besides PostgreSQL @ SCaLE, including “SCaLE: The Next Generation (TNG)” which is a youth-focused tech event encouraging interactive activities and presentations for students, and the annual Cybersecurity Capture the Flag (CTF) game event presented by Cal Poly FAST and Pacific Hackers.</p>
<p>SCaLE remains an excellent place to network when looking to advance your career in open source. Socializing at the booths is always an excellent way to make connections and find opportunities, of course, but Open Source Career Day also returned in order to offer a dedicated space for professionals and aspiring technologists to become empowered with resources, tools, real-world examples, and engaging content from presentations and workshops.</p>
<p>The fun tradition of holding a Saturday Game Night with food &amp; drinks also continued this year, with Trivia Night (presented by Uncoded) and other fun activities such as inflatable axe throwing, nerf target practice, arts &amp; crafts, a board game room, casino night, &amp; a blocks room for building derby cars, playing pictionary, or building with large blocks.</p>
<h2 id="keep-your-calendar-open-for-scale-23x"><a class="heading-anchor" href="#keep-your-calendar-open-for-scale-23x"><strong>Keep Your Calendar Open for SCaLE 23x</strong></a></h2>
<p>SCaLE has established itself as a consistent presence in Pasadena, and this stability has allowed the conference to build lasting relationships with the local community and venues. Keep an eye out for SCaLE 23x announcements - it promises to be well worth the visit.</p>
<p>For those interested in PostgreSQL@SCaLE specifically, stay tuned to the PostgreSQL mailing lists for announcements about volunteering, speaking opportunities, or other ways to participate in next year’s event. The PostgreSQL track and booth is a consistent source of engaging discussions amongst those in the Postgres community and beyond, reflecting the database’s growing adoption across industries.</p>
<h2 id="the-open-source-gathering-for-one-and-all"><a class="heading-anchor" href="#the-open-source-gathering-for-one-and-all"><strong>The Open Source Gathering for One and All</strong></a></h2>
<p>In a world where many tech conferences feel more like elaborate vendor showcases, SCaLE remains that rare gathering where community comes first, collaboration is genuine, and the technology discussions are driven by practitioners solving real problems. Mark your calendars for SCaLE 23x—this is one conference that consistently delivers on its promise of bringing together open source enthusiasts to actually collaborate and learn.</p>
<p>Wish you hadn’t missed out? You can always check out the <a href="https://www.youtube.com/playlist?list=PLh1QjGnfC2eREVHe8shz8Db7jGJvZerCK" rel="noopener">YouTube playlist of talks</a> that were recorded during the conference to at least benefit from the knowledge contained therein.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Once Upon a Time in a Confined Database - PostgreSQL, QRCodes, and the Art of Backup Without a Network</title>
      <link href="https://www.data-bene.io/en/blog/backup-without-a-network/" />
      <updated>2025-04-01T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/backup-without-a-network/</id>
     <content type="html"><![CDATA[ <h2 id="📦-the-fort-knox-of-databases"><a class="heading-anchor" href="#📦-the-fort-knox-of-databases">📦 The Fort Knox of Databases</a></h2>
<p>Once upon a time, in a faraway server room encased in heavy glass and reinforced concrete, lived a PostgreSQL database so confined, so secluded, it could only dream of the cloud.</p>
<p>No network.</p>
<p>No USB.</p>
<p>No writable external storage device.</p>
<p>Just a keyboard, a monitor, and the hum of industrial-grade air filters.</p>
<p>This wasn’t your average air-gapped setup. This was a zero-exfiltration zone, with operational security so tight you’d think it was guarding state secrets—or worse, legacy banking software.</p>
<p>And yet, in this digital oubliette, one innocent challenge remained:<br>
<strong>How do you back up a PostgreSQL database without ever extracting a file?</strong></p>
<hr>
<h2 id="🎥-when-screens-are-your-network"><a class="heading-anchor" href="#🎥-when-screens-are-your-network">🎥 When Screens Are Your Network</a></h2>
<p>Our customer didn’t just want backups—they <em>needed</em> them. The fear wasn’t theft, it was <strong>total failure</strong>: a motherboard dying quietly in its glass sarcophagus, taking the data with it. And if it came to that, chiseling through reinforced architecture wasn’t a viable disaster recovery plan.</p>
<p>We brainstormed everything:</p>
<ul class="list">
<li>OCR of scrolling SQL dumps? Too lossy.</li>
<li>Filming the <code>psql</code> output? Way too verbose.</li>
<li>Printing out hex? Please, we’re not monsters.</li>
</ul>
<p>And then came the epiphany: <strong>QR codes</strong>.</p>
<p>What if we could <code>pg_dump</code> the database…</p>
<p>into QR codes…</p>
<p>on the screen…</p>
<p>captured by a high-speed camera…</p>
<p>then reassembled frame by frame outside the vault?</p>
<p>It was so absurd, it just might work.</p>
<hr>
<h2 id="🧠-hacking-pg_dump-now-with-more-pixels"><a class="heading-anchor" href="#🧠-hacking-pg_dump-now-with-more-pixels">🧠 Hacking <code>pg_dump</code>: Now with More Pixels</a></h2>
<p>PostgreSQL’s beloved <code>pg_dump</code> tool is modular. So we extended it with a custom archiver: <code>--format=qrcode</code>.</p>
<p>Here’s how it works:</p>
<ol class="list">
<li>
<p><strong>QR encoding</strong>: Each chunk of SQL output is encoded into a PNG QR code.</p>
</li>
<li>
<p><strong>Streaming</strong>: Instead of saving to disk, we push the stream of PNGs directly to <code>stdout</code>.</p>
</li>
<li>
<p><strong>Framing</strong>: Our UI lays out multiple QR codes on a single screen using high-DPI output. (We’re talking 2000+ pixels here—room for a whole grid of codes.)</p>
</li>
<li>
<p><strong>Playback</strong>: A dedicated machine with a 1280Hz high-speed camera films the screen, capturing the sequence as a video.</p>
</li>
</ol>
<p>No keyboard macros. No sneaky uploads. Just photons and frames.</p>
<hr>
<h2 id="🔍-reassembly-outside-the-glass"><a class="heading-anchor" href="#🔍-reassembly-outside-the-glass">🔍 Reassembly Outside the Glass</a></h2>
<p>Once the video is extracted from the glass box:</p>
<ul class="list">
<li>
<p>Our parser watches the footage, frame by frame.</p>
</li>
<li>
<p>QR codes are detected and decoded in parallel.</p>
</li>
<li>
<p>Each chunk is sequence-tagged for ordering.</p>
</li>
<li>
<p>The resulting text is reassembled into a proper <code>pg_dump.sql</code>.</p>
</li>
</ul>
<p>And just like that: the database lives again—<strong>fully exported with no digital transfer</strong>.<br>
Only light and lenses.</p>
<hr>
<h2 id="🧩-notes-on-performance-and-fidelity"><a class="heading-anchor" href="#🧩-notes-on-performance-and-fidelity">🧩 Notes on Performance &amp; Fidelity</a></h2>
<ul class="list">
<li>
<p><strong>QR Version</strong>: We used Version 40 QR codes (max capacity) with optimized binary mode for high density.</p>
</li>
<li>
<p><strong>Error Correction</strong>: Level Q for resilience under compression/artifacts.</p>
</li>
<li>
<p><strong>Screen Real Estate</strong>: 25×16 grid of codes per frame on a 1920×1080 pixel monitor—350 chunks per screen, around 1,016KB per frame.</p>
</li>
<li>
<p><strong>Playback Rate</strong>: We achieved ~60 screens/sec = 21,000 chunks/sec, nearly 60MB/sec!.</p>
</li>
<li>
<p><strong>Total Export Time</strong>: A full logical backup under 6GB was exported in less than 100 minutes!</p>
</li>
</ul>
<hr>
<h2 id="🛡️-why-this-matters"><a class="heading-anchor" href="#🛡️-why-this-matters">🛡️ Why This Matters</a></h2>
<p>This isn’t just a quirky story—it’s a reminder that <strong>PostgreSQL’s flexibility extends even into the absurd</strong>. Air-gapped systems aren’t rare in defense, finance, or critical infrastructure. And when normal tooling fails, PostgreSQL’s pluggable architecture gives you room to innovate, even in the tightest constraints.</p>
<p>We at <strong>Data Bene</strong> live for this kind of challenge. Whether it’s optimizing query plans or designing data exfiltration methods that look like spycraft, we’re here to help you make PostgreSQL dance—even when it’s stuck in a cage.</p>
<hr>
<p><em>Want to try it yourself? Drop us a line—we love weird backups.</em></p>
<p><em>And if you’re thinking of streaming <code>pg_restore</code> into a laser light show, call us. We’re intrigued.</em></p>
 ]]></content>
			<author>
				<name>Cédric Villemain</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café: Contributing to Open Source</title>
      <link href="https://www.data-bene.io/en/blog/postgres-cafe-contributing-to-open-source/" />
      <updated>2025-03-04T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/postgres-cafe-contributing-to-open-source/</id>
     <content type="html"><![CDATA[ <p>It’s our sixth episode of <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Postgres Café</a>, a collaborative podcast from <a href="https://www.data-bene.io/en/" rel="noopener">Data Bene</a> &amp; <a href="https://xata.io/" rel="noopener">Xata</a> where we discuss everything from PostgreSQL extensions to community contributions. In today’s episode, Sarah Conway &amp; Gülçin Yıldırım Jelinek meet with Andrea Cucciniello on the topic of how companies and individuals can contribute to open source projects, and why they might consider doing so.</p>
<h2 id="episode-6-postgresql-extension-development-the-community-and-beyond"><a class="heading-anchor" href="#episode-6-postgresql-extension-development-the-community-and-beyond">Episode 6: PostgreSQL Extension Development, The Community, &amp; Beyond</a></h2>
<p>How often do companies express interest in open-source contribution? Clearly, by helping out in any way, the open-source project itself sees a benefit. But are there any advantages for the company that is giving back in any way? What are some contribution methods that a company can consider? These are all questions we hear about constantly—so let’s explore some of the answers discussed in this episode in a quick recap.</p>
<h3 id="giving-back-to-open-source-projects-and-communities"><a class="heading-anchor" href="#giving-back-to-open-source-projects-and-communities">Giving back to open source projects &amp; communities</a></h3>
<p>At Data Bene, we have a few customers that are interested in developing features or enhancements for the PostgreSQL ecosystem already.</p>
<p>These companies are interested in addressing bugs and adding new features that complement their use cases and tech stacks across PostgreSQL, Citus Data, and related technologies to accomplish two things:</p>
<ol class="list">
<li>To build functionality they need that is natively built into the upstream software and transparently maintained by the greater open-source community, and</li>
<li>To ensure others who have a similar use case are able to leverage these benefits as well.</li>
</ol>
<p>Times change; the only way the upstream software will remain relevant, useful, and beneficial to the global audience using the product is if there are global contributions back to the same, ensuring it still meets real users needs from year to year.</p>
<h3 id="why-support-open-source-projects"><a class="heading-anchor" href="#why-support-open-source-projects">Why support open-source projects?</a></h3>
<p>Vendor lock-in is a huge problem in the software &amp; services industry; giving back to open-source projects ensures that technology that is openly developed can continue to be so. Using FOSS technology means you avoid investing in a company that might close the code or restrict access, giving the end user freedom to continue using and developing essential tools that are part of their tech stack.</p>
<p>This kind of software is also subject to a highly visible development process, meaning it is much harder for privacy invasions, cybersecurity vulnerabilities, and more to be built into the underlying code.</p>
<p>Additionally, open-source software is built by individuals all over the world with a variety of perspectives and backgrounds; this ensures that it is thoroughly tested, with a wide range of features built-in that are <em>actually useful</em> to many end-users. This helps these kinds of projects to be successful for a number of years and continue to be so as long as there is a community willing to support each of them.</p>
<p><em>Case-in-point: PostgreSQL has been around for 35+ years of active development and is still topping developer surveys and charts today for being the most liked, most used, and most popular database solution—worldwide!</em></p>
<h3 id="how-can-companies-best-support-open-source-projects"><a class="heading-anchor" href="#how-can-companies-best-support-open-source-projects">How can companies best support open-source projects?</a></h3>
<p>There are a few key ways to achieve this end-goal:</p>
<ol class="list">
<li><strong>Include code contributions as part of your engineers’ working time.</strong> When allocating developer time for working on upstream code, you’re ensuring that the technology that you leverage (to provide support and/or services, to power your product, or for your infrastructure to depend on) experiences improved performance, expanded functionality, resolved issues, or addressed bug fixes.</li>
<li><strong>Consider developing extensions.</strong> Creating and maintaining extensions allow companies to add specialized features or address certain use cases without altering the core codebase. In the case of PostgreSQL in particular, this extensibility allows Postgres to meet the needs of different industries, users, and businesses, with a versatile and strong ecosystem. This kind of modular system lets PostgreSQL evolve without an overcomplicated core, making the project as a whole easier to manage and update.</li>
<li><strong>Sponsor, organize, and participate in events.</strong> As a company, you can elect to uplift or initiate technology conferences, user-groups, workshops, and more to spread awareness and educate the general public about the technology you want to see thrive. Events are an excellent way for users &amp; developers to collaborate, discuss advancements, and share best practices, which leads to a strengthened community and an enhanced product as a result.</li>
</ol>
<h3 id="how-data-bene-contributes"><a class="heading-anchor" href="#how-data-bene-contributes">How Data Bene contributes</a></h3>
<p>Cédric Villemain, Data Bene’s president, has developed <a href="https://codeberg.org/c2main/pgfincore" rel="noopener">pg_fincore</a> and is currently working on <a href="https://codeberg.org/data-bene/statsmgr" rel="noopener">StatsMgr</a>, pg_psi, and other components that are designed to improve Postgres’ statistics capabilities.</p>
<p>Our team is also responsible for a number of contributions across projects like <a href="https://www.citusdata.com/blog/2025/02/06/distribute-postgresql-17-with-citus-13/" rel="noopener">Citus Data</a> and <a href="https://github.com/zammad/zammad/" rel="noopener">Zammad</a>.</p>
<p>We make a point of sponsoring, presenting at, &amp; advocating for PostgreSQL or open-source community conferences and user groups, such as PostgreSQL Europe, pgDay Paris, AlpOSS, Capitole du Libre, &amp; more. Some of our team also individually have started or are on the organizational committees for various events such as the Barcelona &amp; Madrid PostgreSQL User Groups and pgDay Lowlands. The impact of events on the larger project &amp; community cannot be understated, and it is important to us to do all we can to contribute in this manner.</p>
<p>Finally, we help customers understand how to contribute to PostgreSQL and similar open-source projects. Through training, workshops, and collaboration, we encourage making meaningful contributions that fit their goals and support the greater community.</p>
<p><em>If you’re a developer who is interested in contributing to open-source and/or the PostgreSQL ecosystem, or helping customers with R&amp;D requirements, our team is expanding—visit us at our <a href="https://data-bene.io/en/jobs" rel="noopener">website</a> to see available positions!</em></p>
<h3 id="watch-the-full-episode"><a class="heading-anchor" href="#watch-the-full-episode">Watch the full episode</a></h3>
<p>Thinking about watching the full discussion? Check it out on YouTube:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/BYvXQB9O71U?si=-irKIHXxwiPhBFQP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="stay-tuned-for-more-postgres-tools"><a class="heading-anchor" href="#stay-tuned-for-more-postgres-tools">Stay tuned for more Postgres tools</a></h3>
<p>We’ve finished our first round of episodes for Postgres Café as of this release! More episodes may or may not be pending… follow us on social media (like <a href="https://www.linkedin.com/company/91744288" rel="noopener">LinkedIn</a> or <a href="https://fosstodon.org/@data_bene" rel="noopener">Mastodon</a>) to be updated on more to come. (Would you like to see more from this podcast series? Let us know!)</p>
<p><a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Subscribe to the playlist</a> or check it out for interviews about open-source extensions like <a href="https://codeberg.org/Data-Bene/StatsMgr" rel="noopener">StatsMgr</a> for efficient statistics management for PostgreSQL, an open-source change data capture (CDC) tool designed specifically for PostgreSQL called <a href="https://youtu.be/j1R3a0-jg6c" rel="noopener">pgstream</a>, &amp; more. PostgreSQL is one of the most extensible databases on the market with a huge extension ecosystem; learn directly from the experts as you discover some of the options out there.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café: Deploying distributed PostgreSQL at scale with Citus Data</title>
      <link href="https://www.data-bene.io/en/blog/postgres-cafe-deploying-distributed-postgresql-at-scale-with-citus-data/" />
      <updated>2025-01-29T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/postgres-cafe-deploying-distributed-postgresql-at-scale-with-citus-data/</id>
     <content type="html"><![CDATA[ <p>It’s time for the fourth episode of <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Postgres Café</a>, a podcast from our teams at <a href="https://www.data-bene.io/en/" rel="noopener">Data Bene</a> and <a href="https://xata.io/" rel="noopener">Xata</a> where we discuss PostgreSQL contribution and extension development. In this latest episode, Sarah Conway and Gülçin Yıldırım Jelinek meet with Stéphane Carton to cover <a href="https://github.com/citusdata/citus" rel="noopener">Citus Data</a>, a completely open-source extension from Microsoft that provides a solution for deploying distributed PostgreSQL at scale.</p>
<h2 id="episode-4-citus-data"><a class="heading-anchor" href="#episode-4-citus-data">Episode 4: Citus Data</a></h2>
<p>The Citus database has experienced 127 releases since Mar 24, 2016 when it was first made freely open-source for open use and contributions. It’s a powerful tool that works natively with PostgreSQL, and seamlessly integrates with all Postgres tools and extensions. Continue reading for a summary of what we covered in this podcast episode!</p>
<h3 id="addressing-scalability-performance-and-the-management-of-large-datasets"><a class="heading-anchor" href="#addressing-scalability-performance-and-the-management-of-large-datasets">Addressing scalability, performance, and the management of large datasets</a></h3>
<p>So why does Citus Data exist, and what problems does it solve? Let’s delve into this by category.</p>
<h4 id="development"><a class="heading-anchor" href="#development">Development</a></h4>
<p>Citus is designed to solve the distributed data modeling problem by providing methods in distributed data modeling to map workloads, such as sharding tables based on primary keys (especially useful for microservices and high-throughput workloads).</p>
<h4 id="scalability"><a class="heading-anchor" href="#scalability">Scalability</a></h4>
<p>By distributing data across multiple nodes, you’re able to enable the horizontal scaling of PostgreSQL databases.</p>
<p>This allows developers to combine CPU, memory, storage, and I/O capacity across multiple machines for handling large datasets and high traffic workloads. It’s simple to add more worker nodes to the cluster and rebalance the shards as your data volume grows.</p>
<h4 id="performance"><a class="heading-anchor" href="#performance">Performance</a></h4>
<p>The distributed query engine in Citus is used to maximize efficiency, parallelizing queries and batching execution across multiple worker nodes.</p>
<p>Even in cases where there are thousands to millions of statements being executed per second, data ingestion is still optimized through finding the right shard placements, connecting to the appropriate worker nodes, and performing operations in parallel. All of this ensures high throughput and low latency for real-time data absorption.</p>
<h4 id="high-availability-and-redundancy"><a class="heading-anchor" href="#high-availability-and-redundancy">High Availability &amp; Redundancy</a></h4>
<p>Through the distributed data model, you can create redundant copies of tables and shard data across multiple nodes. Through this process, you can ensure the database remains resilient and available even when nodes crash, and maintain high availability as a result.</p>
<h3 id="contributing-to-citus"><a class="heading-anchor" href="#contributing-to-citus">Contributing to Citus</a></h3>
<p>At Data Bene, our goal is to support forward momentum of upstream source code through ongoing development and code contributions. Cédric Villemain, among others on our team, constantly assesses for new feature additions or other improvements that can make a difference for users.</p>
<p>No matter whether you’re part of a DevOps team that is looking to build out distributed architecture for your PostgreSQL instances, or an end user such as a business analyst that is seeking efficient performance when handling vast amounts of data, Citus Data may be the perfect extension to support your use case.</p>
<p>If you have specific feature requests or concerns, our team here at Data Bene will help support you to contribute directly to Citus Data or can do so on your behalf to ensure the longevity of the project and relevance for your projects. Learn more about contributing to Citus Data by referencing the official <a href="https://github.com/citusdata/citus/blob/main/CONTRIBUTING.md" rel="noopener">CONTRIBUTING.md</a> file.</p>
<h3 id="watch-the-full-episode"><a class="heading-anchor" href="#watch-the-full-episode">Watch the full episode</a></h3>
<p>Thinking about watching the full discussion? Check it out on YouTube:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/WueRn76nJ9Q?si=ulvzvfcr4Ux17tt0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="stay-tuned-for-more-postgres-tools"><a class="heading-anchor" href="#stay-tuned-for-more-postgres-tools">Stay tuned for more Postgres tools</a></h3>
<p>More episodes are still being published for Postgres Café! <a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Subscribe to the playlist</a> for more interviews around open-source tools like <a href="https://codeberg.org/Data-Bene/StatsMgr" rel="noopener">StatsMgr</a> for efficient statistics management for PostgreSQL, <a href="https://github.com/xataio/pgzx" rel="noopener">pgzx</a> for the creation of PostgreSQL extensions using Zig, &amp; more. Get ideas from the experts for new extensions to try out and maximize your Postgres deployments.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Postgres Café: Expand monitoring capabilities with StatsMgr</title>
      <link href="https://www.data-bene.io/en/blog/postgres-cafe-expand-monitoring-capabilities-with-statsmgr/" />
      <updated>2025-01-07T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/postgres-cafe-expand-monitoring-capabilities-with-statsmgr/</id>
     <content type="html"><![CDATA[ <p>2025 has begun, and with it we’re excited to release the second episode of <a href="https://www.youtube.com/watch?v=WwaJd2c9whM" rel="noopener">Postgres Café</a>, a blog and video series from our teams over at <a href="https://www.data-bene.io/en/" rel="noopener">Data Bene</a> and <a href="https://xata.io/" rel="noopener">Xata</a> made with the intention of exploring the world of open source and where it meets PostgreSQL’s extensibility. Throughout this series, we discuss different extensions and tools that enhance the developer experience when working with PostgreSQL. In our second episode, we explore a brand new PostgreSQL extension called <a href="https://codeberg.org/data-bene/statsmgr" rel="noopener">StatsMgr</a> that leverages background workers and shared memory to snapshot, manage, and query various statistics for WAL, SLRU, IO, checkpointing, and more.</p>
<h2 id="episode-2-statsmgr"><a class="heading-anchor" href="#episode-2-statsmgr">Episode 2: StatsMgr</a></h2>
<p>In this episode, we introduce the just-released open source extension StatsMgr, created to continuously monitor and track events across PostgreSQL and the underlying system. Here’s a look at what this episode covered:</p>
<h3 id="customized-metrics-processing"><a class="heading-anchor" href="#customized-metrics-processing">Customized metrics processing</a></h3>
<p>Originally the idea was to provide a simplified interface for metrics, while enhancing them with a wide variety of available types. This functionality was then expanded to address problems like:</p>
<ul class="list">
<li><strong>Making statistics available</strong> for collection from external systems, without interruption even when those external systems are down.</li>
<li><strong>Providing an immediate view of PostgreSQL statistics</strong> with historical tracking, including pg_stat views &amp; functions.</li>
<li><strong>Increasing &amp; reducing the amount of historical records when needed</strong> with dynamic buffer allocation.</li>
<li><strong>Debugging PostgreSQL instances</strong> with historical analysis and without required restarts.</li>
</ul>
<p>This extension, in turn, is great at handling situations like when…</p>
<ul class="list">
<li><strong>…your monitoring agent is down</strong>; using StatsMgr as a backup allows you to ensure you won’t lose statistics in this event, as events are captured regardless and stored for collection later on by your monitoring agent.</li>
<li><strong>…you have spikes or otherwise unusual behavior on your production system</strong>. This extension allows you to get an overview of activity for useful debugging insights.</li>
</ul>
<h3 id="expansive-and-historical-metrics-collection"><a class="heading-anchor" href="#expansive-and-historical-metrics-collection">Expansive &amp; historical metrics collection</a></h3>
<p>Currently, supported statistics include:</p>
<ul class="list">
<li>WAL</li>
<li>SLRU</li>
<li>BGWriter</li>
<li>Checkpointer</li>
<li>Archiver</li>
<li>IO</li>
</ul>
<p>Each of these is registered with a handler that lets you fetch and manage these statistics, and also is accompanied by shared memory structures for storing historical snapshots.</p>
<p>Some of the next steps for the project will include adding in dynamic statistics such as pg_stat_user_tables, amongst others.</p>
<p>There are still many things to do, from subtle improvements to major new features. So of course there’s many opportunities to contribute to the project, no matter if you’re a new-comer or an advanced PostgreSQL developer. Interested in being a part of the effort? Check out <a href="https://codeberg.org/Data-Bene/StatsMgr/src/branch/main/CONTRIBUTING.md" rel="noopener">CONTRIBUTING.md</a> within the project.</p>
<h3 id="watch-the-full-episode"><a class="heading-anchor" href="#watch-the-full-episode">Watch the full episode</a></h3>
<p>For an in-depth exploration of StatsMgr and its capabilities, watch the full episode here:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/UMzCLFwCPI8?si=-NW4Na4PAiq6qdoY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<h3 id="stay-tuned-for-more-postgres-tools"><a class="heading-anchor" href="#stay-tuned-for-more-postgres-tools">Stay tuned for more Postgres tools</a></h3>
<p>We still have much more to come for Postgres Café. <a href="https://www.youtube.com/playlist?list=PLf7KS0svgDP_zJmby3RMzzOVO45qLbruA" rel="noopener">Subscribe to the playlist</a> for episodes that feature more open-source tools like <a href="https://pgroll.com/" rel="noopener">pgroll</a> for zero-downtime schema migrations, <a href="https://www.citusdata.com/" rel="noopener">Citus Data</a> for distributed and scalable PostgreSQL as an extension, and more. Watch this space to learn how each tool can make working with Postgres smoother and more efficient.</p>
 ]]></content>
			<author>
				<name>Sarah Conway</name>
			</author>
    </entry>
    <entry>
      <title>Strange data type transformations</title>
      <link href="https://www.data-bene.io/en/blog/strange-data-type-transformations/" />
      <updated>2024-12-02T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/strange-data-type-transformations/</id>
     <content type="html"><![CDATA[ <h2 id="when-your-function-argument-types-are-loosely-changed"><a class="heading-anchor" href="#when-your-function-argument-types-are-loosely-changed">When your function argument types are loosely changed</a></h2>
<p>This article results from a code review I did for a customer.</p>
<p>Our customer created a <code>pg_dump --schema-only</code> of the target database to provide<br>
me with the plpgsql code and database object structures to review. So far<br>
so good.</p>
<p>I started to read the code and then became puzzled. The code looks like this:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> xxx<span class="token punctuation">(</span> p_id <span class="token keyword">character</span><span class="token punctuation">,</span> p_info <span class="token keyword">character</span> <span class="token keyword">varying</span> <span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> <span class="token keyword">integer</span>
<span class="token keyword">LANGUAGE</span> plpgsql
<span class="token keyword">AS</span> $$
<span class="token keyword">DECLARE</span>
<span class="token keyword">BEGIN</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
   <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> t1
   <span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> t2 <span class="token keyword">WHERE</span> t2<span class="token punctuation">.</span>id <span class="token operator">=</span> p_id<span class="token punctuation">;</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$
<span class="token punctuation">;</span></code></pre>
<p>Maybe you saw nothing wrong with the function. Perhaps knowing the table<br>
definition will help:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> t2 <span class="token punctuation">(</span>
   id <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">130</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span>
   <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
   <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span>id<span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p><a href="http://t2.id" rel="noopener">t2.id</a> is always 130 characters long (in practice) and there are 400 million tuples.<br>
So as you may have guessed, it seems odd to have the p_id CHARACTER matching id VARCHAR(130).<br>
Moreover CHARACTER is the same as CHAR(1).</p>
<p>Our customer had not seen any issues with the code for years. Nevertheless, our customer told me that the function definition he wrote was not like that: it was meant to be p_id CHARACTER(130) - not CHARACTER.</p>
<p>So what went wrong? Let’s test around because it’s fun.</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span> c <span class="token keyword">character</span><span class="token punctuation">,</span> d <span class="token keyword">character</span> <span class="token keyword">varying</span> <span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> void
<span class="token keyword">LANGUAGE</span> plpgsql
<span class="token keyword">AS</span> $$
<span class="token keyword">BEGIN</span>
  RAISE NOTICE <span class="token string">'c=%, d=%'</span><span class="token punctuation">,</span> c<span class="token punctuation">,</span>d<span class="token punctuation">;</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123465789'</span><span class="token punctuation">,</span> <span class="token string">'987654321'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  c<span class="token operator">=</span><span class="token number">123465789</span><span class="token punctuation">,</span> d<span class="token operator">=</span><span class="token number">987654321</span>
 test 
<span class="token comment">------</span>
 
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span></code></pre>
<p>We have an interesting result here: no casting to CHAR(1) has been done.<br>
Let’s see more details:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token punctuation">(</span>COSTS <span class="token keyword">OFF</span><span class="token punctuation">,</span><span class="token keyword">ANALYZE</span><span class="token punctuation">,</span>VERBOSE<span class="token punctuation">)</span>
        <span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123465789'</span><span class="token punctuation">,</span> <span class="token string">'987654321'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  c<span class="token operator">=</span><span class="token number">123465789</span><span class="token punctuation">,</span> d<span class="token operator">=</span><span class="token number">987654321</span>
                             QUERY <span class="token keyword">PLAN</span>                              
<span class="token comment">---------------------------------------------------------------------</span>
 Result <span class="token punctuation">(</span>actual <span class="token keyword">time</span><span class="token operator">=</span><span class="token number">0.040</span><span class="token punctuation">.</span><span class="token number">.0</span><span class="token number">.041</span> <span class="token keyword">rows</span><span class="token operator">=</span><span class="token number">1</span> loops<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span>
   Output: test<span class="token punctuation">(</span><span class="token string">'123465789'</span>::bpchar<span class="token punctuation">,</span> <span class="token string">'987654321'</span>::<span class="token keyword">character</span> <span class="token keyword">varying</span><span class="token punctuation">)</span>
 Planning <span class="token keyword">Time</span>: <span class="token number">0.023</span> ms
 Execution <span class="token keyword">Time</span>: <span class="token number">0.053</span> ms
<span class="token punctuation">(</span><span class="token number">4</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>We can see there was a cast to BPCHAR. As a reminder, BPCHAR is an alias of CHARACTER<br>
and it can represent a string up to 10,485,760 characters.</p>
<p>Now let’s make another test:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span>c <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>
<span class="token keyword">LANGUAGE</span> <span class="token keyword">sql</span>
<span class="token keyword">AS</span> $$
<span class="token keyword">select</span> c<span class="token punctuation">;</span>
$$<span class="token punctuation">;</span></code></pre>
<p>As you can see, the language changed to SQL and the argument type and the return<br>
type are CHAR(4). How does it execute?</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">SELECT</span> test<span class="token punctuation">(</span><span class="token string">'123456789'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
   test    
<span class="token comment">-----------</span>
 <span class="token number">123456789</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">EXPLAIN</span> VERBOSE <span class="token keyword">SELECT</span> test<span class="token punctuation">(</span><span class="token string">'123456789'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                QUERY <span class="token keyword">PLAN</span>                 
<span class="token comment">-------------------------------------------</span>
 Result  <span class="token punctuation">(</span>cost<span class="token operator">=</span><span class="token number">0.00</span><span class="token punctuation">.</span><span class="token number">.0</span><span class="token number">.01</span> <span class="token keyword">rows</span><span class="token operator">=</span><span class="token number">1</span> width<span class="token operator">=</span><span class="token number">32</span><span class="token punctuation">)</span>
   Output: <span class="token string">'123456789'</span>::bpchar
<span class="token punctuation">(</span><span class="token number">2</span> <span class="token keyword">rows</span><span class="token punctuation">)</span></code></pre>
<p>As you can see, even though you expect to process CHAR(4) data, you end up processing arbitrary length strings instead!!</p>
<p>However, do not rush to PostgreSQL mailing list to complain YET!</p>
<p>As a matter of fact, this behaviour is not a bug. The <a href="https://www.postgresql.org/docs/current/sql-createfunction.html" rel="noopener">documentation</a> states:</p>
<blockquote>
<p>“The full SQL type syntax is allowed for declaring a function’s arguments and return value. However, parenthesized type modifiers (e.g., the precision field for type numeric) are discarded by CREATE FUNCTION. Thus for example CREATE FUNCTION foo (varchar(10)) … is exactly the same as CREATE FUNCTION foo (varchar) …”</p>
</blockquote>
<p>This explains that CHARACTER(x) became CHARACTER aliased as BPCHAR. And as we saw, BPCHAR is not actually CHAR(1) but more like VARCHAR(10485760). This fully explains the behaviour.</p>
<p>Wait, wait , WAIT ! The original intention was to deal with CHAR(4) string - not any arbituary length strings.</p>
<p>Isn’t there any hope? No, sorry… (kidding.)</p>
<p>Reading the same documentation page, we see that “argtype” and “rettype” can be base, composite, or domain types, or can reference the type of a table column.</p>
<p>The trick is to create either a composite type or a domain to use as argtype or rettype.</p>
<p>Here are some examples:</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Works in simple case trick</span>
<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'12345789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">-- Domain trick</span>
<span class="token keyword">CREATE</span> DOMAIN c4 <span class="token keyword">AS</span> <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span>param c4<span class="token punctuation">)</span>
<span class="token keyword">RETURNS</span> c4
<span class="token keyword">AS</span> $$
<span class="token keyword">BEGIN</span>
  RAISE NOTICE <span class="token string">'param=%'</span><span class="token punctuation">,</span> param<span class="token punctuation">;</span>
  <span class="token keyword">RETURN</span> param<span class="token punctuation">;</span>
<span class="token keyword">END</span><span class="token punctuation">;</span>
$$ <span class="token keyword">LANGUAGE</span> plpgsql<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
ERROR:  <span class="token keyword">value</span> too long <span class="token keyword">for</span> <span class="token keyword">type</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 test 
<span class="token comment">------</span>
 <span class="token number">1234</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::c4<span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 test 
<span class="token comment">------</span>
 <span class="token number">1234</span>
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> pg_typeof<span class="token punctuation">(</span> test<span class="token punctuation">(</span> <span class="token string">'123456789'</span>::<span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
NOTICE:  param<span class="token operator">=</span><span class="token number">1234</span>
 pg_typeof 
<span class="token comment">-----------</span>
 c4
<span class="token punctuation">(</span><span class="token number">1</span> <span class="token keyword">row</span><span class="token punctuation">)</span></code></pre>
<p>Now you should be happy with the result.</p>
<p>What? Not yet? Ok here is an additional trick.</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Map a table structure</span>
<span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> qq <span class="token punctuation">(</span> c <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">CREATE</span> <span class="token keyword">FUNCTION</span> test<span class="token punctuation">(</span><span class="token operator">IN</span> c qq<span class="token punctuation">,</span> <span class="token keyword">OUT</span> d qq<span class="token punctuation">)</span>
<span class="token keyword">LANGUAGE</span> <span class="token keyword">sql</span>
<span class="token keyword">AS</span> $$
<span class="token keyword">SELECT</span> c<span class="token punctuation">;</span>
$$<span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span><span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
ERROR:  <span class="token keyword">value</span> too long <span class="token keyword">for</span> <span class="token keyword">type</span> <span class="token keyword">character</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">from</span> test<span class="token punctuation">(</span><span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'1234'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  c   
<span class="token comment">------</span>
 <span class="token number">1234</span></code></pre>
<p>Hmm, OK, but how is this is different from the domain trick?</p>
<pre class="language-sql"><code class="language-sql"><span class="token comment">-- Easy Type Alteration</span>
<span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span> qq <span class="token keyword">ALTER</span> c <span class="token keyword">TYPE</span> <span class="token keyword">char</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   c   
<span class="token comment">-------</span>
 <span class="token number">12345</span></code></pre>
<p>Try to ALTER a domain - you will see how (not) easy it is.</p>
<p>The table definition trick allows for some flexibility as follows:</p>
<pre class="language-sql"><code class="language-sql"><span class="token keyword">ALTER</span> <span class="token keyword">TABLE</span> qq <span class="token keyword">ADD</span> ee <span class="token keyword">int</span><span class="token punctuation">;</span>

<span class="token keyword">SELECT</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   test   
<span class="token comment">----------</span>
 <span class="token punctuation">(</span><span class="token number">12345</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">)</span>

<span class="token keyword">SELECT</span> <span class="token operator">*</span> <span class="token keyword">FROM</span> test<span class="token punctuation">(</span> <span class="token keyword">ROW</span><span class="token punctuation">(</span><span class="token string">'12345'</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
   c   <span class="token operator">|</span> ee 
<span class="token comment">-------+----</span>
 <span class="token number">12345</span> <span class="token operator">|</span>  <span class="token number">4</span></code></pre>
<p>We hope you enjoyed this article and that you learnt something new and interesting!</p>
 ]]></content>
			<author>
				<name>Frédéric Delacourt</name>
			</author>
    </entry>
    <entry>
      <title>Welcome to the new Data Bene blog</title>
      <link href="https://www.data-bene.io/en/blog/welcome-to-the-new-data-bene-blog/" />
      <updated>2024-10-02T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/welcome-to-the-new-data-bene-blog/</id>
     <content type="html"><![CDATA[ <h2 id="exploring-postgresql-open-source-and-innovation"><a class="heading-anchor" href="#exploring-postgresql-open-source-and-innovation">Exploring PostgreSQL, Open Source, and Innovation</a></h2>
<p>At Data Bene, we’re excited to unveil the latest version of our blog, where we will delve into PostgreSQL, open-source technologies, and the dynamic world of startups. With this update, we’re eager to bring you a curated selection of technical insights, industry news, and success stories to inspire and inform.</p>
<p>As loyal supporters of open-source solutions, we champion PostgreSQL for its ability to drive innovation and efficiency in modern businesses. Through our articles and tutorials, we aim to empower users to unlock it’s full potential. We will discuss our favourite features as well as provide updates on the latest advancements—topics we believe help in leveraging this powerful relational database management system.</p>
<p>In today’s rapidly evolving tech landscape, open source has become synonymous with collaboration, innovation, and community-driven development. We’re strongly committed to showcasing the transformative potential of open source as a result.</p>
<p>Because of this, in our blog we will explore:</p>
<ol class="list">
<li>open-source tools that are part of the PostgreSQL ecosystem,</li>
<li>how we can improve and support open-source collaboration, and</li>
<li>projects to continue progressing in development that shape the future of open technology while avoiding vendor lock-in.</li>
</ol>
<p>With years of experience working alongside a diverse range of companies, from emerging startups to global enterprises, we’ve seen firsthand how innovative organizations leverage PostgreSQL to drive their success. Our blog will feature not only insights from entrepreneurs and tech leaders sharing their experiences but also in-depth articles from our own PostgreSQL experts. They will discuss their favorite PostgreSQL features and native tools, the challenges they’ve faced, and how they overcame them, providing a unique, technical perspective on overcoming real-world challenges.</p>
<p>We’ll also dive into emerging trends and new technologies that are shaping the future of PostgreSQL, offering a window into how startups and established businesses alike are navigating the fast-evolving landscape of data management. Whether it’s through interviews with founders or analysis of groundbreaking projects, we’ll highlight how PostgreSQL continues to be a key enabler of innovation in today’s tech-driven world.</p>
<p>Finally, at Data Bene, sustainability isn’t just a buzzword—it’s a core value that guides our every endeavor. As we embark on new development initiatives and explore cutting-edge technologies, we’re committed to minimizing our environmental footprint and promoting eco-friendly practices. From optimizing software efficiency to reducing energy consumption, we’re dedicated to building a more sustainable future, one line of code at a time. Consequently, some of the articles we release will highlight these practices and open up the topic of sustainability within PostgreSQL development practices for discussion.</p>
<p>We invite you to join us on this exciting journey of exploration, discovery, and innovation. Whether you’re a PostgreSQL enthusiast, an open-source advocate, a startup aficionado, a long-time developer, or just curious, there’s something for everyone in our blog! So bookmark this page, <a href="https://us.linkedin.com/company/data-bene" rel="noopener">follow us on LinkedIn</a> and keep an eye out for our upcoming newsletter. Anywhere you follow, you’ll be able to stay tuned for regular updates packed with valuable insights and inspiration.</p>
<p>Thank you for being a part of our community. Together, let’s embark on a journey of growth, learning, and shared success.</p>
 ]]></content>
			<author>
				<name>Andrea Cucciniello</name>
			</author>
    </entry>
    <entry>
      <title>Data Bene partner of pgDay Paris 2023</title>
      <link href="https://www.data-bene.io/en/blog/data-bene-partner-of-pgday-paris-2023/" />
      <updated>2023-03-14T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/data-bene-partner-of-pgday-paris-2023/</id>
     <content type="html"><![CDATA[ <p>Like every year Data Bene actively participates in pgDays which, new this year, will be over two days. Event that has become a must for all PostgreSQL enthusiasts! Data Bene is “Partner” of this event which gives you the opportunity to train, share experiences and discover the latest advances, functionalities of the open source relational database.<br>
In its desire to contribute, Data Bene is also participating in the March 22nd day to deliver Tutorials (in French):</p>
<p>In the morning, Frédéric Delacourt will present “Everything you always wanted to know about Connection Pools (but were afraid to ask)”, from 9am to 12:15pm.</p>
<p>In the afternoon, it will be Cédric Villemain’s turn with “CREATE EXTENSION, yours preferably”, from 1:45pm to 5pm.</p>
<p>We are delighted to welcome you there. You will find the details of the training on the agenda of the 2 days, and you can register on the registration page.</p>
<p>We hope to see many of you there!</p>
<p>The Data Bene team.</p>
 ]]></content>
			<author>
				<name>Data Bene</name>
			</author>
    </entry>
    <entry>
      <title>Data Bene contributes to the PostgreSQL@CERN Meetup 2023</title>
      <link href="https://www.data-bene.io/en/blog/data-bene-contributes-to-the-postgresql-cern-meetup-2023/" />
      <updated>2023-01-11T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/data-bene-contributes-to-the-postgresql-cern-meetup-2023/</id>
     <content type="html"><![CDATA[ <p>Data Bene is a co-sponsor with CERN of the Meetup organized by the Geneva PostgreSQL User Group on Friday 13 January afternoon at CERN in Geneva. Cédric and Hélène will be happy to welcome you there or to count you among us in situ or via the webcast: <a href="https://webcast.web.cern.ch/event/i1221200" rel="noopener">https://webcast.web.cern.ch/event/i1221200</a></p>
<p>We will host a conference on Citus Data: Distributed database without complex.</p>
 ]]></content>
			<author>
				<name>Data Bene</name>
			</author>
    </entry>
    <entry>
      <title>Data Bene Partner Sponsor of pgDay Paris 2022</title>
      <link href="https://www.data-bene.io/en/blog/data-bene-partner-of-pgday-paris-2022/" />
      <updated>2022-03-23T00:00:00Z</updated>
      <id>https://www.data-bene.io/en/blog/data-bene-partner-of-pgday-paris-2022/</id>
     <content type="html"><![CDATA[ <p>Data Bene will be here all day, on March 24th 2022, as a Partner Sponsor of the event, to welcome you to THE community conference in France. We will also talk about Partitioning, don’t miss it.</p>
 ]]></content>
			<author>
				<name>Data Bene</name>
			</author>
    </entry>
</feed>
