Skip to content
Docs / dflux EdgeGuard
ContactGet started

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

text

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 required
v1 refuses to start if 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:

YAML

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:

Bash

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, and DELETE on 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:

Bash
YAML

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:

YAML

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