That’s how Postgres met Django!

That was an experimental meetup: we never, ever scheduled meetups in August, especially during the last week of August! Still, when Keanya Phelps came up with the idea to have a Postgres meetup during the Djangocon.US conference, I couldn’t say no!

Until the last week before the meetup, I was unsure how many people would register and, more importantly, how many would come, but we had a full house (and yes, I didn’t take enough pictures because we had a Zoom setup crisis, so you have to trust me!)

Once again, I can’t even describe how proud I am of the Prairie Postgres community we built during these less than two years of our existence! I am so thankful to everyone who comes, listens, asks questions, and participates in discussions. I have to remind the attendees multiple times that we are about to close the house because people keep talking :). And if you were there and you can’t believe it was ever different, trust me, it was!

Nothing feels as rewarding as seeing genuine interest from listeners and hearing them thank you for organizing the event. That’s when I feel that I am doing something good 🙂

Here is the event recording:

If you’ve never been to our meetups, please consider coming! We love our new venue, and we have the same Giordano’s pizza! And we are family-friendly: we have room for kids just by our meeting room, and if you notify me in advance, we will provide childcare!

Our next meetup is on September 22! Register here!

Leave a comment

Filed under events, talks

How to optimize when you can’t do anything!

It’s hard to say anything new about query optimization. On the one hand, each new Postgres release includes multiple query planner improvements, and it feels like there is something for any problem that can possibly arise. On the other hand, the fundamental principles of optimization do not change: if your query is highly selective, meaning the result is a small percentage of the original data set, you need to build indexes that would support this particular search. If you are optimizing an analytical query, you are looking for the way to execute it in parallel and aggregate early.

There is only one “but” – it’s not like you can build an index on any table at any time. If that’s the case, what can you do?

Recently, I had to find a way to speed up a production query that suddenly started performing significantly slower than it used to. Yes, it reached the tipping point, but nevertheless, I had to find a way to make it fast again. Or at least not terribly slow.

Here is a problem I had to solve.

Given

  • Postgres version: 13.6
  • A monolithic (non-partitioned) table, size 750 GB, 16 billion rows
  • Several indexes, but none of them were super useful for this particular search

And there is a query I needed to optimize. Yes, it looks simple/obvious, but wait till I get to the details!

SELECT * FROM t
WHERE a=? AND b=? AND c=?
AND start_date <='2026-08-16' AND end_date >='2026-08-16'

Date could be any date; I used August 16 for illustration (and no, it’s not “yesterday” or “today”; the query could run for any date in the past). Basically, what you need is to find all records in which the interval from start_date to end_date includes that date in question (and satisfies other selection criteria). The query was running from several seconds to several minutes.

Yes, we know that we need: we need to build a daterange from start_date to end_date, and then build a GIST index on that range. All good, except we all know how long it takes to build any index on 16 billion rows, and if we are talking about GIST, it would easily take longer than 24 hours.

Also:

  • there was no index that would have all of the search fields
  • the highest selectivity column was end_date, and there was no index which would have the end_date as a first column
  • The most suitable index was on (a, start_date, end_date), but a had the lowest selectivity.

The latter index was used, but the queries were still super slow, because if the day you search is for August 24, pretty much all records satisfy the condition on start_date, which resulted in too many reads and filtering too many records. As I said, building any indexes was not an option. What could I do?!

****

I started by suggesting adding an excessive selection criterion on the start date, figuring the actual start can’t be that far away in the past:

SELECT * FROM t
WHERE a=? AND b=? AND c=?
AND start_date <='2026-08-16' AND end_date >='2026-08-16'
AND start_date >='2026-01-01'

But I was wrong. I was told I need to capture “everything,” so I had to go to the very first recorded occurrence of the value in column a, but that query wasn’t super fast either, because this minimum date could be way too far in the past.

WITH min_start_day AS MATERIALIZED
(SELECT min(start_date) AS first_date
FROM t WHERE a =?
)
SELECT * FROM t
WHERE a=? AND b=? AND c=?
AND start_date <='2026-08-16' AND end_date >='2026-08-16'
AND start_date >= (select first_date from min_start_day)

