Self-hosted service
cybertec-postgresql/pgwatch avatar
cybertec-postgresql/pgwatch

pgwatch: a PostgreSQL-specific monitoring stack with Grafana at the front

🔬pgwatch: PostgreSQL metrics monitor/dashboard

899 stars135 forksGoBSD-3-Clause

At a glance

What is it?
pgwatch is a Go monitoring agent and web interface built specifically for PostgreSQL, with a configuration and metrics database, a web UI for adding monitored servers, and Grafana dashboards on top. The demo container starts in a few minutes, but the production path wants a compose file, a metrics store and a decision about which database version you are prepared to support.
Who is it for?
pgwatch fits a team that runs several PostgreSQL servers and wants a dashboard that answers PostgreSQL questions rather than generic host questions, and it fits a team that already uses Grafana and wants the metric collection to be database aware.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Three containers, one of them is the state you must not lose

The compose file is the clearest description of the architecture, and the documentation names the three services explicitly: the configuration and metric database, the pgwatch monitoring agent with WebUI, and Grafana with dashboards.

That split matters more than it first appears. Two of the three services are stateless in the sense that matters: Grafana holds dashboards, and the agent holds configuration and writes metrics. The third, the configuration and metric database, holds the list of monitored servers, the configuration for each of them, and the metric history. If you lose it, you lose the setup, and you lose the series you were trending. There is no mention in the documentation of an export or backup procedure for that database, so treating it as a first-class piece of production state is a decision you have to make yourself.

The agent is a Go program, and the module path tells you the version it belongs to. The module is github.com/cybertec-postgresql/pgwatch/v6, requiring Go 1.26.0, which matches the v6.0.0 release. That v6 suffix in the module path is a Go convention for a major version past 1.0, and it means anything importing the agent as a library has to use the versioned path. It also means a v6.0.0 release is a deliberate step rather than a routine tag, and the earlier v4.2.0 and v5.3.0 releases on the same day in July 2026 suggest parallel maintenance of the older lines.

The dependency list tells you what the agent is made of. It talks to PostgreSQL through jackc/pgx, stores configuration through the pgx-migrator tool, exposes a websocket with gorilla/websocket, and can pull configuration from an etcd cluster through the etcd client, with the gRPC and protobuf libraries present alongside. Test infrastructure uses testcontainers with dedicated PostgreSQL and etcd modules, and pgxmock for unit level database tests, so the test suite runs real containers rather than only mocks.

The demo image gives you a full stack in one command

The fastest way to see what the project does is the demo image, and the documentation gives the exact command with the three exposed ports and the environment flag that adds a test database.

shell
docker run --detach --name pgwatch-demo \
-p 5432:5432 -p 3000:3000 -p 8080:8080 -e PW_TESTDB=true \
cybertecpostgresql/pgwatch-demo

That command exposes Grafana on port 3000, the administrative web UI on port 8080, and the internal configuration and metrics database on port 5432, with the PW_TESTDB flag set to true.

What matters is the structure it reveals. One container, three ports, and a flag that decides whether a throwaway database is added to the monitoring set. The documentation says that after a few minutes you can open the Database Overview dashboard and start looking at metrics, and that to define your own dashboards you need to log in to Grafana as admin with the admin and pgwatchadmin credentials.

Those default credentials are the first thing to change in any deployment, and the documentation hands them out in plain text in the quick start, which is a signal about the intended audience: this is a demonstration you run on your laptop, not a production image you point at a customer database. Removing the PW_TESTDB parameter is the documented way to start without the test database.

There is also a hosted demo at demo.pgwatch.com, which the documentation links to alongside the full documentation at pgwat.ch, so you can look at the Grafana dashboards without running anything at all.

Production installs clone a version, not the default branch

The production and development paths are documented separately, and the difference is instructive.

For production and long term installation the documentation says to use the cybertecpostgresql/pgwatch image rather than the demo one, and it gives the sequence: clone the repository, check out the version you want, and bring the compose file up detached. The example pins v5.0.0 with a comment noting it can be any other version you want to use.

shell
git clone https://github.com/cybertec-postgresql/pgwatch.git && cd pgwatch

git checkout v5.0.0 # or any other version you want to use

docker compose -f ./docker/docker-compose.yml up --detach

The pattern is the point: the compose file lives in the repository, so you take the whole tree at a tag rather than pointing a compose file at a floating latest image. That gives you the compose file, the dashboards and the agent version from the same commit, which is the only way the pieces are guaranteed to match.

