Using PostgreSQL
dflux EdgeGuard keeps its runtime state in a single control-plane store, which defaults to SQLite. PostgreSQL is the right choice when that state must outlive the proxy host, or when several instances need to share it. This guide covers the DSN format, the required sslmode, and how to point the store at Postgres.
When to use PostgreSQL
The proxy has exactly one persistent store: the control-plane store. It holds policy rules, transformation rules, routing rules, producer configs, and NRF profiles — everything the admin API mutates and the request pipeline reads when it rebuilds. By default this store is SQLite, which is fine for a single instance.
Switch the control-plane store to PostgreSQL when:
- the runtime state must survive a rebuild or replacement of the proxy host, or
- two or more proxy instances need to share the same rules — see multi-instance deployments below.
DSN format
The DSN is a standard libpq connection URL. Beyond sslmode (which the proxy requires — see below), the usual libpq query parameters such as connect_timeout, application_name, and search_path are passed through unchanged.
sslmode is missing from a Postgres DSN. Use
verify-full in production. sslmode=disable is permitted but logs
a warning — accept that you are then sending credentials and signaling metadata in clear
over your DB network.Pointing the control-plane store at Postgres
Set the driver and DSN under storage.control_plane_db:
The {'${VAR:?msg}'} form interpolates an environment variable and fails startup with msg if it is unset, which keeps the credential out of the config file. {'${VAR:-default}'} is also supported for non-required values.
You can set the same two values from the CLI instead of the config file:
Provisioning
The proxy creates its own tables and indexes on first connect. You need to provide:
- A database.
- A role with
CREATE,SELECT,INSERT,UPDATE, andDELETEon that database. - TLS material on both sides for
verify-full— the server cert, plus the CA bundle in the proxy host's trust store.
Lab-grade Postgres for testing:
Connection pooling
The proxy opens a small connection pool to Postgres; it does not need many, because control-plane mutations are infrequent and the request pipeline reads from an in-memory snapshot rather than hitting the DB per request. For production, sit Postgres behind PgBouncer or your cloud provider's pooler to bound the maximum connection count.
Multi-instance deployments
When two or more proxy instances share a Postgres control-plane store, each one picks up the other's mutations by polling the store on an interval (process.store_watch_interval, default 5s). A policy change applied to one instance reaches the others within the poll window.
NRF profile registration stays per-instance — each instance advertises its own listen address — but the profile definitions are shared through the control-plane store.
Debugging slow queries
Turn on per-query logging when you suspect the DB is the bottleneck:
Or set the matching flag at startup: d3x-edge -db-query-log …. Combine it with d3x-edgectl log-level set debug for runtime control of the log level.
Backups
The control-plane store is small — rules, routes, producer configs, and NRF profiles. Back it up at the DB level alongside the rest of your Postgres; restoring is fast.
Where to go next
- Deploying dflux EdgeGuard — file layout and the systemd unit.
- Config schema — the full
storageblock and every other config key.