Skip to content
PostgreSQL

pgsonify: Hearing PostgreSQL Health as Elephant Sounds

An experimental open-source tool that turns pg_stat_activity, pg_locks and friends into real elephant calls — calm rumbles when all is well, trumpets when it is not.

D
5 min read

Dashboards have to be looked at. Sound does not — it reaches you while you are reading code, writing a migration, or staring at a different terminal. That is the idea behind pgsonify, a small experimental tool I built: it monitors a PostgreSQL instance and plays its health, in real time, as elephant sounds. PostgreSQL’s mascot is an elephant, so the choice of animal was never really in question.

To be clear up front: this is an experiment for local, dev and QA environments — a fun way to build intuition about how a database behaves under load, not a replacement for real monitoring. It is MIT-licensed, written in Go, and the sounds are real elephant recordings from published bioacoustics research, not synthesizer approximations.

What it sounds like

Three moods, driven by a continuous stress score in [0, 1]:

  • 🐘 CALM — a deep, slow, contented rumble with an occasional soft chirp.
  • ⚠️ ALERT — the rumble’s pitch, brightness and pulse rate rise, and a short clean trumpet sounds.
  • 🚨 PANIC — an agitated rumble under rapid, chaotic trumpet blasts.

Individual findings each have their own voice, so you learn to tell what is wrong without looking:

SoundMeaning
😤 Grumblelock waiters, long transactions, rollback storms
💨 Snorttemp-file spills, cache misses going to disk
📢 Contact callreplication lag, XID wraparound distance
🐾 Heavy footfallscheckpoints forced by WAL pressure
🚨 Panic trumpetsdeadlocks, connection saturation, disconnects

Every beat is also explained on the console with the metric and the threshold that triggered it, so the sound is never a mystery.

How it maps PostgreSQL to sound

At startup pgsonify reads pg_settings and derives a musical baseline: a bigger shared_buffers means a bigger elephant, which means a deeper rumble fundamental; checkpoint_timeout sets the cadence of the contented chirp.

Then, every interval (5 s by default), it samples the standard statistics views — no extensions, no superuser requirement:

-- activity and stuck transactions
SELECT count(*) FILTER (WHERE backend_type = 'client backend'),
       count(*) FILTER (WHERE state = 'idle in transaction'),
       COALESCE(max(EXTRACT(EPOCH FROM now() - xact_start))
                FILTER (WHERE backend_type = 'client backend'
                        AND state <> 'idle'), 0)
FROM pg_stat_activity;

-- lock waiters
SELECT count(*) FROM pg_locks WHERE NOT granted;

-- commits, rollbacks, cache hits, deadlocks, temp files (deltas per tick)
SELECT sum(xact_commit), sum(xact_rollback), sum(blks_hit),
       sum(blks_read), sum(deadlocks), sum(temp_files)
FROM pg_stat_database WHERE datname IS NOT NULL;

The checkpoint counters are version-aware: on PostgreSQL 17 and later they come from pg_stat_checkpointer (num_timed, num_requested); before 17, from pg_stat_bgwriter (checkpoints_timed, checkpoints_req). Wraparound distance is max(age(datfrozenxid)) compared against autovacuum_freeze_max_age, and replication is read from pg_stat_replication on a primary or pg_last_wal_replay_timestamp() on a replica — the role is detected with pg_is_in_recovery().

Each finding carries a level (alert or panic) and contributes to the stress score. The score continuously drives the rumble — pitch ×1.0–1.7, louder, brighter, faster pulsing — which mirrors how real elephants encode arousal in their calls. The level picks which trumpet you hear.

Real recordings, real bioacoustics

Early versions used synthesized elephant calls. They sounded terrible. The current voices are genuine field recordings under open licenses: alarm calls from King et al. 2010 (“Bee Threat Elicits Alarm Call in African Elephants”, PLOS ONE, CC BY 2.5) and trumpets from Fuchs et al. 2021 (“Acoustic structure and information content of trumpets in female Asian elephants”, PLOS ONE, CC BY 4.0), plus CC0 recordings from Wikimedia Commons and Freesound. Full attribution ships in the repo.

One honest exception: real elephant rumbles are largely infrasonic — fundamentals around 20–30 Hz, below what laptop speakers reproduce — so the continuous background rumble bed is synthesized in the audible band. The event calls are all real, pitch-shifted at runtime where a voice needs to sit higher to be heard.

Try it

The repo includes pgchaos, a companion load generator that deliberately provokes every condition — connection surges, lock queues, deadlock pairs, temp-file spills, rollback storms, idle-in-transaction sessions — against a scratch database, so you can hear the whole repertoire in a couple of minutes:

git clone https://github.com/cridge-dinesh/pgsonify
cd pgsonify
make demo   # Docker: postgres + pgchaos; pgsonify plays live; Ctrl-C cleans up

Or without a database at all: ./pgsonify -demo sounds plays every event sound with its meaning. Herd mode takes repeated -dsn flags for a primary plus replicas — each instance gets its own voice pitch and stereo position, so you hear which server is calling and from where.

Compatibility is tested, not assumed: every PostgreSQL release line from 10 through 18 passes an end-to-end smoke test (connect → configuration pull → metrics sample → assessment) against the official Docker images.

What this is, and is not

Is it useful? As monitoring, no — keep your Prometheus and your alerting. As a way to feel how a database responds to load — how a lock queue builds, how a checkpoint storm follows a WAL burst, how rollback ratio spikes when a deploy goes wrong — it is surprisingly effective, and it makes database behavior tangible in demos and teaching in a way graphs do not. That, and your PostgreSQL now trumpets at you when someone leaves a transaction open.

Code, sounds, and credits: github.com/cridge-dinesh/pgsonify. Feedback and issues welcome — it is an experiment, and experiments improve by being played with.

Keep reading

All articles →