a curated list of database news from authoritative sources

August 25, 2026

Replication Lag on AWS FSx: The Hidden EC2 Single-Flow Bandwidth Limit

A recent case in our Percona Support team started with a familiar complaint. A PostgreSQL standby lagging behind its primary. Although the problem was simple, it brought a specific flavor that’s worth sharing. The customer had already reached out to AWS Support about the storage layer behind the database, an Amazon FSx filesystem mounted over … Continued

The post Replication Lag on AWS FSx: The Hidden EC2 Single-Flow Bandwidth Limit appeared first on Percona.

Software Bill of Materials in Percona Server for MongoDB

Introduction A software bill of materials (SBOM) offers end users enhanced supply chain visibility, thereby facilitating license compliance and timely vulnerability detection. An SBOM of an application, library, or framework (collectively referred to as a “component”) is a machine-readable document that enumerates all other components it incorporates, including transitive ones. In this way, an SBOM … Continued

The post Software Bill of Materials in Percona Server for MongoDB appeared first on Percona.

August 24, 2026

August 23, 2026

Thoughts on LLMs

I am a distributed systems researcher. I mostly read and write about distributed systems and lightweight formal methods. But as my blog definition says, the blog is about "distributed systems broadly defined and other curiosities". 

The last two years, LLMs were unavoidably the biggest part of those curiosities. However, I was still surprised how much I had written about them, when I went looking for a line I remembered coining. Something like, "LLMs are good at mediocrity, but really fast".

I couldn't find the line, but instead I found a pile of my takes on LLMs scattered across the blog, and I figured it was worth collecting them into an index. So here it is, enjoy! I also threw in my overall take on LLMs that has stayed constant through their four years of reign so far.

 

Hot takes on LLMs

Our Collective Bike Shed Moment (June 26)

Are We Becoming Architects or Butlers to LLMs? (Feb 26)

How LLMs may affect academic writing (Feb 26) 

Agentic AI and The Mythical Agent-Month (Jan 26)

The Agentic Self: Parallels Between AI and Self-Improvement (Jan 26) 

Too Close to Our Own Image? (Jan 26)

Rethinking the University in the Age of AI (Jan 26)

Welcome to Town Al-Gasr (Jan 26)

The Invisible Curriculum of Research (Oct 25) — mostly about AI, trust me

Academic chat: On PhD (Oct 25) — follow-up to the above

What I'd do as a College Freshman in 2025 (Apr 25)


Hot damn, 11 posts deep... Apparently I am an AI thought leader now by accident.

Looking at the dates, I was clearly most obsessed with LLMs in January 2026. There is no surprise there, since agentic tools and models turned a real corner that Thanksgiving of 2025. 

What has stayed constant over the years, however, even as the models themselves got much better, is my verdict on them. The phrase I had been hunting for turned out to be: "LLMs excel at high-throughput mediocrity". 

LLM output looks excellent when you are not the expert in the room. But on a topic you actually know, you would evaluate the output only as a notch above mediocre. This is the Gell-Mann amnesia effect in action. However, the difference is that LLMs can produce this output fast, and they never get tired.  

That is actually very handy when you don't want to work on a part of a project that requires mediocre effort. And the best thing is, you don't have to get bogged down doing it, and keep your momentum going as the LLMs handle those parts. They are a gift from the Gods if you have ADHD. The mundane half of a project that used to stall me out completely is no longer an obstacle.

Which is all to say,  LLMs are a tool. Use the right tool for the right job and you'll love it. Master your tools, and don't focus on their shortcomings for everything and all things.

Even with all these tools running, my highest-ROI tool is still just Emacs (going strong against LLMs at 50 years old, like me), where the actual thinking, writing, and planning happens. Use LLMs for the uninteresting stuff, where mediocrity is sufficient, so you have your time and energy for the work that actually matters.


AI x Systems Research

Well, LLMs didn't just show up as a curiosity in my work, they also collided more directly with my research. Here as they show up in my paper reviews, workshop write-ups, and conference notes, where formal methods and AI actually crossed paths.


Specula: Scaling formal specifications for autonomous model checking of system code (August 26)

Our MongoDB TLA+ Workshop (June 26)

