PostgreSQL Wire Protocol
Zatabase implements the PostgreSQL wire protocol (v3.0), allowing you to connect using any standard PostgreSQL client or driver. This means existing tools, ORMs, and database GUIs that support PostgreSQL can work with Zatabase with zero code changes.
Connection Setup
Section titled “Connection Setup”Connect to Zatabase using your project endpoint. The SDK handles routing automatically — no port configuration needed.
# Connect with psqlConnection Parameters
Section titled “Connection Parameters”| Parameter | Default | Description |
|---|---|---|
| Host | your-project.zatabase.io | Your project endpoint |
| User | (required) | Your Zatabase username (email) |
| Database | zatabase | Database name (maps to Zatabase organization) |
Authentication
Section titled “Authentication”Zatabase supports SCRAM-SHA-256 authentication over the wire protocol, the same mechanism used by modern PostgreSQL servers. This provides secure password exchange without transmitting the password in cleartext.
# psql will prompt for passwordConnection String Format
Section titled “Connection String Format”Standard PostgreSQL connection string syntax is supported:
postgresql://[email protected]:[email protected]/zatabaseOr the key-value format:
host=your-project.zatabase.io [email protected] password=SecurePass123! dbname=zatabaseSupported SQL
Section titled “Supported SQL”The wire protocol supports the same SQL subset as the HTTP API. See the SQL Reference for complete syntax:
-- DDLCREATE TABLE products (name TEXT, price FLOAT, quantity INTEGER);DROP TABLE products;
-- DMLINSERT INTO products (name, price, quantity) VALUES ('Widget', 9.99, 100);SELECT * FROM products WHERE price > 5.0 ORDER BY name LIMIT 10;DELETE FROM products WHERE name = 'Widget';
-- Vector operationsCREATE TABLE docs (title TEXT, embedding VECTOR(384));SELECT * FROM docs ORDER BY embedding <-> ARRAY[0.1, 0.2, ...] LIMIT 5;Driver Compatibility
Section titled “Driver Compatibility”Zatabase’s wire protocol has been tested with the following PostgreSQL client libraries:
psql (Interactive CLI)
Section titled “psql (Interactive CLI)”
zatabase=# CREATE TABLE test (id INTEGER, name TEXT);CREATE TABLEzatabase=# INSERT INTO test (id, name) VALUES (1, 'Alice');INSERT 0 1zatabase=# SELECT * FROM test; id | name----+------- 1 | Alice(1 row)Rust: tokio-postgres
Section titled “Rust: tokio-postgres”use tokio_postgres::NoTls;
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let (client, connection) = tokio_postgres::connect( NoTls, ).await?;
tokio::spawn(async move { if let Err(e) = connection.await { eprintln!("connection error: {}", e); } });
// Create table client.execute( "CREATE TABLE users (name TEXT, age INTEGER)", &[], ).await?;
// Insert client.execute( "INSERT INTO users (name, age) VALUES ($1, $2)", &[&"Alice", &30_i32], ).await?;
// Query let rows = client.query( "SELECT name, age FROM users WHERE name = $1", &[&"Alice"], ).await?;
for row in &rows { let name: &str = row.get(0); let age: i32 = row.get(1); println!("{}: {}", name, age); }
Ok(())}Rust: sqlx
Section titled “Rust: sqlx”use sqlx::postgres::PgPoolOptions;
#[tokio::main]async fn main() -> Result<(), sqlx::Error> { let pool = PgPoolOptions::new() .max_connections(5) .await?;
sqlx::query("CREATE TABLE items (name TEXT, price FLOAT)") .execute(&pool) .await?;
sqlx::query("INSERT INTO items (name, price) VALUES ($1, $2)") .bind("Widget") .bind(9.99_f64) .execute(&pool) .await?;
let rows = sqlx::query_as::<_, (String, f64)>( "SELECT name, price FROM items WHERE price > $1" ) .bind(5.0_f64) .fetch_all(&pool) .await?;
for (name, price) in rows { println!("{}: ${:.2}", name, price); }
Ok(())}Python: psycopg2
Section titled “Python: psycopg2”import psycopg2
conn = psycopg2.connect( host="your-project.zatabase.io", password="SecurePass123!", dbname="zatabase")
cur = conn.cursor()cur.execute("CREATE TABLE sensors (location TEXT, temperature FLOAT)")cur.execute("INSERT INTO sensors VALUES ('lab-1', 22.5)")conn.commit()
cur.execute("SELECT * FROM sensors")for row in cur.fetchall(): print(row)
conn.close()Configuration
Section titled “Configuration”Server-side wire protocol settings via environment variables:
| Variable | Default | Description |
|---|---|---|
ZPG_BIND_PORT | 5432 | Port for PG wire protocol |
ZPG_SSL_PORT | 5434 | Port for TLS connections |
ZPG_MAX_CONNECTIONS | 100 | Maximum concurrent connections |
ZPG_CONNECTION_TIMEOUT | 30 | Connection timeout in seconds |
ZPG_AUTH_TIMEOUT | 30 | Authentication timeout in seconds |
ZPG_MAX_AUTH_ATTEMPTS | 3 | Failed auth attempts before lockout |
ZPG_LOCKOUT_DURATION | 900 | Lockout duration in seconds (15 min) |
ZPG_TCP_NO_DELAY | true | Disable Nagle’s algorithm |
ZPG_KEEP_ALIVE | true | Enable TCP keepalive |
TLS/SSL
Section titled “TLS/SSL”Enable encrypted connections by configuring the SSL port and providing certificate files:
export ZPG_SSL_ENABLED=trueexport ZPG_SSL_CERT_PATH=/path/to/server.crtexport ZPG_SSL_KEY_PATH=/path/to/server.keyClients can then connect with sslmode=require:
Limitations
Section titled “Limitations”- Prepared statements: Basic support; complex parameterized queries may require the HTTP API
- COPY protocol: Not currently supported; use the HTTP ingest endpoint for bulk loads
- Cursors: Not supported; use
LIMIT/OFFSETfor pagination - System catalogs:
pg_catalogqueries return limited metadata - Extensions: PostgreSQL extensions (PostGIS, pgvector, etc.) are not available; Zatabase has its own native vector support