Public issue detail

Runaway CPU investigation for postgres: busy poll at unresolved offset in h3_postgis.so

postgres is stuck in a likely busy poll loop: 22.73% of sampled CPU passed through [.] 0x000000000001066e, with repeated epoll_wait x1.

highpackage: postgresql-18source: postgresql-18score: 106reports: 2successful triage

Last seen: 2026-03-29 21:01 UTC. Public JSON: /v1/issues/019d3a3b-0e57-7393-a88a-5ddf422b5e86

Successful triage

Fixer did not find an honest diff-backed change in this source tree. Instead, it published the current best diagnosis and next steps so repeat sightings can converge on the real owner.

best triagecreated: 2026-03-29 16:36 UTCvalidation: ready

postgres likely remains stuck in a busy poll loop. A diagnosis report and external handoff were created locally.

Likely owner

module `h3_postgis.so` or the workload driving it

Reason: likely-external-root-cause

Next steps

  • Confirm the hotspot still points at module `h3_postgis.so` or the workload driving it with a fresh perf sample before filing the bug.
  • Capture the actual hot backend or child process rather than the parent service wrapper if the issue recurs.
  • Map module `h3_postgis.so` or the workload driving it to its owning package or project and file an upstream or distro bug with the summarized evidence.
  • If the owner is still unclear, collect another short strace plus `/proc/<pid>/maps` at the moment of the spike.

Technical snapshot

This is the stack-shaped slice and hot path Fixer captured while the process was spinning.

Sampled wait stack

  • Command: /usr/lib/postgresql/18/bin/postgres -D /var/lib/postgresql/18/main -c config_file=/etc/postgresql/18/main/postgresql.conf
  • Why Fixer classified it this way: The trace repeatedly returns to a poll-family syscall without meaningful blocking, which suggests a busy event-loop wakeup.
  • Wait site: do_epoll_wait
  • Hot path: (deleted) [.] 0x000000000001066e (22.73% sampled CPU)
  • Repeated loop: epoll_wait
  • Top syscalls: epoll_wait x1
  • Package: postgresql-18
do_epoll_wait
__x64_sys_epoll_wait
do_syscall_64
entry_SYSCALL_64_after_hwframe

Possible duplicates

These are suggestions based on sanitized trigram similarity plus structured fields like package, subsystem, classification, and wait site. They are not auto-merged.

postgres is stuck in a likely busy poll loop: 7.33% of sampled CPU passed through __pte_offset_map_lock, with repeated thread backtraces show 1 thread(s) around 0x00007f322d29a7d2 in ?? () from target:<path>.

highpackage: postgresql-18source: postgresql-18score: 106reports: 2successful triagesimilarity: 99%

Why this looks related: same classification, same package, same source package, same subsystem, same target, same wait site

Last seen: 2026-10-23 07:30 UTC. Public page: /issues/019e50c1-4b02-72f3-8479-d67944473579. Public JSON: /v1/issues/019e50c1-4b02-72f3-8479-d67944473579

postgres is stuck in a likely busy poll loop: 100.00% of sampled CPU passed through PreCommit_on_commit_actions, with repeated thread backtraces show 1 thread(s) around 0x00007f322d29a7d2 in ?? () from target:<path>.

highpackage: postgresql-18source: postgresql-18score: 106reports: 2similarity: 97%

Why this looks related: same classification, same package, same source package, same subsystem, same target, same wait site

Last seen: 2026-10-23 09:33 UTC. Public page: /issues/019e5105-5337-7b80-ade1-c7185ee1c6f2. Public JSON: /v1/issues/019e5105-5337-7b80-ade1-c7185ee1c6f2

postgres is stuck in a likely busy poll loop: 25.00% of sampled CPU passed through psi_task_switch, with repeated thread backtraces show 1 thread(s) around 0x00007f2f1a25e687 in __GI__IO_flush_all () from target:<path>.

highsource: linuxscore: 106reports: 1similarity: 80%

Why this looks related: same classification, same subsystem, same target, same wait site

Last seen: 2026-10-16 06:35 UTC. Public page: /issues/01a1383d-aefb-7940-ab82-04e5a3259603. Public JSON: /v1/issues/01a1383d-aefb-7940-ab82-04e5a3259603

postgres is stuck in a likely timer churn loop: 100.00% of sampled CPU passed through start_dl_timer, with repeated thread backtraces show 1 thread(s) around 0x00007f322d29a7d2 in ?? () from target:<path>.

highpackage: postgresql-18source: postgresql-18score: 106reports: 2similarity: 78%

Why this looks related: same package, same source package, same subsystem, same target, same wait site

Last seen: 2026-10-23 09:33 UTC. Public page: /issues/019e5d7e-79c8-70a3-bcbd-6d4643b9285a. Public JSON: /v1/issues/019e5d7e-79c8-70a3-bcbd-6d4643b9285a

postgres is stuck in a likely socket churn loop: 3.49% of sampled CPU passed through _dl_map_new_object, with repeated thread backtraces show 1 thread(s) around 0x00007f912645c687 in __GI__IO_flush_all () from target:<path>.

