GERYON
Three Bodies. One Proxy. Every Connection.
A high-performance, multi-database connection pooler and proxy built in pure Go with zero external dependencies. Named after the three-bodied giant of Greek mythology, Geryon speaks PostgreSQL, MySQL, and MSSQL wire protocols — all from a single static binary.
Running PostgreSQL, MySQL, and MSSQL? Today you need separate tools for each:
| Problem | Existing Solution | Limitation |
|---|---|---|
| PostgreSQL pooling | PgBouncer | C, limited observability, no clustering |
| MySQL pooling | ProxySQL | C++, complex configuration |
| MSSQL pooling | (nothing) | Driver-level pooling only |
Three tools. Three configs. Three monitoring setups. Three failure modes.
Geryon replaces all of them with one binary.
| Body | Protocol | Wire Format | Auth Methods |
|---|---|---|---|
| I — PostgreSQL | v3 Frontend/Backend | Extended Query, COPY, LISTEN/NOTIFY | SCRAM-SHA-256, MD5, trust, cert |
| II — MySQL | Handshake v10 | COM_QUERY, COM_STMT_*, COM_CHANGE_USER | mysql_native_password, caching_sha2, sha256 |
| III — MSSQL | TDS 7.4+ | SQL Batch, RPC, Bulk Load | SQL Auth, NTLM passthrough |
| Mode | Multiplexing | Best For |
|---|---|---|
| Session | 1:1 | Temp tables, SET vars, LISTEN/NOTIFY |
| Transaction | N:M | Web apps, microservices (default) |
| Statement | N:1 | Simple query patterns, max throughput |
- Prepared Statement Cache — Transparent re-preparation across pooled connections with LRU eviction
- Query Result Cache — In-memory LRU cache with TTL, write invalidation, and per-pattern rules
- Read/Write Splitting — Route SELECTs to replicas, writes to primary, transaction-aware
- Auth Interception — Manage proxy users, map N clients to M backend credentials
- TLS/mTLS — Full TLS termination with mutual TLS client certificate validation
- Hot Reload — Config changes via YAML watch, SIGHUP, or API — zero downtime
| Interface | Description | Port |
|---|---|---|
| REST API | Full CRUD for pools, connections, backends, users, cache | :8080 |
| Web Dashboard | Real-time monitoring with SSE streaming, config editor | :8080 |
| MCP Server | LLM-native management (Claude Code / Claude Desktop) | :8081 |
| gRPC API | Programmatic integration with streaming stats | :9090 |
- Raft Consensus — Configuration replication and leader election across nodes
- SWIM Gossip — Node discovery, failure detection, metadata dissemination
- Backend Health Sharing — Avoid thundering herd on failover
# Download latest release
curl -sSL https://github.com/GeryonProxy/geryon/releases/latest/download/geryon-linux-amd64 -o geryon
chmod +x geryon
# Generate example config
./geryon --generate-config > geryon.yaml
# Edit config (set your database backends)
vim geryon.yaml
# Start
./geryon --config geryon.yamldocker run -d \
--name geryon \
-p 5432:5432 \
-p 3306:3306 \
-p 1433:1433 \
-p 8080:8080 \
-v ./geryon.yaml:/etc/geryon/geryon.yaml \
ghcr.io/geryonproxy/geryon:latestservices:
geryon:
image: ghcr.io/geryonproxy/geryon:latest
ports:
- "5432:5432" # PostgreSQL
- "3306:3306" # MySQL
- "1433:1433" # MSSQL
- "8080:8080" # Dashboard + REST API
volumes:
- ./geryon.yaml:/etc/geryon/geryon.yaml
restart: unless-stoppedgit clone https://github.com/GeryonProxy/geryon.git
cd geryon
make build
# Binary at bin/geryonpools:
- name: "my-postgres"
body: postgresql
mode: transaction
listen:
host: "0.0.0.0"
port: 5432
backend:
hosts:
- host: "pg.internal"
port: 5432
database: "myapp"
auth:
username: "postgres"
password_file: "/etc/geryon/secrets/pg"
limits:
max_client_connections: 10000
max_server_connections: 100
admin:
rest:
listen: "0.0.0.0:8080"
dashboard:
enabled: truepools:
- name: "primary-pg"
body: postgresql
mode: transaction
listen:
host: "0.0.0.0"
port: 5432
backend:
hosts:
- host: "pg-primary.internal"
port: 5432
role: primary
- host: "pg-replica.internal"
port: 5432
role: replica
database: "myapp"
auth:
method: scram-sha-256
username: "geryon_pool"
password_file: "/etc/geryon/secrets/pg-password"
limits:
max_client_connections: 10000
max_server_connections: 100
- name: "analytics-mysql"
body: mysql
mode: session
listen:
host: "0.0.0.0"
port: 3306
backend:
hosts:
- host: "mysql-primary.internal"
port: 3306
database: "analytics"
auth:
method: caching_sha2_password
username: "geryon_pool"
password_file: "/etc/geryon/secrets/mysql-password"
- name: "reporting-mssql"
body: mssql
mode: transaction
listen:
host: "0.0.0.0"
port: 1433
backend:
hosts:
- host: "mssql.internal"
port: 1433
database: "reporting"
auth:
username: "geryon_pool"
password_file: "/etc/geryon/secrets/mssql-password"
routing:
read_write_split: true
admin:
rest:
listen: "0.0.0.0:8080"
dashboard:
enabled: true
mcp:
transport: sse
listen: "0.0.0.0:8081"Connect your application to Geryon instead of directly to the database:
# PostgreSQL
psql -h localhost -p 5432 -U app -d myapp
# MySQL
mysql -h 127.0.0.1 -P 3306 -u app -p analytics
# MSSQL
sqlcmd -S localhost,1433 -U app -d reporting ┌─────────────────────────────────────────────────┐
│ GERYON PROXY │
│ │
Clients ────────► │ ┌───────────┐ ┌──────────┐ ┌─────────────┐ │
(PG/MySQL/TDS) │ │ BODY I │ │ BODY II │ │ BODY III │ │
│ │PostgreSQL │ │ MySQL │ │ MSSQL │ │
│ │ :5432 │ │ :3306 │ │ :1433 │ │
│ └─────┬─────┘ └────┬─────┘ └──────┬──────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────┐│
│ │ UNIFIED POOL MANAGER ││
│ │ Session │ Transaction │ Statement ││
│ │ Prepared Stmt Cache │ Query Result Cache ││
│ └──────────────────┬──────────────────────────┘│
│ │ │
│ ┌──────────────────┴──────────────────────────┐│
│ │ BACKEND CONNECTORS ││
│ │ R/W Split │ Health Check │ Failover ││
│ └─────────────────────────────────────────────┘│
└─────────────────────────────────────────────────┘
Cluster: N1 (Leader) ◄─── Raft + SWIM ───► N2, N3 (Followers)
Access the web dashboard at http://localhost:8080 after starting Geryon:
| Page | Description |
|---|---|
| Overview | Total connections, queries/sec, cache hit rate, cluster health |
| Pools | Per-pool connection counts, wait queue, avg query time |
| Backends | Server status (up/down/degraded), latency, connection count |
| Connections | Live table: client IP, pool, state, duration, current query |
| Query Stats | Top queries by time/frequency, slow query log |
| Cache | Hit/miss rate graph, memory usage, top cached queries |
| Cluster | Node map, Raft state, leader indicator, gossip health |
| Config | Live editor with validation + hot-reload |
Built with vanilla HTML/CSS/JS — no npm, no bundler, embedded in the binary via embed.FS.
geryon # Start with geryon.yaml in current dir
geryon --config /path/to/config # Start with specific config
geryon --validate # Validate config without starting
geryon --version # Print version info
geryon --generate-config # Output example config to stdout
geryon --generate-password # Generate SCRAM-SHA-256 hash
geryon --generate-cert # Generate self-signed TLS certThe REST API provides full management capabilities. Default endpoint: http://localhost:8080
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/pools |
List all pools |
POST |
/api/v1/pools |
Create new pool |
GET |
/api/v1/pools/{name} |
Get pool details |
PUT |
/api/v1/pools/{name} |
Update pool (TODO) |
DELETE |
/api/v1/pools/{name} |
Delete pool |
Create Pool Example:
curl -X POST http://localhost:8080/api/v1/pools \
-H "Content-Type: application/json" \
-d '{
"name": "new-pool",
"body": "postgresql",
"mode": "transaction",
"listen": {"host": "0.0.0.0", "port": 5433},
"backend": {
"hosts": [{"host": "db.internal", "port": 5432, "role": "primary"}],
"database": "myapp"
},
"limits": {
"max_client_connections": 1000,
"max_server_connections": 100
}
}'| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/backends |
List all backends |
POST |
/api/v1/backends/{address}/drain |
Start draining backend |
POST |
/api/v1/backends/{address}/cancel-drain |
Cancel draining |
Drain Backend Example:
curl -X POST http://localhost:8080/api/v1/backends/db.internal:5432/drain| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/connections |
List active connections |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/queries |
Query statistics |
GET |
/api/v1/queries/slow |
Slow query list |
GET |
/api/v1/queries/recent |
Recent queries |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/transactions |
Transaction stats |
GET |
/api/v1/transactions/active |
Active transactions |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/stats |
Global statistics |
GET |
/api/v1/stats/stream |
SSE streaming stats |
GET |
/metrics |
Prometheus metrics |
SSE Stats Stream:
curl -N http://localhost:8080/api/v1/stats/stream
# Returns: data: {"total_connections":42,"active_pools":3,...}| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/config |
View current config |
POST |
/api/v1/config/reload |
Reload configuration |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/tls/status |
TLS status per pool |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/v1/health |
Health check |
GET |
/api/v1/ready |
Readiness probe |
Geryon includes a built-in MCP server for AI-assisted database management, compatible with Claude Code, Claude Desktop, and other MCP clients.
Tools: geryon_pool_list, geryon_pool_stats, geryon_connection_list, geryon_connection_kill, geryon_backend_status, geryon_backend_detach, geryon_backend_attach, geryon_cache_stats, geryon_cache_invalidate, geryon_cluster_status, geryon_config_reload, geryon_query_stats, geryon_user_manage
Resources: geryon://config, geryon://pools/{name}, geryon://stats/overview, geryon://cluster/topology
| Metric | Target |
|---|---|
| Max client connections | 100,000+ per node |
| Connection setup latency | < 1ms |
| Query proxy overhead | < 100μs |
| Memory per idle connection | < 8KB |
| Config reload | < 100ms, zero downtime |
| Binary size | < 30MB |
| Startup time | < 2s |
| Platform | Status |
|---|---|
| Linux (amd64, arm64) | Primary |
| macOS (amd64, arm64) | Supported |
| Windows (amd64) | Supported |
| Container (GHCR) | ghcr.io/geryonproxy/geryon |
#NOFORKANYMORE — Geryon is built with a strict zero-dependency philosophy:
- Pure Go — stdlib only,
go.sumis empty - Single Binary — one file, runs anywhere Go compiles
- Zero CGo — fully static, cross-compile to any platform
- No Vendor — no dependency management, no supply chain risk
git clone https://github.com/GeryonProxy/geryon.git
cd geryon
make build # Build binary
make test # Run tests
make lint # Run go vetApache 2.0 — See LICENSE for details.
Built by ECOSTACK TECHNOLOGY OÜ
Geryon (Γηρυών) — the three-bodied giant, guardian of the red cattle of Erytheia. Defeating Geryon was the 10th of Heracles' twelve labors — one entity with three bodies, each a formidable force on its own.