λ
The Dream BookSystems • Architecture • Engineering
GitHub ProfileGitHub Profile
#rust

(ENG) Introducing PgVisor

A tool that simplifies PostgreSQL cluster setup and management.

dreamoutbox
dreamoutbox•GitHub

•4 min read

(ENG) Introducing PgVisor

I built a tool to simplify PostgreSQL cluster setup and management.

Nowadays, if you want a simple, minimal 3-node PostgreSQL database cluster, what does it take?

All of the approaches above eventually hit operational friction.

Many teams end up using Patroni with etcd, which introduces even more infrastructure overhead.

Moreover, Patroni is heavily oriented towards Kubernetes; setting it up manually across 3 bare VPS nodes is quite tedious.

We just want a simple PostgreSQL cluster — why does it have to be this complicated? (or maybe it’s just my skill issues?)

Introducing PgVisor


I wrote a Rust wrapper on top of PostgreSQL, integrating Raft consensus via openraft.

Raft allows all cluster nodes to participate in leader elections when a leader goes down, without needing an external witness node like repmgr.

I also built a custom proxy in Rust that routes read-write queries to the leader node and balances read-only queries across follower nodes.

It includes a web dashboard to manage the cluster directly in your browser: inspect cluster and node health, and handle backup & restore (with Point-In-Time Recovery / PITR support).

Backups are executed using pg_basebackup and uploaded to an S3 bucket.

Restores leverage pg_combinebackup to automatically synthesize full and incremental backups.

Let’s Try It Out

Clone the PgVisor repository and launch an example cluster using Docker:

Terminal window
git clone https://github.com/dreamoutbox/pgvisor.git
cd examples/

Start the example cluster:

Terminal window
./pgvisorctl.sh up

Once initialization finishes, open the web dashboard (default password is postgres):

http://localhost:8080

Or connect to the database via psql:

Terminal window
psql -h localhost -p 5432 -U postgres -d postgres

Or connect from your application using the connection URI:

postgresql://postgres:postgres@localhost:5432/postgres

The web dashboard opens to the cluster overview:

web dashboard index

The Cluster Nodes page allows you to start, stop, restart, and promote nodes:

cluster nodes page

Testing Backup & Restore

Generate mock data to test backup and restore:

Terminal window
./dev-mock-data.sh

The Database Explorer will display the generated mock records:

database explorer page

The Backups page now shows 1x full backup and 1x incremental backup:

backups page

Let’s test restoring the database with PITR by entering a timestamp right before the foxtrot record was inserted:


⚠️ Gotcha !

Select the full backup, then specify the PITR target time. PgVisor will automatically pull the necessary incremental backups that cover that timeframe. The key rule: PITR time must be after the full backup creation time.

backup page restore modal

Notice that the foxtrot record is gone because the database was restored to a point in time prior to the insert:

database explorer after restore

Testing High Availability (Auto Failover)

Stop the leader node to simulate a node outage:

Terminal window
docker stop pgvisor-node1

On the Cluster Nodes page, notice that node 1 is marked offline and node 2 was automatically elected as the new leader:

cluster page after node 1 stop

Bring node 1 back online:

Terminal window
docker start pgvisor-node1

cluster page after node 1 restart

Notice that node 1 is back online and has seamlessly rejoined as a follower:

Testing Manual Leader Promotion

You can manually promote any follower directly from the Cluster Nodes page:

promote leader press

cluster page after node 1 promote

Node 1 is now promoted back to leader.

Testing User Creation

You can create database users under the Users & Roles page:

user page create user

Update Table Privileges for the user:

user page update Table Privileges

Connect to the database using the newly created user credentials:

Terminal window
psql -h localhost -p 5432 -U app1 -d postgres

postgres=> SELECT * FROM pgvisor_demo;
id | name | status | counter | created_at | updated_at
----+-------+----------+---------+-------------------------------+-------------------------------
1 | alpha | active | 10 | 2026-11-03 04:00:47.907981+00 | 2026-11-03 04:00:47.907981+00
2 | beta | active | 20 | 2026-11-03 04:00:47.907981+00 | 2026-11-03 04:00:47.907981+00
3 | gamma | pending | 30 | 2026-11-03 04:00:47.907981+00 | 2026-11-03 04:00:47.907981+00
4 | delta | archived | 40 | 2026-11-03 04:00:47.907981+00 | 2026-11-03 04:00:47.907981+00
5 | echo | active | 50 | 2026-11-03 04:00:56.492623+00 | 2026-11-03 04:00:56.492623+00
(5 rows)

Inspecting Audit Logs

You can inspect database queries and activity logs in real time:

audit logs page

It highlights dangerous SQL statements, such as a DELETE without a WHERE clause:

audit logs Dangerous SQL

Conclusion

This tool simplifies setting up and managing a PostgreSQL cluster, focusing primarily on automated HA failover and reliable backup & restore (PITR).

If you run into bugs or have feature ideas, feel free to open an Issue or Pull Request.

All contributions are welcome!

https://github.com/dreamoutbox/pgvisor

#rust#tools#deploy#postgresql#database#backup#restore
dreamoutbox
Written by

dreamoutbox

GitHub

Software Engineer. Passionate about systems architecture, Rust, Go, Linux, and backend infrastructure.

Action completed