A high-performance MariaDB and PostgreSQL proxy with caching, read replica, metrics, and transaction support.
Blog post: https://www.tqdev.com/2026-tqdbproxy-mariadb-postgresql-proxy/
- Query Caching: Cache SELECT queries with configurable TTL and thundering herd protection
- Caller Metadata: Track queries by source file and line number
- Metrics: Prometheus metrics for cache hits/misses, query latency, and more
- Read Replica Support: Automatic routing of SELECT queries to replicas
- Transaction Support: Full BEGIN/COMMIT/ROLLBACK support
- Interactive Mode: Full interactive client support
Cache hits are as fast as empty queries with 100 connections. Proxy overhead is minimal for queries ≥1ms.
# Start the proxy
./tqdbproxy
# Connect via MariaDB client (interactive mode)
mariadb -u tqdbproxy -p -P 3307 tqdbproxy --commentsAdd caller metadata to your queries for better observability:
/* ttl:60 file:app.php line:42 */ SELECT * FROM users WHERE active = 1NB: When using the MariaDB CLI, you must use the --comments flag to preserve metadata comments
Full transaction support with proper isolation:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;All query types supported:
- SELECT queries (with optional caching)
- INSERT queries (returns last insert ID)
- UPDATE queries (returns affected rows)
- DELETE queries (returns affected rows)
Check which backend served the last query:
MariaDB:
mariadb> SHOW TQDB STATUS;
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Backend | primary |
| Cache_hit | 0 |
+---------------+---------+PostgreSQL:
tqdbproxy=> SELECT * FROM pg_tqdb_status;
variable_name | value
---------------+---------
Backend | primary
Cache_hit | 0
(2 rows)Values: Backend = primary, replicaN, cache, or none (no query yet); Cache_hit = 0 or 1.
This is useful for debugging cache behavior during development.
Configure replicas in config.ini:
[mariadb]
listen = :3307
primary = 127.0.0.1:3306
replica1 = 127.0.0.2:3306
replica2 = 127.0.0.3:3306Select queries with a TTL hint are round-robin distributed across replicas.
The proxy implements single-flight for warmup and resfresh to prevent concurrent DB queries for the same key.
Access Prometheus metrics at http://localhost:9090/metrics:
curl http://localhost:9090/metrics | grep tqdbproxy_query_totalMetrics include file and line labels when metadata comments are used.
DNS round-robin load balancing can be used to distribute queries across multiple proxies.
See docs/README.md for more information.