Then the customer asked whether it was possible to make their lives better for just a subset of queries, and I thought I could at least build a couple of partial indexes concurrently, so I asked them which conditions they wanted to run faster. They sent me an Excel sheet, and I built these partial indexes, with start_date first, then end_date, then column a; for this subset, the queries without any changes started running very fast (<100 ms), so the crisis was partially resolved. But then, I looked one more time at that Excel and realized that for each combination, they also sent me the “first day occurred”! I quickly loaded the Excel into a new table, making a, b, and c a unique combination, and modified the query like that:

WITH min_start_day AS MATERIALIZED
(SELECT start_date AS first_date
FROM mapping_table
WHERE a =? AND b=? AND c=?
)
SELECT * FROM t
WHERE a=? AND b=? AND c=?
AND start_date <='2026-08-16' AND end_date >='2026-08-16'
AND start_date >= (select first_date from min_start_day)

I ran this query while the last partial index hadn’t been built yet, using the combination that would be covered by the new index, and it worked perfectly (also under 100 ms). Next, I asked the customer whether they could load the complete list, and how big it would be. They said it’s just a little bit over 2K, and they could definitely insert the remaining records. However, after giving it some thought, they got back to me saying that this list is a table in a different database, and they do not want to maintain the same data in two places, so they will just execute a call to this other database in their code and pass the first date to the query we were optimizing. I said that it was fine; the one round-trip penalty was minimal, and I understood they didn’t want redundancy.

However, on Monday (did I have to say it all happened on Friday?!) I had another thought. If the customer runs two queries in the app, they won’t be able to run this query outside the app and measure performance, so I asked whether they would be willing to try a foreign table. With all precautions of read-only permissions on just one table, the final query was:

  WITH min_start_day AS MATERIALIZED
(SELECT start_date AS first_date
FROM foreign_table
WHERE a =? AND b=? AND c=?
)
SELECT * FROM t
WHERE a=? AND b=? AND c=?
AND start_date <='2026-08-16' AND end_date >='2026-08-16'
AND start_date >= (select first_date from min_start_day)

Again, executed in the same milliseconds.

The takeaways.

  • When you can’t build a new index due to time/size constraints, sometimes you can build an interim “indexing table”: the table has the index you need, is smaller than the one you actually need to index, and it references an existing index
  • The most powerful optimization tool was, is, and will always be looking at the actual data and how different parts are related in real life (or its representation:)).
  • Knowing not what the query reads,but what goal we are trying to achieve is critical

… and now I know why these data centers need to much energy! I was a dead body after I was done!

1 Comment

Filed under SQL

Do What You Love Doing

I was going to write this post for at least a month, but each time I sat down to write, I immediately thought it wasn’t a good time. When so many jobs are at risk and so many people around me are spending months trying to land any job, saying that you should look for a perfect match felt unfair. However, during the past two months, I had so many conversation on the same topic and repeated the same answer so many time, that I thought it’s worth posting about it.

The question I get is some variation of “how do I find time to do everything I am doing” or “where do I get energy to do everything I am doing,” or “what’s my secret of being so active”. No matter in which form this question comes, my answer is always the same: I do the things I want to do, and I never do the things I do not want to do. People do not believe me, but I can tell exactly what I mean when I say this.

Granted, there are always things I have to do, but I am only doing them because thay help me to achieve the goal which I want to achieve. For example, I might not necessarily want to reply to the potential sponsor email at 11 PM, but I want to show my respect to the sponsor, as well as my interest in having them as our sponsor, so I will definitely reply and go to bed later than I planned :).

However, I would never do something I do not really want to do, just because someone asks me and I do not feel comfortable saying “no.” My problem is the opposite: there are so many things I genuinly want to do, that it’s impossible to fit even a half of my wants in my life, so I have to make sacrifices :). I do not have to believe me, but sometimes I can respond to a user request late in the evening, although I do not “have to,” just because I want to help them to resolve the situation. (If you are one of my friendly users, please don’t overuse this feature :)).

Similarly, I firmly believe that the most money one can make is doing the things like like to do the most, because you excel in things which you most love doing, and I am not just talkiong about IT – this applies to any occupation. Again, you do not have to believe me, but once I met a DBA who really wanted to be a nurse, and they were miserable, no matter how much they were paid, and they were not a good DBA either.

Right now, my highest priority is PG DATA 2027, which means that each time I sit at my desk I start with checking whether anything in my Prairie Postgres Inbox calls for action, end everything else is a second priority (except for my day job, of course). I feel guilty not responding to my friends for days and weeks, and that’s not because I do not want to respond or do not like them, but because I have to queue even the things I want to fit in my life. At least, I am trying!