Writing Code vs. Shipping Code: Productivity Effects Across Generations of AI Coding Tools (June 26)

ACM CAIS: Conference on AI and Agentic Systems (June 26)

BugBash'26 Keynote: We won, what now? (April 26) 

Measuring Agents in Production (March 26)

Measuring AI Ability to Complete Long Software Tasks (March 26) 

SysMoBench: Evaluating AI on Formally Modeling Complex Real-World Systems (March 26) 

Beat Paxos (March 26)

Barbarians at the Gate: How AI is Upending Systems Research (Oct 25)

Supporting our AI overlords: Redesigning data systems to be Agent-first (Sep 25)

Neurosymbolic AI: Why, What, and How (Aug 25)

August 20, 2026

Migrate multilingual full-text search from SQL Server to PostgreSQL

Migrating full-text search from SQL Server to PostgreSQL can silently change results because the engines handle text, linguistics, and accents differently. This post shows how to reproduce SQL Server full-text search on Amazon Aurora PostgreSQL and Amazon RDS for PostgreSQL, covering collation, tokenization, accent-insensitive search, and synonyms.

August 19, 2026

Understand memory management in Amazon RDS for PostgreSQL to avoid out of memory

PostgreSQL out-of-memory (OOM) events and excessive disk spilling are among the most common production incidents on Amazon RDS for PostgreSQL and Amazon Aurora PostgreSQL. Learn how PostgreSQL allocates and consumes memory, how to identify memory-intensive queries, and how to diagnose, prevent, and recover from OOM events on both engines.

Security Advisory: Privileged ClickHouse access through the Grafana data source in PMM

Date of release: 19 August 2026 Severity: High Affected product: PMM Impacted versions: 3.9.0 and below Summary Percona has recently been made aware of a security vulnerability affecting PMM. We take the security of our products and the protection of our customers’ data with the utmost seriousness. This advisory describes the vulnerability, the immediate steps … Continued

The post Security Advisory: Privileged ClickHouse access through the Grafana data source in PMM appeared first on Percona.

Stop guessing at gcache: inspect Galera/PXC write sets with gcache-inspector

The common practice is to size the Galera Cache based on write volume measured during peak load, but often it is more of a guesswork. The writeset cache capacity planning is crucial to shorten the maintenance time and avoid long state transfers while the cluster runs with reduced compute power. Now, if you could understand … Continued

The post Stop guessing at gcache: inspect Galera/PXC write sets with gcache-inspector appeared first on Percona.

August 18, 2026

Scale pgvector with binary quantization on Amazon Aurora PostgreSQL

Learn how to use binary quantization with reranking (HNSW+BQ) in pgvector to scale vector search to hundreds of millions or billions of vectors on Amazon Aurora PostgreSQL, with practical guidance on index sizing, recall validation, and the scenarios where the approach works best.

Connect client traces to your logs

supabase-js now propagates W3C Trace Context to Supabase, so a client trace and the matching Supabase log share one trace_id.

Poisoned Postgres connection pools

An engineer's worst nightmare is waking up to a seemingly read-only database with no clear issue in sight. Let's dig into why this happens, and how AI can help solve it.

August 17, 2026

Amazon Aurora DSQL observability concepts and usage with Amazon CloudWatch

Amazon Aurora DSQL offers time-based observability through Amazon CloudWatch Database Insights. Learn how the DSQL observability model, DASH, Database Insights, PromQL, and the system diagnostics AI skill help you find performance bottlenecks and connect session time directly to cost.

Unlocking real-time analytics: Streaming Aurora DSQL changes into Apache Iceberg

Stream Amazon Aurora DSQL change data capture (CDC) events into Apache Iceberg tables on Amazon S3 with Amazon Data Firehose, then query them using Amazon Athena. This post walks through a two-table design that keeps a full audit trail and a current-state view, plus deployment and a dashboard for exploring the results.

Skip Scan vs. Loose Index Scan

