Tools: PostgreSQL Performance Halved on Linux Kernel 6.8: The THP Bug Every DBA Needs to Know [2026 Guide]

Tools: PostgreSQL Performance Halved on Linux Kernel 6.8: The THP Bug Every DBA Needs to Know [2026 Guide]

PostgreSQL Performance Halved on Linux Kernel 6.8: The THP Bug Every DBA Needs to Know

What Happened to PostgreSQL Performance on Linux 6.7 and 6.8?

The Root Cause: How a Memory Optimization Broke Everything

How to Fix the PostgreSQL THP Performance Regression

Which Linux Kernel Versions Have the Fix?

Why This Keeps Happening: The THP and PostgreSQL Tension

What This Means Going Forward 50%. That's how much PostgreSQL throughput dropped after a single commit landed in the Linux kernel. Not a misconfiguration. Not a bad query plan. A memory management change in kernel 6.7 that was supposed to improve efficiency instead wrecked performance for one of the most widely deployed databases on earth. If you're running PostgreSQL on a recent Linux kernel and haven't heard about this Transparent Huge Pages regression, your production system might already be affected. Here's what makes this bug so nasty: it's invisible. Your queries don't fail. Your logs look clean. Everything just gets slower. By about half. I've spent years debugging production PostgreSQL clusters, and the silent regressions are always the ones that hurt worst. In early 2024, Andres Freund — a PostgreSQL committer — noticed something alarming while running pgbench on a machine with a newer kernel. Throughput had dropped by roughly half compared to the same workload on Linux 6.6. That's not a rounding error. That's the kind of drop that turns a well-provisioned database server into an underpowered one overnight. Michael Larabel at Phoronix independently confirmed it with benchmarks showing PostgreSQL performance dropping by as much as 50% on Linux 6.7 and 6.8 compared to 6.6. Reproducible across different hardware. No ambiguity. The timing made this especially dangerous. Linux 6.7 and 6.8 shipped in early 2024, and distributions were starting to pick them up. Anyone who upgraded their kernel — or deployed on a distro that auto-updated — silently inherited the regression. If you've ever managed a fleet of database servers, you know how terrifying silent performance degradation actually is. No alerts fire because nothing is technically broken. You just burn twice the CPU for the same work. I've seen this exact pattern play out in production more than once. A system change that looks totally benign on paper creates a performance cliff that only shows up under real load. The fix is usually simple. Finding the root cause is where you lose sleep. The culprit was a kernel commit that changed how madvise(MADV_DONTNEED) interacted with Transparent Huge Pages (THP). The intent was straightforward: improve memory efficiency by calling split_huge_page_to_list() when a process signaled it no longer needed certain memory pages. Here's why that was a problem for PostgreSQL specifically. PostgreSQL uses a multi-process architecture. When a new client connects, the system forks a backend process. Parent and child initially share memory pages through copy-on-write semantics. THP, when enabled, collapses small 4KB pages into larger 2MB "huge pages" to reduce TLB (Translation Lookaside Buffer) pressure and speed up memory access. The kernel change caused memory pages to be eagerly collapsed into huge pages. Sounds fine in isolation. But when PostgreSQL forks a process — which it does constantly — those huge pages need to be split back apart so each process gets its own copy. Splitting a 2MB huge page is significantly more expensive than copying a 4KB page. Multiply that by hundreds or thousands of connections and your system spends more time managing memory than actually executing queries. The kernel was optimizing for a workload pattern that is the exact opposite of how PostgreSQL operates. More aggressive huge page consolidation means more expensive page splits on every fork. For a fork-heavy database, this is a disaster. Andres Freund traced the regression directly to this interaction. The commit was well-intentioned — for many workloads, the change probably was an improvement. But PostgreSQL's architecture, with its heavy reliance on fork() and shared memory, turned a memory optimization into a performance anti-pattern. This is exactly why understanding how memory allocators work under the hood matters so much. The kernel and the database were both doing reasonable things individually. The combination was toxic. The good news: the fix is trivial. The bad news: you need to know you have the problem first. Immediate workaround: Disable Transparent Huge Pages system-wide. Write never to /sys/kernel/mm/transparent_hugepage/enabled. This is a runtime change — no reboot required. You can also set transparent_hugepage=never on the kernel command line to make it persistent across reboots. This is the community-recommended approach from both the Hacker News discussion and the LKML thread where the issue was debated. If disabling THP entirely feels too aggressive (some workloads genuinely benefit from it), set THP to madvise mode instead of always. That way only applications that explicitly request huge pages get them. PostgreSQL doesn't request them, so it gets left alone. Honestly, disabling THP for PostgreSQL isn't new advice. The community has recommended it for years. But this regression turned a "best practice" into an "urgent requirement." If you've been running with THP enabled and hadn't noticed problems before, kernel 6.7 is where the math changed. I'll say this plainly, having managed PostgreSQL clusters in production for years: THP should be off by default on any dedicated database server. The theoretical benefits of huge pages for database workloads rarely show up in practice, and the downside risks — as this regression proves — can be severe. If you want the benefits of large pages, use explicit HugePages configuration in PostgreSQL. Skip the THP footgun entirely. The problematic commit has been reverted in the mainline Linux kernel. Linus Torvalds himself weighed in on the LKML thread, acknowledging the severity and noting that THP has caused issues with PostgreSQL before. The revert is being backported to affected stable releases. But here's the practical reality: depending on your Linux distribution, the fix may or may not have reached you yet. If you're running a distro that ships kernel 6.7 or 6.8 — Fedora 39/40, Arch Linux, some Ubuntu development releases — you've got three options: If you're on enterprise distributions like RHEL or Ubuntu LTS, you're likely still on older kernels and not directly affected. But check. Don't assume. This is a good reminder of why careful infrastructure management matters for stateful services like databases. I've shipped enough kernel upgrades to know: for database servers, you test against representative workloads before production. Always. This isn't the first time Transparent Huge Pages have caused problems for PostgreSQL. Not even close. The tension between THP and fork-heavy workloads is a well-documented architectural mismatch that the Linux kernel and PostgreSQL communities have been fighting about for over a decade. THP was designed for workloads with large, contiguous memory allocations. Think Java applications with massive heaps, or in-memory analytics engines. Allocate big chunks, access them sequentially, rarely fork. PostgreSQL is the opposite in every dimension: it forks constantly, uses shared buffers with complex access patterns, and depends on predictable virtual memory behavior. Every few years, a kernel change tips the balance and PostgreSQL performance takes a hit. The pattern is predictable enough that it should be part of every DBA's mental model. The deeper issue is that kernel developers and database developers optimize for different workload profiles. A change that's objectively good for 90% of applications can be catastrophic for the 10% that use fork() and shared memory heavily. PostgreSQL sits squarely in that 10%. This is also why I always push people to understand the full stack when comparing databases. PostgreSQL vs MySQL isn't just about SQL features or query planners. It's about process models, memory architectures, and how they interact with the OS underneath. That stuff matters more than most people think. Kernel upgrades are database migrations. Treat them with the same rigor. Benchmark before and after. Monitor throughput, not just uptime. And for PostgreSQL specifically, disable THP unless you have a very specific, tested reason not to. The PostgreSQL community caught this one relatively quickly, thanks to Andres Freund's diligence and clear benchmarks. But the next regression might not be a dramatic 50% cliff. It might be 10%. Or 15%. Just enough to slowly erode your headroom until one day your database can't keep up during peak traffic and nobody knows why. My prediction: as Linux distributions ship newer kernels by default and PostgreSQL continues growing, we'll see more of these collisions. The kernel isn't going to stop evolving its memory management. PostgreSQL isn't abandoning process-per-connection anytime soon (though connection poolers like PgBouncer help absorb some of the fork pressure). If you're running PostgreSQL in production, add this to your runbook: check THP status on every kernel upgrade. Ten seconds of work. The alternative is discovering a 50% throughput drop from your monitoring dashboard at 2 AM. Or worse, from your users. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Code Block

Copy

madvise(MADV_DONTNEED) split_huge_page_to_list() /sys/kernel/mm/transparent_hugepage/enabled transparent_hugepage=never - Disable THP now using the workaround above. Fastest path to fixing production. - Pin your kernel to 6.6 or earlier. More disruptive but guarantees you avoid the issue entirely. - Update to a kernel that includes the revert. Check your distro's package tracker to see if it's landed in their stable channel.