Deployment guide

PoWA

Overview

This guide shows you how to deploy and configure PoWA on Ubuntu 24.04 on Azure with the SecureAnyCloud Azure Marketplace images.

PoWA, the PostgreSQL Workload Analyzer, is a workload analysis platform for PostgreSQL. A set of statistics collection extensions records what the server is doing. A background worker snapshots those statistics on an interval into a repository database, and a web interface turns the snapshots into time-series charts and ranked query lists.

PoWA stores a history rather than a single instantaneous reading, so it answers a question that a live statistics view cannot: what changed, and when. pg_stat_statements can tell you which query has used the most time since the counters were last reset. PoWA can tell you that the same query was fine all week and then tripled its runtime at 14:20 on Thursday.

This image bundles the complete appliance on a single virtual machine. What you get:

  • powa-archivist 5.2.0. The repository schema and the snapshot background worker.
  • powa-web 5.2.0. The web interface, served through nginx on TCP 80.
  • PostgreSQL 18. It is configured as the first monitored server, so the appliance analyses a real database from the moment it starts.
  • The full statistics stack. pg_stat_statements, pg_qualstats, pg_stat_kcache, pg_wait_sampling, pg_track_settings and hypopg.
  • A dedicated data disk. The repository lives on its own 32 GiB volume, so you can widen retention by resizing storage rather than rebuilding.

The three component versions, the services as a customer virtual machine runs them, and the dedicated volume the repository lives on.

The appliance is standalone and self-demonstrating. PoWA registers the PostgreSQL instance it is installed in as server id 0, the <local> server. The background worker snapshots that instance with no collector, no remote server and no database of yours required. You get a working analyzer on day one, and you attach your own servers when you are ready (Step 9 and Step 10).

The image also includes:

  • PoWA 5.2.0, with archivist and web interface as a matched pair, under the PostgreSQL licence.
  • PostgreSQL 18 from the PGDG repository, so the database and every extension keep receiving upstream security updates.
  • A first-boot service that creates the administrator role and the session signing key uniquely per virtual machine.
  • A demo workload tool, so you can prove collection end to end in about a minute.

Every statistics source PoWA consumes, installed in the repository database, and the preload order that pg_stat_kcache requires.

Security model

PoWA can read every query text that runs on the servers it watches, so treat the interface as privileged:

  • Only TCP 80 (the web interface) and TCP 22 (SSH) are reachable from the network. PostgreSQL binds 127.0.0.1:5432 and powa-web binds 127.0.0.1:8888, so nginx is the single front door.
  • The interface has no account store of its own. The login form's username and password are used to open a PostgreSQL connection, so the login credential is a database role. The image contains no application-level default account.
  • No usable credential ships in the image. The powa_ui role does not exist in the captured image at all. First boot creates it on each virtual machine, with a password generated on that machine, and writes the password to a 0600 root:root file. The session signing key is generated at the same moment, so a captured image cannot even forge a session cookie.
  • powa-web cannot start before first boot has finished. Its unit is gated on a bootstrap marker that first boot writes only after the credential exists. The service therefore never starts with a key in place but no administrator role.
  • PostgreSQL's own postgres role is left as the packaging leaves it. It has no password and allows peer authentication over the local socket only.
  • PoWA's own predefined roles are group roles, not logins. Creating the powa extension defines powa_admin, powa_snapshot, powa_signal_backend, powa_write_all_data, powa_read_all_data and powa_read_all_metrics, so the repository can be shared with least privilege. All six ship exactly as the extension creates them: NOLOGIN, no password. The appliance's login role is deliberately named powa_ui so that it never collides with them.

Prerequisites

  • An Azure subscription with permission to create virtual machines.
  • An SSH key pair for administrative access.
  • A network security group that allows inbound TCP 22 (SSH) and 80 (PoWA web interface) from your own address ranges.
  • Recommended size: Standard_B2s (2 vCPU, 4 GiB) for the appliance analysing itself and a small number of remote servers. Choose a larger size when you attach busy servers, because retention and query cardinality drive both memory and disk.
1

Deploy from the Azure Portal

  • In the Azure Portal, choose Create a resource and search for PoWA on Ubuntu 24.04 LTS by SecureAnyCloud.
  • Select the offer and click Create.
  • Choose your subscription, resource group and region.
  • Set the virtual machine size to Standard_B2s or larger.
  • Under Administrator account, select SSH public key and supply your key. The admin username is azureuser.
  • Under Inbound port rules, allow SSH (22) and HTTP (80).
  • Click Review and create, then Create.