Both optimizations avoid (skip) reading (scan) irrelevant leaf pages by repositioning (seek) via a fresh index descent instead of scanning sequentially. This surface similarity explains why people often used "skip scan" and "loose index scan" interchangeably before the distinction was clearly defined. For example, I wrote YugabyteDB Skip Scan aka Loose Index Scan on compound index in 2022 because the two concepts were not clearly distinguished in the PostgreSQL wiki at that time. PostgreSQL implemented neither of those features yet, and YugabyteDB implemented both with the same hybrid scan mechanism. However, today the distinction matters because PostgreSQL 18 has added Skip Scan but not Loose Index Scan.

What they have in common: repositioning an index scan between multiple sub-ranges

A plain range scan seeks once to the start of a range and then reads forward or backward until past the end. Both Skip Scan and Loose Index Scan can instead reposition to a new range, or "grouping" (a run of index entries sharing the same leading-column value), via a new index descent, rather than reading through a single range sequentially. This avoids reading irrelevant leaf pages.

What's different: what happens within each sub-range

Skip Scan avoids reading leaf pages entirely outside a relevant sub-range. PostgreSQL does not skip index entries that might match: within a grouping, it still examines the relevant entries and returns every match, exactly as a normal scan would within that sub-range. Separately, PostgreSQL can sometimes avoid rechecking a scan key on a page whose high key proves that all entries satisfy it (as a CPU optimization), but it does not avoid reading the page.

A Loose Index Scan, by contrast, deliberately reads only the first entry of each range and then jumps to the next range — it never reads the remaining matching rows because it isn't trying to satisfy a later-column predicate, only to enumerate the distinct values of a prefix.

In short:

Skip Scan Loose Index Scan
Skips Leaf pages belonging to sub-ranges that can't satisfy the later-column predicate Leaf pages/entries belonging to any range after its first entry
Within a matched range Reads/checks every entry against the later-column Reads one entry, then repositions to the next range
Purpose of the leading column Vehicle for enumerating candidate ranges so a later-column predicate can be applied efficiently The thing being enumerated (e.g., DISTINCT) — no later-column predicate needed

They benefit from similar data distributions

Both optimizations benefit when the leading index column has relatively few distinct values and many rows per value. Repeated descents are then cheaper than scanning large groups of entries sequentially.

Skip Scan may be rejected when the number of descents exceeds the cost of scanning the index normally. A Loose Index Scan has the same trade-off: if almost every row has a different prefix value, one descent per value is not worthwhile. Its advantage appears when each group contains enough duplicate entries to make skipping the rest of the group profitable.

The distinction is therefore not primarily the index definition or the data distribution. It is the query's objective: Skip Scan must return all matching rows, whereas Loose Index Scan deliberately returns only one representative per group.

Example

I created a table with an index on two columns:

CREATE EXTENSION IF NOT EXISTS pageinspect;

DROP TABLE IF EXISTS demo CASCADE;

CREATE TABLE demo (
    a       integer NOT NULL,
    b       text    NOT NULL,
    payload text    NOT NULL
);

INSERT INTO demo (a, b, payload)
SELECT
    a,
    repeat(md5(g::text), 28),       -- approximately 900 bytes
    repeat('payload-' || a || '-' || g, 20)
FROM generate_series(1, 8) AS a
CROSS JOIN generate_series(1, 80) AS g;

CREATE INDEX demo_ab_idx ON demo (a, b);

VACUUM ANALYZE demo;

Here is a query that shows the index entries in their logical order:

SELECT
    s.blkno AS index_block,
    i.itemoffset,
    d.a,
    left(d.b, 100) || '...' AS b,
    i.itemlen,
    i.htid,
    i.data as data 
FROM bt_multi_page_stats('demo_ab_idx', 1, -1) AS s
CROSS JOIN LATERAL bt_page_items('demo_ab_idx', s.blkno) AS i
JOIN demo AS d
  ON d.ctid = i.htid
WHERE s.type = 'l'
ORDER BY
    d.a,
    d.b;

My example has 640 rows:

A Skip Scan will scan all values of "a" but may skip the portions of each "a" grouping outside the "b" range, for example WHERE b LIKE '28%':

 index_block | itemoffset | a |                                                    b                                                    | itemlen |  htid   |                                                                                              data
