morletdb

Self-driving Postgres on the edge

The phrase is not ours. In July 2025 Nikolay Samokhvalov, founder of Postgres AI ↗, announced an open-source project called Self-Driving Postgres ↗. His aim fits in one sentence:

“Our goal is to reduce manual interventions as much as possible.”

Nikolay Samokhvalov, Postgres AI, July 2025

He borrowed the levels of driving automation, from 0 (manual) to 5 (full automation), and applied them to each area of database operations separately: index care, vacuum, upgrades and so on. And he put the emphasis on health rather than cleverness: what matters, he wrote, is “not automated index creation, but rather automated index health management”. Postgres AI has since sharpened this to fixes that come with evidence, are tested on a copy of the data, and need the owner’s approval before they touch production. We find that last step as important as the first.

Next to a machine tool there is no database administrator. There is an operator who sees a screen, and in the control cabinet a small computer that a controls engineer needs a ticket to restart. A database that only stays healthy if someone opens a shell will, in practice, not stay healthy. Background builds fall behind, the disk fills, and the first sign is a search that quietly finds less than it should. So we want to take Nikolay’s idea to the shop floor: MorletDB should look after itself, area by area, and know exactly where it must stop and ask.

Line illustration of a CNC machining center with an accelerometer on the spindle and an operator panel showing Normal, wired to a control cabinet whose DIN rails hold circuit breakers, a PLC, terminal blocks and a small edge computer running PostgreSQL with MorletDB CNC MACHINING CENTER SENSOR NORMAL HMI MORLETDB POSTGRES 17 PLC CONTROL CABINET (SCHALTSCHRANK) RAW WAVEFORM STATUS → HMI
The database lives in the cabinet, the person who looks at it stands at the panel. Illustration, not a specific machine.

Why MorletDB is a good candidate

Diagram of MorletDB's storage layers: a row of lossless raw chunks at the bottom, and above them derived layers that are rebuilt from the raw chunks: one summary per chunk, exact roll-ups over blocks of chunks, and search envelopes. A ledger records every forgetting step. On the right, the order of steps when the disk runs short, ending with never deleting raw data silently. RAW CHUNKS · LOSSLESS · CRC-32C · NOT REBUILDABLE ONE SUMMARY PER CHUNK (66 BYTES) EXACT ROLL-UPS OVER BLOCKS OF CHUNKS SEARCH ENVELOPES AND PROBES DERIVED · REBUILT FROM RAW LEDGER: EVERY FORGETTING STEP, BYTES FREED, MD5 WHEN THE DISK RUNS SHORT 1 WARN IN TIME LEFT 2 PAUSE BACKGROUND WORK 3 DROP DERIVED DATA 4 REFUSE NEW RECORDINGS NEVER DELETE RAW SILENTLY
Only the bottom row is irreplaceable. Everything above it can be dropped under pressure and rebuilt later, which is what makes unattended upkeep safe.

The line it must not cross

In Nikolay’s levels, MorletDB should run at a high level for everything above the bottom row of the picture, and at a low one for the bottom row itself. Most self-tuning systems risk a slow query that gets rolled back. MorletDB stores recordings that cannot be measured again. So the rule is narrow on purpose: automate every job whose output can be rebuilt, ration the disk on its own, and never delete raw data unless a person approved that exact plan and a verified copy exists elsewhere. It will also never update itself; in a plant, updates go through change control.

When the disk runs short, the order is fixed. Warn early, in time remaining rather than percent. Pause background work. Drop rebuildable search data if a policy allows it. Then refuse new recordings, with a clear reason. Refusing new data is a visible failure someone can fix. Losing old data unnoticed is not.

What the operator sees

One state: Normal, Attention or Action required, as industrial screens already do it. Each item says what is happening, what happens if nobody acts, one action and who should take it: “Disk full in about 6 days at the current recording rate; then new recordings are refused. Maintenance: add storage or confirm export.” Things the system fixes by itself are logged, not alarmed. The same status should reach the plant’s screens, monitoring and, read-only, AI agents over MCP.

Update, 8 November: the first tests

A day later, part of the design runs. morlet-steward ↗ is a small program next to the database, as a container or a systemd service. It runs the rebuildable jobs (envelopes, summaries, roll-ups, a weekly morlet_verify pass) in one loop with a time budget, only when the machine is not busy, and writes a row for every action and one plain status. Its database role can build derived data and cannot remove stored samples: its test checks that DELETE, UPDATE of samples, TRUNCATE and DROP are refused.

Then we filled a disk on purpose. On a Raspberry Pi 3B+, the database lived on a 1.2 GB filesystem, and a writer appended incompressible noise until it was refused. The result ↗:

The edge also had a say. The first run was stopped by hand because the power strip feeding the Pi started clicking. The Pi kept power, but the soak will run on a better outlet. Power is part of the problem, not just the disk.

Half of the line not to cross is now enforced in SQL, not just written down. Anything that removes or changes stored samples, or updates the extension, is a plan. The steward or a person proposes it, a second person approves that exact plan (tied to its hash, valid for 24 hours, applied once, no self-approval), and a person applies it. The steward notices when a newer pg_morlet is installed and proposes the update. It never applies one. The other half, a verified copy elsewhere before raw data goes, is not checked yet; it waits for the backup drills (#192 ↗). These rules bind the steward and the plan path; the database owner can still act directly, as in any PostgreSQL.

Search on the Pi also got faster. Exact search used to build query matrices larger than the Pi’s cache; now it scores windows directly when they do not fit. A query over 1,341 windows of 16,384 samples went from 15.1 s to 1.5 s, with bit-identical distances (results ↗). All of this is in release 0.3.8-alpha.1 ↗.

Still open

Of the four steps in the picture, step 4 (refuse new recordings) has now been tested on a real disk. Steps 1 and 2, warning in time remaining and pausing background work, are built and unit-tested, but need days of real growth to show they act in time. Step 3, dropping rebuildable search data by policy, is not built yet. The status is a view that an HMI can poll and a status / check command; the read-only MCP tool and the metrics endpoint (#197 ↗) are not built yet. MorletDB has also not yet passed a power-cut test (#190 ↗) or a multi-week soak (#191 ↗), which will run on the Pi with live data from a smart plug. The plan and its progress are in issue #287 ↗ Comments and objections are welcome there.