The development path is the same clone without the checkout, but with a build step and an extra initialisation task. The compose file is built from source, brought up detached, and then task demo:init runs to seed the configuration.

shell
git clone https://github.com/cybertec-postgresql/pgwatch.git && cd pgwatch

docker compose -f ./docker/docker-compose.yml build

docker compose -f ./docker/docker-compose.yml up --detach

task demo:init

The task runner here is Go Task rather than Make, and the repository carries a Taskfile.yml along with a Makefile-style layout in the docker directory. The expected startup output is four lines of container status, with the PostgreSQL container reported as Healthy and the agent and Grafana containers started.

The point for a reviewer is that there is a version pinning step, and it is easy to skip. Cloning master and running the compose file gives you whatever is on the default branch, which for a project on a 6.x line is not what the documentation describes.

The web UI is how you add a database, not a config file

Adding a monitored server is done through the built-in web interface on port 8080, and the documentation points you there rather than describing a configuration file format.

That is a meaningful design choice for a PostgreSQL monitoring tool, because a monitored server needs a connection string, a set of credentials, and a decision about which metrics to collect. Handing that to a user interface rather than a YAML file removes an entire class of setup friction for the common case, at the cost of making the configuration harder to version control and harder to reproduce across environments. The documentation does not describe a file based alternative, and the repository listing does not show one at the top level, so the web UI appears to be the supported path.

The agent is what does the work, and the monitoring model follows from the architecture. The agent connects to each monitored database, collects the metrics that database exposes, and writes them into the configuration and metrics database, where Grafana reads them. The dependencies support the idea of configuration coming from a shared store, since the etcd client and the gRPC libraries are present, which suggests an agent can be pointed at configuration held centrally rather than only at its own database.

For looking at what is inside the pgwatch database itself, the documentation offers pgAdmin4 through a separate compose service. There is a port caveat that is worth noting: pgAdmin uses port 80 by default, and the documentation says to change it in the docker/compose.pgadmin.yml file if you want a different port. The service is started with the same compose file and a service name of pgadmin, and you log in at localhost as [email protected] with the password admin, with the pgwatch server already added to the Servers group.

Reproducing load with pgbench is part of the demo loop

The documentation includes a workload step, and that is unusual for a monitoring project, and it is the most useful part of the quick start for anyone trying to learn the tool.

The command is a single task:

shell
task demo:bench

What it does is visible in the sample output, which is a pgbench run at a scaling factor of 50 in simple query mode with 10 clients and 2 threads, 10000 transactions per client and 100000 transactions processed with 0 failed, at a reported average latency of 6.253 ms and a throughput figure of 1567 tps without initial connection time. The pgbench version shown is 17.2 on Debian.

A monitoring tool that only ever sees an idle database teaches you nothing, and dashboards that look flat tell you nothing about whether they detect problems. The benchmark step gives you a moving target with a known shape, so you can watch the metrics respond.

The task also shows the shape of the demo data generation, which drops old tables, creates tables, generates data on the client side, vacuums and then creates primary keys. That order matters for a Postgres audience: the vacuum before the primary keys is there so the index build is not slowed by a pile of dead tuples, and the client side generation avoids a server side copy for no reason.

The developer loop is documented in the same practical spirit. After changing source code, running the compose up command with build, force-recreate and detach is enough to rebuild the agent and relaunch the container. And for detached setups the documentation gives both a compose logs follow command and a variant that follows only the pgwatch service, which is the one you want when three services are writing to the same terminal.

Where pgwatch is the wrong tool

The first limitation is the one the project itself states. pgwatch is described as a PostgreSQL-specific monitoring solution, and its scope is the database rather than the host or the application. A team that wants one monitoring stack covering Postgres, MySQL, a message broker and a handful of API servers will end up running pgwatch alongside something else, and the correlation between a database metric and an application metric becomes manual.

The second is the operational surface. A single database on a single server does not need an agent, a configuration database and a Grafana instance. For that case the standard Postgres tooling, the statistics views and the log files, answers most questions with no extra infrastructure. pgwatch pays off when the number of monitored servers makes manual checking impractical, and it is a poor fit below that threshold.

The third is the upgrade path. The v6.0.0 release moved the Go module path to a v6 suffix, which is the Go signal for a breaking major version, and the documentation's own production instructions still show v5.0.0 as the example checkout. A team that upgrades from a v5 deployment to a v6 one is dealing with a schema change in the configuration and metrics database, and the documentation shown here does not describe the migration procedure or how to roll back if it goes wrong. The presence of pgx-migrator in the dependency list tells you migrations are handled, and the maintenance section of the full documentation is where you would look for the specifics, but the README does not cover it.

