Skip to content

HeliosProxy Integration Guide

HeliosProxy Integration Guide

How to integrate HeliosProxy into your application stack.


Quick Start

1. Build HeliosProxy

Terminal window
# Minimal build
cargo build --release -p heliosdb-proxy
# With connection pooling modes
cargo build --release -p heliosdb-proxy --features pool-modes
# Full feature build
cargo build --release -p heliosdb-proxy --features pool-modes,distribcache

2. Create Configuration

/etc/heliosproxy/config.toml
listen_address = "127.0.0.1:5433"
admin_address = "127.0.0.1:9090"
[pool_mode]
mode = "transaction"
max_pool_size = 100
[load_balancer]
read_write_split = true
read_strategy = "least_connections"
[[nodes]]
host = "127.0.0.1"
port = 5432
role = "primary"

3. Start the Proxy

Terminal window
heliosdb-proxy --config /etc/heliosproxy/config.toml

4. Connect Applications

Terminal window
# Connect via proxy instead of directly to database
psql -h localhost -p 5433 -U myuser -d mydb

Application Integration

Python (psycopg2/asyncpg)

# Before: Direct connection
conn = psycopg2.connect(
host="db.example.com",
port=5432,
database="mydb"
)
# After: Via HeliosProxy
conn = psycopg2.connect(
host="proxy.example.com",
port=5433, # Proxy port
database="mydb"
)

Node.js (pg)

// Before: Direct connection
const pool = new Pool({
host: 'db.example.com',
port: 5432,
database: 'mydb'
});
// After: Via HeliosProxy
const pool = new Pool({
host: 'proxy.example.com',
port: 5433, // Proxy port
database: 'mydb'
});

Java (JDBC)

// Before
String url = "jdbc:postgresql://db.example.com:5432/mydb";
// After
String url = "jdbc:postgresql://proxy.example.com:5433/mydb";

Go (pgx)

// Before
conn, err := pgx.Connect(ctx, "postgres://user:pass@db.example.com:5432/mydb")
// After
conn, err := pgx.Connect(ctx, "postgres://user:pass@proxy.example.com:5433/mydb")

Rust (tokio-postgres)

// Before
let (client, connection) = tokio_postgres::connect(
"host=db.example.com port=5432 dbname=mydb",
NoTls
).await?;
// After
let (client, connection) = tokio_postgres::connect(
"host=proxy.example.com port=5433 dbname=mydb",
NoTls
).await?;

Connection Pooling Best Practices

Choosing a Pool Mode

Use CaseRecommended ModeReason
Web applicationstransactionConnections returned after each request
MicroservicestransactionEfficient sharing between services
Background jobssessionLong-running operations
Prepared statementssessionStatements tied to connection
Simple SELECT queriesstatementMaximum connection efficiency

Transaction Mode Guidelines

When using mode = "transaction":

# Good: Transaction boundaries are clear
with conn.cursor() as cur:
cur.execute("BEGIN")
cur.execute("INSERT INTO orders VALUES (%s)", (order_id,))
cur.execute("COMMIT") # Connection returned to pool here
# Bad: Implicit transaction holds connection
with conn.cursor() as cur:
cur.execute("SELECT * FROM orders")
# Process results slowly...
# Connection held until next statement or disconnect

Statement Mode Guidelines

When using mode = "statement":

# Good: Simple, independent queries
results = []
for id in ids:
cur.execute("SELECT * FROM items WHERE id = %s", (id,))
results.append(cur.fetchone())
# Bad: Prepared statements won't work
cur.execute("PREPARE get_item AS SELECT * FROM items WHERE id = $1")
cur.execute("EXECUTE get_item(1)") # May fail - different connection

Query Routing with Hints

Use SQL comments to control routing:

-- Force to primary (for critical reads)
SELECT /* helios:route=primary */ balance FROM accounts WHERE id = 1;
-- Force to standby (for read replicas)
SELECT /* helios:route=standby */ * FROM analytics_data;
-- Skip cache (for real-time data)
SELECT /* helios:cache=skip */ * FROM live_metrics;
-- Multiple hints
SELECT /* helios:route=standby helios:cache=skip */ * FROM events;

Application Helper

def read_from_primary(query):
"""Execute query on primary node."""
return f"/* helios:route=primary */ {query}"
def read_from_replica(query):
"""Execute query on replica node."""
return f"/* helios:route=standby */ {query}"
# Usage
cur.execute(read_from_primary("SELECT balance FROM accounts WHERE id = %s"), (user_id,))

High Availability Setup

Multi-Node Configuration