The image includes a 32 GiB data disk that is provisioned with the virtual machine. The disk is mounted at /var/lib/powa and holds the PostgreSQL cluster, which contains the whole PoWA repository.

2

Connect and wait for first boot

Once the virtual machine is running, connect over SSH from your workstation with ssh azureuser@<vm-public-ip>.

First boot creates this machine's administrator role and session signing key, starts the interface, proves that the credential works and takes the first snapshot. It normally completes within a minute of the machine reaching the running state. Confirm that it has finished:

systemctl is-enabled powa-firstboot.service test -f /var/lib/sac/data/powa-firstboot.done && echo "first boot complete" || echo "first boot still in progress"
3

Retrieve your credentials

First boot writes the administrator credential for this machine to a root-only file. Read it with:

sudo cat /root/powa-credentials.txt

The file shows the interface URL, the login URL, the administrator role name (powa_ui) and the password generated for this virtual machine.

Everything reachable from the network, the root only credentials file with the password masked, and a real authentication round trip proving the credential works and that a wrong one does not.

4

Sign in to the interface

Open http://<vm-public-ip>/ in a browser. PoWA answers every unauthenticated request with the sign-in form.

Enter the username and password from Step 3, and leave Server set to main, which is the bundled PostgreSQL instance.

powa-web authenticates by opening a PostgreSQL connection, so the credential is a database role rather than an application account.

After you sign in, you land on the list of monitored servers. The <local> entry is the appliance's own PostgreSQL instance, and PoWA is already analysing it.

The bundled PostgreSQL 18 instance, registered as server id 0 and analysed with no further configuration.

5

Confirm collection is running

The background worker takes a snapshot every minute. Check the repository directly with these queries:

sudo -u postgres psql -tAd powa -c "SELECT count(*) AS snapshots FROM powa_snapshot_metas WHERE srvid = 0"
sudo -u postgres psql -tAd powa -c "SELECT count(*) AS statements FROM powa_statements WHERE srvid = 0"

To read back the collection policy this image ships with, run:

sudo -u postgres psql -tAc 'SHOW powa.frequency'
sudo -u postgres psql -tAc 'SHOW powa.retention'
sudo -u postgres psql -tAc 'SHOW pg_qualstats.sample_rate'

The shipped collection policy, the local server PoWA registered for itself, and the history accumulated so far.

6

Generate a demo workload

A new appliance has very little to chart, because PoWA plots the difference between snapshots and a quiet machine produces nearly identical ones. The image includes a tool that creates a small powa_demo database and drives a real transactional workload against it. It forces a snapshot on each side of the workload, so you can see the whole pipeline work in about a minute.

Run sudo powa-demo-workload.sh to use the default 45-second workload, or pass a duration such as sudo powa-demo-workload.sh 90. When you have finished with it, run sudo powa-demo-workload.sh --drop to remove the demo database.

Reload the interface afterwards, and the charts show data.

7

Read the dashboards

Open the <local> server and you land on General Overview. This is the appliance's main view. It plots the following over the selected time range: query runtime and query rate per second, block access (split into shared buffer hits, operating system cache hits and real disk reads), global connection activity, parallel query usage and backend age.

Query runtime, block access and connection activity plotted over time. The spike is the demo workload from Step 6.

The tabs across the top switch between subject areas for the same time range: WALs, JIT, Background Writer / Checkpointer, Archiver / Replication, Database activity, Database Objects, User functions, System resources, SLRU and Wait Events. The time range control at the top right sets the range for every chart on the page.

8

Find the queries that cost the most

Choose a database from the breadcrumb at the top and scroll to Details for all queries. This is the ranked list that PoWA exists to produce. It lists every statement PoWA has seen, with call count, total and average execution time, blocks read, hit and dirtied, temporary block usage, input and output time, write-ahead log volume and JIT time.

Real statements ranked by what they actually cost, with the wait events they blocked on underneath.

Click any statement to open its own page, where the same metrics are plotted over time for that one query, alongside the predicates it filters on.

Below the query list, Wait events for all queries attributes lock and lightweight lock waits to the statements that suffered them. This is usually the fastest route to diagnosing contention rather than slowness.