Leave a comment

Filed under People

Prairie Postgres July Meetup: Proudly Sourced at Midwest!

On July 15, we hosted the second meetup at our new location, the Chicago Innovations Center. The CIC is evolving, and we like it more and more! I will probably stop saying it at some point, but for now, I want to repeat it one more time: we hope it will be our permanent home!

We keep experimenting to better serve our community and work toward our mission of supporting Postgres education. For the longest time, I was reluctant to switch to the “two talks at one meetup” model. We used to have two talks in 2016-2017, but ended up switching to one talk per meetup. My rationale was to be able to have a really deep dive into a topic we were discussing, but let’s admit it: listening to a long (even very well-presented) talk after a full workday in the middle of the workweek and staying focused is challenging :)).

This time, we had two shorter talks, both very practical and very engaging. Zach Paden from Symetra presented Declarative schema management with pgschema, and Anna Bailliekova presented PostGIS Quick Start.

I really enjoyed both talks! In Zach’s presentation, I liked the clear explanation of why the declarative, Postgres-native, way of writing migrations eliminates multiple problems (“just use Postgres” approach). And I liked Anna’s presentation because, as she rightly mentioned afterward, people are often afraid to use PostGIS because it feels complicated, and at the same time are reluctant to admit they do not know how to use it. QuickStart was a perfect format!

I also wanted to talk about one more important change which wouldn’t be possible without the support of Chicago Innovations: we now have childcare for the duration of the meetup! I can’t tell you enough how thankful we are for the CIC for recognizing the importance of childcare in providing access to professional development for everyone.

The current childcare space is temporary; there will be a bigger and better-equipped room in the near future. Still, even now, we are happy to offer this option. For our future meetups:

  • If your child is 11 or older and can be self-sufficient (with a book or a tablet), you can just bring them in and indicate that you are bringing a child (children) on the RSVP form
  • If you are going to bring a smaller child, please try to RSVP at least a week in advance so that we can be staffed appropriately for childcare.
  • We have art supplies
  • Each child is getting pizza!

Please see the meetup recording below. As you can see, some children might still miss their parents, but the show still went on!

1 Comment

Filed under community, events

PG DATA 2026 recap, and looking forward to PG DATA 2027

It has been a month since PG DATA 2026, the first full-scale event organized by Prairie Postgres. Looking at the feedback we received from the seekers, sponsors, and participants (and regrets of those who were unable to come :)), I couldn’t be happier with how it went.

I know everyone says this, but let me repeat: this event wouldn’t be possible without everyone who contributed in so many different ways! One more time, I want to thank all organizational committee members, all CfP members. volunteers, speakers, and every single person who attended. You all helped us to build an open and inclusive event where everyone felt welcome.

The organization team and volunteers were so efficient that I was able to attend several talks (which is a huge improvement in comparison with all three PG Days I organized in previous years :)). My only regret is that I didn’t have time for longer conversations with speakers and attendees, especially those who visited Chicago for the first time, but I hope it wasn’t their last time in our city!

And guess what – we are already working on PG DATA 2027! The website is not up yet, but mark your calendar for June 11-12, 2027, and plan to join us in Chicago!

Things I hope will stay the same

  • We will have a similarly amazing CfP committee, and will have a great program featuring both new and experienced speakers
  • We will keep the ticket prices low, making the conference affordable for anyone
  • We will have multiple community sponsors

Things I hope we will do more

  • More people are using DEI – focused grants
  • More training sessions
  • More students participation
  • We hope that at least some universities will participate in our Academic Partnership program

What will be better

  • The conference will be held on Friday and Saturday, which we hope will allow more people to participate
  • Better venue with more space and better floor plan (you won’t need to take the elevator to get from the Red Line to Green Line :))
  • More flexible sponsoring options (we will do labs!)
  • Lower cost of accommodation
  • On-site child care
  • Loyalty discount (if you participated in PG DATA 2026, you will get a discount for PG DATA 2027, and no worries, we saved your ticket number!)
  • More social events

Do you have any other suggestions? If you had joined us in Chicago this year, what would you like to see more next year? What would you like to see less? If you didn’t join us, what would make you join us next year?

Let us know!

Leave a comment

Filed under community, events

Estonia PUG Meetup