listen_address = "0.0.0.0:5433"
admin_address = "0.0.0.0:9090"
[pool_mode]
mode = "transaction"
max_pool_size = 50
[load_balancer]
read_write_split = true
read_strategy = "least_connections"
[health]
check_interval_secs = 5
failure_threshold = 3
# Primary node
[[nodes]]
host = "db-primary.internal"
port = 5432
role = "primary"
# Sync standby for failover
[[nodes]]
host = "db-standby.internal"
port = 5432
role = "standby"
# Read replicas for scaling
[[nodes]]
host = "db-replica-1.internal"
port = 5432
role = "replica"
weight = 100
[[nodes]]
host = "db-replica-2.internal"
port = 5432
role = "replica"
weight = 100

Failover Behavior

  1. Primary fails: Writes queue until write_timeout_secs or new primary elected
  2. Standby promoted: Proxy detects new primary via health checks
  3. Replica fails: Traffic redistributed to remaining replicas
  4. All replicas fail: Reads fall back to primary

Kubernetes Deployment

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
name: heliosproxy-config
data:
config.toml: |
listen_address = "0.0.0.0:5433"
admin_address = "0.0.0.0:9090"
[pool_mode]
mode = "transaction"
max_pool_size = 100
[[nodes]]
host = "heliosdb-primary.default.svc.cluster.local"
port = 5432
role = "primary"
[[nodes]]
host = "heliosdb-standby.default.svc.cluster.local"
port = 5432
role = "standby"

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: heliosproxy
spec:
replicas: 2
selector:
matchLabels:
app: heliosproxy
template:
metadata:
labels:
app: heliosproxy
spec:
containers:
- name: heliosproxy
image: heliosdb/proxy:v1.0.0
ports:
- containerPort: 5433
name: postgres
- containerPort: 9090
name: admin
volumeMounts:
- name: config
mountPath: /etc/heliosproxy
livenessProbe:
httpGet:
path: /health
port: admin
initialDelaySeconds: 5
readinessProbe:
httpGet:
path: /health
port: admin
initialDelaySeconds: 2
volumes:
- name: config
configMap:
name: heliosproxy-config

Service

apiVersion: v1
kind: Service
metadata:
name: heliosproxy
spec:
selector:
app: heliosproxy
ports:
- name: postgres
port: 5433
targetPort: 5433
- name: admin
port: 9090
targetPort: 9090

Docker Compose

version: '3.8'
services:
heliosproxy:
image: heliosdb/proxy:v1.0.0
ports:
- "5433:5433"
- "9090:9090"
volumes:
- ./config.toml:/etc/heliosproxy/config.toml:ro
depends_on:
- heliosdb-primary
- heliosdb-standby
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
interval: 5s
timeout: 3s
retries: 3
heliosdb-primary:
image: heliosdb/heliosdb-lite:latest
ports:
- "5432:5432"
environment:
- HELIOS_ROLE=primary
heliosdb-standby:
image: heliosdb/heliosdb-lite:latest
environment:
- HELIOS_ROLE=standby
- HELIOS_PRIMARY_HOST=heliosdb-primary

Monitoring

Prometheus Metrics

HeliosProxy exposes metrics at /metrics:

# Connection pool metrics
heliosproxy_pool_connections_total{node="primary"} 50
heliosproxy_pool_connections_active{node="primary"} 12
heliosproxy_pool_connections_idle{node="primary"} 38
heliosproxy_pool_acquire_duration_seconds_bucket{le="0.001"} 9500
heliosproxy_pool_acquire_duration_seconds_bucket{le="0.01"} 9900
heliosproxy_pool_acquire_duration_seconds_bucket{le="0.1"} 10000
# Query metrics
heliosproxy_queries_total{type="read"} 150000
heliosproxy_queries_total{type="write"} 25000
heliosproxy_query_duration_seconds_bucket{le="0.001"} 100000
heliosproxy_query_duration_seconds_bucket{le="0.01"} 145000
# Health metrics
heliosproxy_node_healthy{node="primary"} 1
heliosproxy_node_healthy{node="standby"} 1
heliosproxy_node_latency_seconds{node="primary"} 0.0005

Grafana Dashboard

Import the HeliosProxy dashboard from docs/monitoring/grafana-dashboard.json.


Troubleshooting

Connection Issues

Terminal window
# Check proxy health
curl http://localhost:9090/health
# Check pool stats
curl http://localhost:9090/pool/stats
# Check node status
curl http://localhost:9090/nodes

Pool Exhaustion

Symptoms: connection acquire timeout errors

Solutions:

  1. Increase max_pool_size
  2. Switch to transaction or statement mode
  3. Reduce application connection hold time
  4. Scale horizontally with multiple proxy instances

Query Routing Issues

Terminal window
# Enable debug logging
RUST_LOG=heliosdb_proxy=debug heliosdb-proxy --config config.toml
# Check routing decisions in logs
# [DEBUG] Routing query to node=primary reason=write_query
# [DEBUG] Routing query to node=replica-1 reason=read_query

See Also