-------------+------------+---+---------------------------------------------------------------------------------------------------------+---------+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
           1 |         14 | 1 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (8,2)   | 01 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           1 |         15 | 1 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (12,4)  | 01 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           1 |         94 | 2 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (21,3)  | 02 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           1 |         95 | 2 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (25,5)  | 02 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           2 |         78 | 3 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (34,3)  | 03 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           2 |         79 | 3 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (38,5)  | 03 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           4 |         62 | 4 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (47,3)  | 04 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           4 |         63 | 4 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (51,5)  | 04 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           5 |         46 | 5 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (60,3)  | 05 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           5 |         47 | 5 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (64,5)  | 05 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           6 |         30 | 6 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (73,3)  | 06 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           6 |         31 | 6 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (77,5)  | 06 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           7 |         14 | 7 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (86,3)  | 07 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           7 |         15 | 7 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (90,5)  | 07 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00
           7 |         94 | 8 | 2838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838023a778dfaecdc212708f721b7882838... |      72 | (99,3)  | 08 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 33 38 30 32 33 61 37 37 38 64 66 61 65 63 64 63 32 31 32 37 30 38 66 37 32 31 62 37 38 38 20 00 ff ff ff 4b 50 31 62 37 38 38 00 00 00 00 00 00
           7 |         95 | 8 | 28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd2c7955ce926456240b2ff0100bde28dd... |      72 | (103,5) | 08 00 00 00 da 00 00 00 80 03 00 40 ff 11 32 38 64 64 32 63 37 39 35 35 63 65 39 32 36 34 35 36 32 34 30 62 32 66 66 30 31 30 30 62 64 65 20 00 ff ff ff 4b 50 30 30 62 64 65 00 00 00 00 00 00

A Loose Index Scan will read only the first row for each value of "a", for example, in SELECT DISTINCT ON (a):

 index_block | itemoffset | a |                                                    b                                                    | itemlen |  htid  |                                                                                              data
-------------+------------+---+---------------------------------------------------------------------------------------------------------+---------+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
           1 |          2 | 1 | 02e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e7... |      72 | (4,2)  | 01 00 00 00 da 00 00 00 80 03 00 40 ff 11 30 32 65 37 34 66 31 30 65 30 33 32 37 61 64 38 36 38 64 31 33 38 66 32 62 34 66 64 64 36 66 30 20 00 ff ff ff 4b 50 64 64 36 66 30 00 00 00 00 00 00
           1 |         82 | 2 | 02e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e7... |      72 | (17,3) | 02 00 00 00 da 00 00 00 80 03 00 40 ff 11 30 32 65 37 34 66 31 30 65 30 33 32 37 61 64 38 36 38 64 31 33 38 66 32 62 34 66 64 64 36 66 30 20 00 ff ff ff 4b 50 64 64 36 66 30 00 00 00 00 00 00
           2 |         66 | 3 | 02e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e7... |      72 | (30,3) | 03 00 00 00 da 00 00 00 80 03 00 40 ff 11 30 32 65 37 34 66 31 30 65 30 33 32 37 61 64 38 36 38 64 31 33 38 66 32 62 34 66 64 64 36 66 30 20 00 ff ff ff 4b 50 64 64 36 66 30 00 00 00 00 00 00
           4 |         50 | 4 | 02e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e7... |      72 | (43,3) | 04 00 00 00 da 00 00 00 80 03 00 40 ff 11 30 32 65 37 34 66 31 30 65 30 33 32 37 61 64 38 36 38 64 31 33 38 66 32 62 34 66 64 64 36 66 30 20 00 ff ff ff 4b 50 64 64 36 66 30 00 00 00 00 00 00
           5 |         34 | 5 | 02e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e74f10e0327ad868d138f2b4fdd6f002e7... |      72 | (56,3) | 05 00 00 
                                    
                                    
                                    
                                    
                                

Percona University Comes to Uruguay

Percona University is coming to Montevideo. On September 23rd, 2026, we’re getting together for a full day of technical talks on open source software, and you are invited! If you work or study with open source software in Uruguay, this one is for you. It’s a whole day of learning, with the people who build … Continued

The post Percona University Comes to Uruguay appeared first on Percona.

What is a data topology?

A data topology describes the sharding scheme a Neki router uses to map logical PostgreSQL tables to physical shards and route queries.