Yesterday, I had the pleasure of presenting at the Postgres User Group Estonia, and that was a delightful experience! Many thanks to Ervin Weber, who literally spent three years trying to make it happen. I was happy to give back to one of my favorite places in the world – the city of Tallinn.

I was a little bit hesitant when Ervin indicated his preference to listen to my pg_acm talk. I thought that this talk was often viewed as “too specialized”, “niche,” and not interesting enough to people who are “not very much into Postgres.” And I am so glad I ended up giving this talk to this particular group!

I have probably never heard such extensive and thoughtful feedback! Multiple people approached me during the break, saying they had run into all the problems I described, that they understand the challenges, and that they would love to give it a try! (and now I need to make sure all the bugs in the open-source version are fixed! – Watch for updates on this GitHub repo).

That was a slightly extended version of the talk I gave at PG DATA, and now that this talk has been accepted for PG.Conf EU, I need to extend it a little more, and I know what I will add and how I will incorporate the feedback I received yesterday! It always surprises me that application developers “get it” right away, unlike many DBAs, and understand the advantages of that approach. Each question I received yesterday was clear evidence that people had thought about the problems I was trying to solve and were happy to hear that a solution is available.

Thank you, Tallinn! We will do it again 🙂

Leave a comment

Filed under Data management, events, talks

I think AI can actually help me…

Note: this post was not rewritten by AI 🙂

I’ve been saying for a long time that AI can’t help me because no one else codes the way I do, so it doesn’t have any reference points. Then I realized many advantages of having AI perform some boring tasks, like writing tests (we know we need unit tests, and why we are not writing them? because we don’t have time!).

Something changed a couple of weeks ago, after some conversations I had at work, and here is what I think could potentially happen and bring some positive change.

I have been complaining for years about the application developers’ inertia and their overreliance on ORM tools rather than writing high-performing SQL. I am not going to repeat this rant here – I am not the only one, and you all know! And when I asked what I could do to facilitate changing the course, the answer would be: I am used to that way of programming; I know it works and produces the correct result, too bad it’s not always the most performant!

But now that thing have changed, and most developers use Claude Code, I am wondering whether it would be possible to teach just an AI assistant to use better techniques? Will it work, if people are not actually writing the code? I know that AI can use SQL performance tuning tips; would it be possible to teach AI to use NoRM?

Any thoughts? Or any volunteers to give it a try?

Leave a comment

Filed under Development and testing

Prairie Postgres May meetup: the Mythical data Warehouse

Yesterday, we had our first meetup at our new venue, which we hope will become our permanent home: the Chicago Innovations Center at 1 W. Monroe. We had the pleasure of having Elizabeth Christensen from Snowflake, who delivered a talk pg_lake: Unifying transactional and analytical data with Postgres.

I find the topic exceptionally valuable, and I was delighted when Elizabeth suggested it. Below are some photos and a presentation recording.

Many thanks to:

  • Chicago Innovations Center and personally, David Dewane, for hosting
  • Elizabeth, for coming and presenting
  • Snowflake for sponsoring pizza
  • Carlos Aranibar for co-hosting
  • Ryan Weisman, Rober Ismo, and Akshay Mestry for essential help before, during, and after the meetup
  • and everyone who came and made it a great event!

I hope to see everyone at PG DATA on June 4-5 and at our next meetup on July 15.

Leave a comment

Filed under events, talks, Uncategorized

PG DATA 2026: The talks I am most excited about. Part 4 (the last one!)

That’s the last post of the series about the talks at the upcoming PG DATA 2026 conference, covering the remaining Friday talks.

Part 1

Part 2

Part 3

First, I wanted to mention two more talks presented by PG DATA organizers: Comparing Apples to Oranges with Postgres’ Type System by Dian Fay and Master Upgrading PostgreSQL, Using Real World stories and examples by Pat Wright. Dian’s talk is about Postgres types, and I can’t say enough how much I love the ability to create new types! Probably even more than I love Postgres extensions! Pat’s talk is about real-life upgrade stories, and although we know way too well that our own upgrades will present us with our unique challenges, it’s still worth learning from other people’s experience 🙂

Yet another real-life story is Apoorv Garg’s Electric SQL: Local -first Architecture. Building mobile applications is not something I am familiar with, but it looks like developers had to face familiar problems of reliability, performance, and security, which become especially challenging in the situation of a disappearing network.