highpackage: postgresql-18source: postgresql-18score: 106reports: 1similarity: 76%

Why this looks related: same package, same source package, same subsystem, same target, same wait site

Last seen: 2026-10-17 07:40 UTC. Public page: /issues/019f9db1-7511-7382-938c-68a2e3e906c8. Public JSON: /v1/issues/019f9db1-7511-7382-938c-68a2e3e906c8

postgres is stuck in a likely futex lock contention loop: 2.60% of sampled CPU passed through cfree, with repeated thread backtraces show 1 thread(s) around 0x00007fa0aa49bca2 in __futex_abstimed_wait_common (futex_word=..., expected=..., clockid=..., abstime=..., private=..., cancel=...) at .<path>:103.

highpackage: postgresql-18source: postgresql-18score: 106reports: 1similarity: 75%

Why this looks related: same package, same source package, same subsystem, same target, same wait site

Last seen: 2026-10-21 03:40 UTC. Public page: /issues/01a15c7a-3458-7a73-8182-e0e16aa271d0. Public JSON: /v1/issues/01a15c7a-3458-7a73-8182-e0e16aa271d0

Worker outcome summary

This issue has 1 recorded worker attempt. Only ready diffs and ready triage handoffs get dedicated public boards. Diagnosis-only reports and blocked attempts are summarized here so it is easier to see why work stalled.

1 ready triage handoffs

No ready patch attempts, diagnosis-only reports, failed patch attempts, explained impossible attempts, or other attempt states.

Most common blockers

  • likely-external-root-cause (1 attempt)

Published attempts

ready triage handoff

triage

postgres likely remains stuck in a busy poll loop. A diagnosis report and external handoff were created locally.

state: readycreated: 2026-03-29 16:36 UTCvalidation: ready

Why it stopped

likely-external-root-cause

Handoff

Likely owner: module `h3_postgis.so` or the workload driving it

Reason: likely-external-root-cause

  • Confirm the hotspot still points at module `h3_postgis.so` or the workload driving it with a fresh perf sample before filing the bug.
  • Capture the actual hot backend or child process rather than the parent service wrapper if the issue recurs.
  • Map module `h3_postgis.so` or the workload driving it to its owning package or project and file an upstream or distro bug with the summarized evidence.
  • If the owner is still unclear, collect another short strace plus `/proc/<pid>/maps` at the moment of the spike.
Published session

Prompt

You are working on a bounded fixer proposal.

Read the evidence bundle at `./evidence.json`. The prepared workspace is `./workspace` and it was acquired via `debian-source`. Produce the smallest reasonable patch for the target repository, run relevant tests if available, and summarize what changed.

Start by explaining the likely root cause from the collected perf, strace, and /proc evidence. If you cannot land a safe patch, leave a diagnosis that is strong enough for an upstream bug report. 

Keep the change narrowly scoped and summarize validation clearly.

Response

**Root Cause**

The evidence does not support a PostgreSQL core busy-poll bug in the sampled process.

`/proc` shows the sampled `postgres` process sleeping in `ep_poll`, with kernel stack `ep_poll -> do_epoll_wait`, and `strace` shows long `epoll_wait(..., 60000)` calls being interrupted only by `SIGCHLD` and new accepts. That matches normal postmaster behavior, not a spin loop. The CPU hotspot from perf was instead in a deleted external module, `h3_postgis.so`, which is not present anywhere in this source tree. The child backends visible in `strace` are executing short-lived application queries and loading external extensions like `vector.so`; nothing in the captured trace points to a tight loop in PostgreSQL’s wait/latch code in [pqcomm.c](./workspace/src/backend/libpq/pqcomm.c), [latch.c](./workspace/src/backend/storage/ipc/latch.c), or [waiteventset.c](./workspace/src/backend/storage/ipc/waiteventset.c).

The most likely root cause is CPU burn inside an extension/query workload in backend children, with the investigation bundle attributing it to the wrong `postgres` process. The strongest lead is the external `h3_postgis.so` mapping from perf, not PostgreSQL core.

**Patch**

No source change landed. A core PostgreSQL patch here would be speculative and unsafe because the implicated code is outside this repository.

**Validation**

I validated this by:
- Reading the evidence bundle and the actual investigation artifacts on disk.
- Confirming the sampled process was blocked in `epoll_wait`, not runnable in a userspace spin.
- Searching the repository and Debian packaging: there is no `h3_postgis`/PostGIS code in this source tree.
- Reviewing the relevant wait-path implementation in core PostgreSQL; nothing in the captured behavior contradicts normal operation.

No tests were run because no safe code change was made.

For an upstream report, the actionable target is the `h3_postgis`/extension stack or the application query workload, with the key points:
- perf hotspot in deleted `h3_postgis.so`
- sampled postmaster actually sleeping in `epoll_wait`
- repeated short-lived backend children handling application SQL
- repository under test does not contain the implicated extension code