Deployment Guide
June 24, 2026 · View on GitHub
See NOTICE for important disclaimers.
This guide covers deploying extenddb in various environments beyond local development.
Architecture Overview
extenddb is a single Rust binary that connects to PostgreSQL. All state lives in PostgreSQL — extenddb itself is stateless (no in-process caching). This means:
- Multiple extenddb instances can share a PostgreSQL catalog (with caveats — see Multi-Instance below)
- Standard PostgreSQL HA, backup, and replication tools provide durability
- extenddb can run anywhere PostgreSQL is reachable
Deployment Models
Single-Node
extenddb and PostgreSQL on the same host. Simplest setup, suitable for development, CI, and small workloads.
┌─────────────────────────┐
│ Host │
│ ┌─────┐ ┌──────────┐ │
│ │ extenddb│──│PostgreSQL │ │
│ └─────┘ └──────────┘ │
└─────────────────────────┘
extenddb init
extenddb serve --config extenddb.toml
Separated Database
extenddb on an application server, PostgreSQL on a dedicated database server or managed service.
┌──────────┐ ┌──────────────┐
│ App Host│──────▶│ DB Host │
│ extenddb │ │ PostgreSQL │
└──────────┘ └──────────────┘
extenddb init \
--pg-host db.example.com \
--pg-pass
Configure the connection string in extenddb.toml:
[storage.postgres]
connection_string = "postgresql://extenddb:<password>@db.example.com:5432/extenddb_catalog?sslmode=require"
pool_size = 20
Use sslmode=require (or verify-full with a CA certificate) for encrypted database connections.
Managed PostgreSQL
extenddb works with any PostgreSQL 14+ service:
- Amazon RDS for PostgreSQL / Amazon Aurora PostgreSQL
- Google Cloud SQL for PostgreSQL
- Azure Database for PostgreSQL
- Self-managed PostgreSQL with streaming replication
# Amazon RDS / Aurora example
extenddb init \
--pg-host mydb.cluster-abc123.us-east-1.rds.amazonaws.com \
--pg-user extenddb_admin \
--pg-pass
Containerized
extenddb runs in Docker or Kubernetes. The binary has no runtime dependencies beyond libc and network access to PostgreSQL.
Example Dockerfile:
# Match rust-version in Cargo.toml
FROM rust:1.95 AS builder
WORKDIR /src
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates tini && rm -rf /var/lib/apt/lists/*
COPY --from=builder /src/target/release/extenddb /usr/local/bin/extenddb
COPY extenddb.toml /etc/extenddb/extenddb.toml
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
EXPOSE 18443
ENTRYPOINT ["tini", "--"]
CMD ["/usr/local/bin/entrypoint.sh"]
extenddb always daemonizes (there is no foreground mode). In a container, the parent process exits after forking, which causes the container runtime to stop the container. Use tini as PID 1 and a wrapper script that starts extenddb and waits on the daemon process:
#!/bin/sh
# entrypoint.sh
extenddb serve --config /etc/extenddb/extenddb.toml
# Wait on the daemon PID — the PID file location depends on run_dir in extenddb.toml
# Default: ~/.extenddb/run/extenddb-<port>.pid
PID_FILE="${HOME}/.extenddb/run/extenddb-18443.pid"
if [ -f "$PID_FILE" ]; then
tail --pid="$(cat "$PID_FILE")" -f /dev/null
else
echo "extenddb failed to start — PID file not found at $PID_FILE" >&2
exit 1
fi
For Kubernetes, run extenddb init as an init container or a one-time Job, then deploy extenddb as a Deployment with the generated extenddb.toml mounted as a ConfigMap or Secret.
Air-Gapped
extenddb requires no internet connectivity. All functionality is self-contained in the binary. Build on a connected host, transfer the binary and extenddb.toml to the air-gapped environment, and run.
Requirements in the air-gapped environment:
- PostgreSQL 14+ (reachable from the extenddb host)
- The
extenddbbinary (statically linked or with matching libc)
Production Checklist
Authentication
- Set
auth.provider = "builtin"inextenddb.toml - Change the admin password from the auto-generated one
- Create named accounts and IAM users with least-privilege policies
- Disable credential import if not needed:
extenddb settings set allow_credential_import false
Transport
- TLS is enabled by default. Verify it is not disabled in
extenddb.toml - Replace the self-signed certificate with a CA-signed certificate
- Use
sslmode=requireorsslmode=verify-fullin the PostgreSQL connection string
Network
- Set
bind_addrto the appropriate interface (not0.0.0.0unless behind a load balancer) - Firewall: allow only necessary ports (extenddb port, PostgreSQL port)
- Consider a reverse proxy (nginx, HAProxy) for TLS termination, rate limiting, and access logging
Database
- Use a dedicated PostgreSQL user for extenddb with minimal privileges
- Configure PostgreSQL
max_connections≥ extenddbpool_size+ 3 - Enable PostgreSQL TLS
- Set up automated backups (pg_dump, WAL archiving, or managed service snapshots)
- Monitor PostgreSQL disk usage, connection count, and query performance
Monitoring
- Poll
/metricsfor JSON snapshots and forward to your monitoring system (the response is custom JSON, not Prometheus exposition format; convert as needed) - Forward syslog to a log aggregation service
- Set up alerts on health check failures (
/health) - Monitor extenddb process with systemd, supervisord, or equivalent
Upgrades
- Test upgrades in a staging environment first
- Run
extenddb migrate --config extenddb.tomlafter binary upgrade - Verify catalog version matches:
extenddb verify --config extenddb.toml
systemd Service
Example unit file for Linux:
[Unit]
Description=ExtendDB
After=postgresql.service
Requires=postgresql.service
[Service]
Type=forking
ExecStart=/usr/local/bin/extenddb serve --config /etc/extenddb/extenddb.toml
ExecStop=/usr/local/bin/extenddb stop --config /etc/extenddb/extenddb.toml
# PID file path: {run_dir}/extenddb-{port}.pid
# Default run_dir is ~/.extenddb/run (~ expands to $HOME of the User= below)
# Adjust if run_dir or port are overridden in extenddb.toml
PIDFile=/home/extenddb/.extenddb/run/extenddb-18443.pid
User=extenddb
Group=extenddb
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl enable extenddb
sudo systemctl start extenddb
Multi-Instance Considerations
Multiple extenddb instances can connect to the same PostgreSQL catalog. However:
- extenddb does not cache database state in-process — every request reads directly from PostgreSQL
- This means multiple instances see consistent data without cache invalidation
- PostgreSQL's connection pool and row-level locking handle concurrent access
- Ensure
pool_size × instance_count + 3 × instance_count ≤ PostgreSQL max_connections
Performance Tuning
Connection Pool
The default pool_size = 20 is suitable for moderate workloads. For high-concurrency deployments:
[storage.postgres]
pool_size = 50 # Increase for higher concurrency
Ensure PostgreSQL max_connections accommodates the total pool size plus overhead.
PostgreSQL Tuning
Key PostgreSQL settings for extenddb workloads:
shared_buffers: 25% of available RAMeffective_cache_size: 75% of available RAMwork_mem: 64MB (for sort operations in Query/Scan)max_connections: ≥ extenddb pool_size + 10
Monitoring Queries
-- Active connections from extenddb
SELECT count(*) FROM pg_stat_activity WHERE usename = 'extenddb';
-- Table sizes
SELECT relname, pg_size_pretty(pg_total_relation_size(oid))
FROM pg_class WHERE relname LIKE 'ddb_%' ORDER BY pg_total_relation_size(oid) DESC;
-- Slow queries
SELECT query, mean_exec_time, calls
FROM pg_stat_statements WHERE usename = 'extenddb'
ORDER BY mean_exec_time DESC LIMIT 10;
License
Copyright 2026 ExtendDB contributors. Licensed under the Apache License, Version 2.0. See LICENSE for the full text.
This software is provided "as is" without warranty of any kind. ExtendDB is not affiliated with, endorsed by, or sponsored by Amazon Web Services. "DynamoDB" is a trademark of Amazon.com, Inc.