Predixy
Predixy is a high-performance Redis
protocol proxy. pgcli runs it as a standalone, top-level addon whose job is
to take a Redis native cluster — 3+ nodes, 16384
slots, MOVED redirects — and hand it back to your applications as one plain
redis:// endpoint. Clients do not need to be cluster-aware: no -c, no
redirect handling, just connect and run commands.
Platform support: like HAProxy and Redis, the Predixy addon needs Linux host networking to dial its backend nodes; it is not supported on macOS.
How It Works
Predixy speaks the Redis protocol on its client port and keeps persistent
connections to every cluster node listed in --backend. A client request is
routed by slot: if the node it lands on does not own the key’s slot, Predixy
follows the MOVED itself and re-issues the command on the right node —
transparently, in-proxy. The client never sees a redirect.
pgcli renders one config file per instance,
<base-dir>/addon/predixy/<name>/predixy.conf, and bind-mounts it
(file-level, read-only) over the image’s baked-in
/usr/local/predixy/conf/predixy.conf. The rendered file’s
Include license.conf resolves relative to that directory, so the image’s
signed license sibling stays visible — pgcli never ships or manages a license
(see Known limitations).
One password, two sides
The proxy sits between two authenticated parties — its own clients and the cluster behind it — and pgcli uses one password for both:
Authority { Auth "<pw>" { Mode admin } }— clients mustAUTHthis password to use the proxy;ClusterServerPool { Password "<pw>" }— Predixy authenticates to the cluster nodes with it.
That works because the password is the proxied cluster’s own requirepass:
clients already know it, the nodes already accept it. Read it straight out of
the redis addon:
A single cluster-member password therefore gates the proxy endpoint too — no second secret to keep in sync. (If you want a separate client-facing password, that is a different Authority design pgcli does not render; see Known limitations.)
Install
--backend and --password are both required. --backend is the cluster’s
full node list — pgcli never derives it from local redis addons, because the
cluster being fronted often lives on other hosts; you know its topology, so you
list it. Repeat the flag or comma-separate one run; duplicates are rejected.
The summary prints the one endpoint clients should be pointed at:
Guards run before anything is pulled or created: a missing --backend, a
malformed entry (no port, non-numeric or out-of-range port, empty entry), a
duplicate node, a missing --password, a password containing " or a newline
(Predixy’s quoted-string syntax has no escape for them), or --workers < 1 all
fail fast with a clear message.
Re-running install is idempotent as elsewhere: a running container is left
alone (config rewritten), a stopped one is started, and --force recreates it
so a changed port/listen/password/backend set takes effect. The backend list is
replaced wholesale each time, so growing the cluster (install more redis
members, --cluster add-node, …) is followed by re-running the same install
with the updated full list.
Workers
--workers N sets Predixy’s WorkerThreads (default 1). Each worker is a
busy-poll event thread; on a multi-core host dedicated to proxying, N ≈ the
number of cores you are willing to spend scales throughput roughly linearly.
Using the proxy
Any Redis client connects to the proxy’s port with the cluster’s password and behaves as if it were talking to a single standalone Redis — the whole keyspace is served through the one endpoint:
(DSN shape: redis://:<password>@<listen>:<port>/0.)
With pg redis-cli
pg redis-cli reaches the proxy through --host/--port — there is no
--name path to a Predixy instance (--name resolves redis addons only):
With a local redis addon configured, its image and password are reused (see
redis.md — pg redis-cli). If that addon happens to be
a cluster member, pg redis-cli injects its -c as usual — harmless through the
proxy, because the proxy absorbs every MOVED before the client could see one.
That is the point of the proxy: the same plain-client commands work whether or
not -c is in play.
Cross-host
Verified end-to-end: a proxy on one host fronting a three-host cluster
(--backend 10.10.0.15x:6379,…), with plain cluster-unaware clients connecting
from a different host through it — SET whose slot belongs to a remote node
is absorbed and applied, and reads back from that node’s own port. The only
requirement is reachability: the proxy host must be able to dial every
--backend node’s client port (the cluster bus ports are between the members,
not the proxy).
Ports
Each instance takes one port from Predixy’s own pool, predixy_start_port
(default 7617, the port the image EXPOSEs) — separate from Redis’s
redis_start_port pool, so a proxy and the cluster it fronts never collide.
--port pins an instance; auto-assignment skips what is already taken.
The bind address defaults to 0.0.0.0 (the AUTH password is the only gate);
--listen 127.0.0.1 tightens it to loopback.
Configuration
Instances live under the top-level addons.predixy map in pg.yaml:
The rendered predixy.conf carries the same information in Predixy’s own
syntax; hand-editing it is wiped by the next install — edit pg.yaml (or the
flags) and re-install instead.
List
pg addon list redacts the password; --show-password reveals it, and
pg addon password predixy --name proxy prints just that value bare for
scripting.
Start and stop
start only starts an existing container (self-healing an improper state by
recreating it from the rendered config on disk); it errors if that file is
missing — re-run install to regenerate it.
Auto-start on Boot
Boot is start-only (install first), and the boot service starts Predixy after Redis, so the proxied members are already coming up when the proxy dials them. See Auto-start on Boot.
Remove
Stops and removes the container, deletes the rendered config directory, and
drops the pg.yaml entry. The proxied cluster is untouched — the proxy is
merely a consumer of it.
Logs
The startup banner reports the effective build (Workers:2, …) — the place to
confirm --workers landed.
Known limitations
- One admin Authority user — the renderer emits a single
Auth "<pw>" { Mode admin }: every client of the proxy shares one password with full access. Per-user auth, read-only users, and keyspace restrictions are not rendered (Predixy itself supports more; pgcli’s surface stops here). - Cluster pools only —
ClusterServerPoolis the only backend type; Sentinel or standalone pools are not configured. - License lives in the image — the free-edition license baked into
ghcr.io/mars-base/pgcli/predixy:7.0.1-alpinecaps clients atClientLimit 128and expires 2026-12-31; pgcli never ships or rotates it — the image build does. When it expires, rebuild the image (the Makefile target already swaps in the current license). - No TLS on the client side in this addon (password-only gate; keep
listenloopback or a trusted network, as with Redis itself). - Linux only — host networking is required to dial the backends; macOS is not supported (fails fast).
Troubleshooting
ERR invalid passwordfrom clients — the client mustAUTHthe one password; check it againstpg addon password predixy --name proxy(it should equal the cluster’s,pg addon password redis --name n1).- Container exits at once — Predixy rejects its config on the spot: a lone
{on its own line, or a password with a"/newline that broke quoting. pgcli validates both before writing, so this points at a hand-editedpredixy.conf— re-install. - Commands hang or every key errors — a backend node is unreachable from
the proxy host (wrong address, firewalled).
pg logs addon predixyshows the dial failures;--backendmust list nodes this host can dial. - Stale backend list after cluster changes — install replaces the list wholesale; re-run it with the current full node set after adding or removing members.