Web UI and REST API for ProxySQL.
Code-generated from the ProxySQL source. Zero build step.
Table browser, SQL console, config sync, live stats.
Everything you need to manage ProxySQL — in the browser.
Browse all 99 ProxySQL tables. Full CRUD for config tables. Resizable columns, inline editing, per-column filters, sortable headers. Empty tables greyed out.
CodeMirror editor with syntax highlighting and fuzzy tab completion. Query any target — admin, proxy port, MySQL/PostgreSQL backends. Schema tree sidebar.
Three-layer diff: Memory ↔ Runtime ↔ Disk. Git-style inline diffs with + ~ − indicators. Apply, Save, Discard — one click.
Real-time charts: connections, QPS, connection pool, memory. Command counters and top query digests. 5-second polling, 10-minute rolling window.
Login with ProxySQL admin credentials. Server-side sessions — no passwords in cookies. Audit logging for queries and config changes.
The entire API is generated from ProxySQL's C header file. Re-run the generator after a ProxySQL update to stay in sync. 163 Pydantic models, 282 routes.
Dark theme, monospace everything, zero build tooling.
Code generation from C headers → FastAPI → Alpine.js SPA.
gen_fastapi_models.py reads ProxySQL's ProxySQL_Admin_Tables_Definitions.h — resolves #define alias chains, extracts every CREATE TABLE, parses columns, types, PKs, defaults, CHECK constraints.
Produces 5 files: Pydantic models, CRUD router (GET/POST/PUT/DELETE per table), table metadata, connection pool, and the FastAPI app with config sync, query engine, schema browser.
Talks to ProxySQL's admin port (6032) using aiomysql. No C++ linkage needed. Auto-discovers proxy ports, backend servers, and credentials from ProxySQL's own state.
Alpine.js + Pico CSS SPA served as static files. No npm, no webpack, no build step. CodeMirror for SQL editing, uPlot for charts. Everything from CDN.
┌──────────────┐ ┌────────────────┐ ┌────────────────┐
│ Browser │─────▶│ proxui :8080 │─────▶│ ProxySQL :6032 │
│ Alpine.js │ REST │ FastAPI │ MySQL │ admin iface │
└──────────────┘ └────────────────┘ └────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌────────────┐ ┌────────────┐
│ MySQL │ │ PostgreSQL │
│ backends │ │ backends │
└────────────┘ └────────────┘
ProxySQL's three-layer configuration model, visualized.
DISK ←── Save ─── MEMORY ─── Apply ──→ RUNTIME
↑ │
└─────── Discard ───────┘
Toggle the Diff view to see memory vs runtime side-by-side. Changed columns are bold. Git-style indicators: + new, ~ changed, − deleted.
Apply pushes memory → runtime. Save persists to disk. Discard reverts memory to match runtime. Buttons light up only when there's a difference.
Shows "Unapplied changes" or "Unsaved to disk" with clickable pills to jump to the affected table. Disappears when everything is in sync.
Designed for internal admin use, not public internet exposure.
Cookie contains only an HMAC-signed session ID. Credentials stored in memory on the server, never sent to the client.
UI served same-origin. No cross-origin access. No CSRF via CORS+credentials vector.
Every login, SQL query, and config action logged with username. Queries truncated to 200 chars in logs.
Connection pools destroyed on logout. Sessions invalidated on server restart (secret regenerates).
# Clone and set up
git clone https://github.com/artw/proxui
cd proxui
just all # venv + deps + generate from C header
# Test bench (needs podman)
just bench-up # MySQL 8.4 + PostgreSQL 17 + ProxySQL 3.0
just bench-run # build + run proxui on same network
# Open in browser
open http://localhost:8080 # login: radmin / radmin
# Point at your own ProxySQL
PROXYSQL_ADMIN_HOST=10.0.0.1 \
PROXYSQL_ADMIN_PORT=6032 \
just run