There is also a question of what is not monitored. The project is database-centric, so host level signals such as disk latency, CPU steal or network saturation have to come from somewhere else, and the repository contains no node_exporter or similar component. A dashboard that shows only database-side metrics can look healthy while the machine underneath is saturated.

Licence, releases and the shape of the project

The licence is BSD-3-Clause, and the badge in the documentation links to the BSD 3-Clause text. That is a permissive licence with no copyleft obligation, so embedding the agent in an internal platform or redistributing a modified build is not a legal problem. The project is maintained by Cybertec, a PostgreSQL-focused company, and the repository carries an AGENTS.md file, a CLAUDE.md file and an AI_POLICY.md, which is an unusual set of files for a monitoring project and suggests the project is explicit about how automated tooling is expected to be used against the repository.

The release record shows a project in active development. The recent tags are v6.0.0 on 2026-09-15, v5.3.0 on 2026-07-30 and v4.2.0 on the same day, and the last push to the repository was on 2026-10-22. Publishing two major lines on one day is what a maintainer does when parallel support of older major versions is intended, and the fact that the documentation's production example still pins v5.0.0 suggests v5 remains a supported line rather than an abandoned one.

The repository layout is consistent with a mature Go project. There is an api directory, a cmd directory for the binaries, an internal directory, a spec directory that likely holds the API specification, a grafana directory holding the dashboards, a docker directory with the compose files, a docs directory and an mkdocs.yml, a contrib directory, and a Taskfile.yml for the task definitions. The build uses goreleaser through a.goreleaser.yml, and linting is configured with a.golangci.yml.

The Go dependencies are a good summary of what the agent does. pgx for database access, prometheus client libraries for metric exposition, logrus and zap for logging, lumberjack for log rotation, go-retry for the retry logic that a monitoring agent needs when a target database is briefly unavailable, and websocket for the live connection to the web interface. A monitoring agent that retries rather than giving up is a small but meaningful design decision, and the presence of a dedicated retry library is evidence for it.

Editorial conclusion

pgwatch fits a team that runs several PostgreSQL servers and wants a dashboard that answers PostgreSQL questions rather than generic host questions, and it fits a team that already uses Grafana and wants the metric collection to be database aware. It is the wrong choice for a single database, where the operational overhead of an agent, a metrics store and a dashboard exceeds the benefit, and it is the wrong choice if you need monitoring across several database engines, because the project is explicitly PostgreSQL-specific. Before deploying it, pin the version you clone and check the migration path, since the 6.0.0 release changed the Go module path to include a v6 suffix, and decide where the configuration and metrics database will live, because that database is the piece of state you have to back up and secure.

Frequently asked questions

What is pgwatch and who is it for?

pgwatch is a PostgreSQL-specific monitoring solution written in Go, described as scalable and flexible, that provides Grafana dashboards for inspecting database metrics and trends. It is aimed at teams running PostgreSQL servers that want database-level visibility rather than generic host monitoring.

How do I try pgwatch quickly?

Run the demo Docker image, which exposes Grafana on port 3000, the administrative web UI on port 8080 and the configuration and metrics database on port 5432, with PW_TESTDB=true to add a test database. After a few minutes you can open the Database Overview dashboard, and Grafana admin credentials are given in the quick start.

How do I install pgwatch for production?

The documentation says to use the cybertecpostgresql/pgwatch image and the Docker Compose files, by cloning the repository, checking out the version you want, and running docker compose -f ./docker/docker-compose.yml up --detach. That brings up the configuration and metrics database, the monitoring agent with its WebUI, and Grafana with the dashboards.

How do I add a database to pgwatch monitoring?

Through the built-in WebUI on port 8080, which the documentation points to for adding a monitored server. The demo also includes a task demo:bench command that runs pgbench against the test database so you can watch the metrics respond to real load.

What licence is pgwatch released under?

The project is licensed under BSD-3-Clause, a permissive licence with no copyleft requirement. The recent releases are v6.0.0 from 2026-09-15, v5.3.0 and v4.2.0 from 2026-07-30, and the last push to the repository was on 2026-10-22.

Official sources

  1. cybertec-postgresql/pgwatch on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/cybertec-postgresql-pgwatch.svg)](https://hysenlabs.com/projects/cybertec-postgresql-pgwatch)

Was this useful?