Start
This guide starts PgPaw against an existing Postgres database.
Before you start
You need:
- Postgres 13 or newer;
-
a user that can run the one-time setup in
pgpaw init; - the
pgpawbinary installed; -
a table you can safely query, such as
usersororders.
1. Prepare upstream Postgres
Run pgpaw init once for the database:
pgpaw init \
--pg-host 127.0.0.1 \
--pg-port 5432 \
--pg-user postgres \
--pg-password "$POSTGRES_PASSWORD" \
--pg-database myapp
The command explains what it will change and asks for confirmation. It checks or creates:
wal_level=logical;max_wal_senders >= 10;max_replication_slots >= 10;- publication
pgpaw_pub; - a DDL event trigger, when permissions allow it.
If PgPaw changes WAL settings, restart Postgres before starting
pgpaw serve. init prints this when a
restart is required.
2. Start PgPaw
pgpaw serve \
--host 127.0.0.1 \
--port 8080 \
--data-dir ./pgpaw-data \
--pg-host 127.0.0.1 \
--pg-port 5432 \
--pg-user postgres \
--pg-password "$POSTGRES_PASSWORD" \
--pg-database myapp
Watch for the readiness log:
level=INFO target=pgpaw::http::server event=http_server_listening bind_addr=127.0.0.1:8080 url=http://127.0.0.1:8080
Check health:
curl http://127.0.0.1:8080/healthz
Healthy response:
{ "status": "ok", "watermark": 12345678 }
3. Run a public snapshot query
curl -i -X POST http://127.0.0.1:8080/query \
-H "content-type: application/json" \
-d '{"sql":"select id, email from users where id = 7"}'
If the touched tables are public, PgPaw returns a cursor:
HTTP/1.1 303 See Other
Location: /q/{hash}/{version}
Cache-Control: no-store
Fetch the snapshot:
curl http://127.0.0.1:8080/q/{hash}/{version}
Snapshot response:
[{ "id": 7, "email": "ada@example.com" }]
4. Open a live stream
curl -N -X POST "http://127.0.0.1:8080/query?live=true" \
-H "content-type: application/json" \
-d '{"sql":"select id, status from orders order by id"}'
The first event is a snapshot pointer for public queries:
data: {"type":"snapshot","url":"/q/{hash}/{version}","version":42}
Then PgPaw sends row changes after relevant upstream commits:
data: {"op":"update","key":"7","row":{"id":7,"status":"paid"},"txid":124}
data: {"op":"up-to-date","txid":124}
5. Next steps
- Use Authorization for RLS-protected tables.
- Use Cache-Control to understand public vs private caching.
- Use Configuration for production flags.
- Use Logging to understand startup, health, query, cache, and CDC output.