Egor Tarasenko’s presentation, Streamlining Data Ingestion and Transformation with Trino + dbt, addresses a well-known problem: handling DDL changes in the source when they are not promptly communicated to the streaming process. I’ve seen multiple solutions to this problem, but none of them appeared to be perfect, so I’m very interested to hear Egor’s perspective.

Several presentations will address understanding and monitoring query execution. First is Alfredo Rodriguez’s presentation How to understand EXPLAIN without dying in the attempt. I remember Alfredo presenting at PG Day Chicago for the first time, and I know he is happy to be back with his by now well-known presentation. Then comes Mohsin Ejaz’s “Why your PostgreSQL tuning guide might be wrong (and what to do about it),” in which he shares DBTune’s perspective. And finally, Postgres plan monitoring and management in practice by Lukas Fittl. I am a great admirer of Lucas’ work; his blog posts have helped me multiple times in hopeless situations, and I am very thankful to him for submitting his talk to PG DATA!

Index skip scan is one of my favorite new Postgres features, and I haven’t had an opportunity yet to experince it’s benifits in real life; and I hope to learn more from Naresh Reddy Regalla’s presentation Index Skip Scans in Postgres 18: Optimizing Composite Index Performance. And finally, Wagner Bianchi’s talk PostgreSQL Security – I already have tons of questions for him, just from reading the talk description!

The conference will end with an hour of Lightning talks – and who knows what surprises this last session will bring!

That’s all about the Program of the upcoming PG DATA conference! Thank you for reading! I hope I sparked some curiosity, and I hope that people are taking notes! See you in Chicago!!!


Leave a comment

Filed under events, talks

PG DATA 2026. The talks I am most excited about. Part 3

After Part 1 and Part 2, here comes the Friday schedule! I hope that on the second day of the conference, I will have more time to attend different talks and actually stay and listen!

My absolutely-most-anticipated Friday talk is Paul Jungwirth’s Migrating to a Temporal Schema. I hope I do not need to explain why. It has been more than ten years since I first tried to implement an asserted versioning model in Postgres, and I took in all the endless possibilities that opened up when you incorporate time into Postgres. I’ve been closely watching Paul’s work for several years, and in 2024, I asked him to present at the Chicago PostgreSQL User Group. That was a blast, but then I really wanted him to give a talk on temporal tables at any Postgres conference, preferably in Chicago :). I am super-excited that temporal features are making their way into Postgres Core, slowly but surely, and waiting for this talk like for no other!

Another speaker whom I encouraged to apply is Denis Magda. I have been following his work for several years, and I really appreciate his contribution to optimizing applications’ interaction with Postgres. Needless to say, I love his book Just Use Postgres! In fact, the talk that Denis will present at PG DATA is just about that: Using modern Postgres capabilities for hybrid search encourages app developers to use Postgres native capabilities in place of “specialized” third-party tools.

I am also happy that Varun Dhawan’s talk was finally accepted for presentation in Chicago! His talk Using Postgres to locate the best coffee near you! demonstrates the versatility of Postgres and presents some non-trivial use cases.

As much as I love seeing new faces at PG DATA, I really appreciate the well-known speakers who often come to Chicago and consistently provide the highest-quality content to conference attendees. We want to bring the world’s best speakers to our local audience, and I am very grateful to all of those who help us to achieve this goal.

This “Gold standard list” includes LISTEN Carefully: How NOTIFY Can Trip Up Your Database by Jimmy Angelakos, Let’s Build a Postgres Extension! by Shaun Thomas, and Logging with Purpose: A Framework for Finding and Fixing Slow Queries in Postgres by Ryan Booz.

VACUUM in PostgreSQL. A danger zone. For any Postgres novice, it’s something scary and mysterious. If you can relate, attend the talk PostgreSQL Housekeeping: The Complete VACUUM Handbook by Sukhpreet Kaur Bedi and Nazneen Jafri.

I am very interested in hearing the presentation, Bridging Oracle’s Diagnostics Power with PostgreSQL’s Native Performance Views by Kellyn Gorman. I can’t tell you how many times I was presented with a question from reluctant (former) Oracle DBAs: Where are AWR reports in PostgreSQL? Looks like we might finally get an answer!

And finally, a community talk by Ellyne Phneah: More Than Just a VIEW: Operational Insights from M-PUG’s First Year. We need to have more of these stories – community building is important!

That concludes Part 3, one more to come!

1 Comment

Filed under events, talks