At the bottom of the page, Index suggestions runs the wizard. It takes the predicates that pg_qualstats captured and proposes candidate indexes. It then uses hypopg to cost each candidate against the real planner without building it, so each suggestion arrives with an estimated gain attached. Click Optimize this database to run it.

9

Analyse your own database

To have PoWA analyse a database on this same instance, install the two extensions it needs in that database. Connect with sudo -u postgres psql -d <your-database>, then run CREATE EXTENSION pg_stat_statements; followed by CREATE EXTENSION hypopg;.

Both extensions are already present in template1, so any database you create on this appliance from now on inherits them automatically.

10

Attach a remote PostgreSQL server

The appliance analyses itself out of the box. To add servers of your own, PoWA runs in remote mode. You install the statistics extensions on the server being watched, and a collector on this appliance connects out to that server and writes the snapshots into this repository.

On the remote server, add powa to shared_preload_libraries alongside the other collection extensions, restart the server, and create the same extension set in a database there. Then register the server from the Configuration page of the interface, or from SQL on the appliance with SELECT powa_register_server(hostname => '<remote-host>', port => 5432, username => '<remote-role>', password => '<remote-password>');.

Finally, install and start the collector on the appliance with sudo apt-get install -y powa-collector, and configure it against the repository. The collector is packaged in the same PGDG repository that this image already trusts. Full details are in the PoWA remote setup documentation.

11

Tune retention and snapshot frequency

This image ships a deliberately generous policy: a snapshot every minute, seven days of retention and full predicate sampling. That policy suits an appliance analysing itself and a handful of servers. It is the first thing to relax when you attach a very busy server.

The relevant settings are powa.frequency, powa.retention and pg_qualstats.sample_rate, and they live in /etc/postgresql/18/main/conf.d/10-sac-powa.conf. Edit that file and reload PostgreSQL with sudo systemctl reload postgresql@18-main. The reload applies powa.frequency and pg_qualstats.sample_rate, and powa.retention also takes effect on reload.

Because the repository sits on its own volume, you have a second option: resize the data disk in the Azure Portal and grow the filesystem, rather than trading away history.

12

Reach PostgreSQL directly

PostgreSQL is bound to the loopback interface by design, because the repository holds the text of every query PoWA has seen. To use a local client, forward the port over SSH from your workstation with ssh -L 5432:127.0.0.1:5432 azureuser@<vm-public-ip>.

Then connect to 127.0.0.1:5432, database powa, as the powa_ui role with the password from Step 3.

Troubleshooting

The interface returns 502. powa-web is not running. Check it with sudo systemctl status powa-web.service. On a machine that has just started, first boot may still be in progress. The unit deliberately refuses to start until first boot has written /var/lib/sac/data/powa-bootstrap-ready.

The sign-in form comes back with "Auth failed". The credential is a PostgreSQL role, so this is a database authentication failure. Read /root/powa-credentials.txt again, and confirm that the Server field is set to main. To prove the shipped credential end to end, run sudo powa-cred-roundtrip.sh. It asserts a real login and an authenticated data request, and it checks that a deliberately wrong password is refused.

The interface reports a version mismatch. powa-web refuses to sign you in when its own version and the powa extension version differ in major or minor. This image ships them as a matched 5.2.0 pair. If you have upgraded one half, upgrade the other. The interface checks the extension version recorded in the database, so an upgraded package still requires ALTER EXTENSION powa UPDATE.

The charts are empty. PoWA plots the difference between snapshots, so it needs at least two of them across a period with activity. Confirm that snapshots are accumulating with the queries in Step 5, then generate activity as in Step 6. If powa_snapshot_metas is not growing at all, check that powa is still in shared_preload_libraries and that the background worker started.

First boot did not finish. Read its log with sudo journalctl -u powa-firstboot.service. The unit is a one-shot unit gated on /var/lib/sac/data/powa-firstboot.done, so it does not silently re-run over a partially configured machine.

Support

SecureAnyCloud publishes and supports this image. For deployment assistance, contact support through the SecureAnyCloud website.

PoWA is developed by the PoWA team and is distributed under the PostgreSQL licence. SecureAnyCloud is not affiliated with, sponsored by or endorsed by the PoWA team or the PostgreSQL Community Association. PostgreSQL and PoWA are used here only to identify the software this image contains.

Deploy on Azure

Launch PoWA on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure