Skip to main content
Frontier requires two databases: PostgreSQL for application data and SpiceDB for authorization relationships. This guide covers configuration for both.

PostgreSQL Configuration

Frontier uses PostgreSQL to store users, organizations, subscriptions, billing data, and other application state.

Requirements

  • PostgreSQL 12 or higher
  • Database with appropriate permissions for schema migrations
  • SSL/TLS recommended for production

Configuration

db.driver
string
default:"postgres"
required
Database driver. Currently only PostgreSQL is supported.
db.url
string
required
PostgreSQL connection string.
db:
  url: "postgres://username:password@localhost:5432/frontier?sslmode=disable"
Format: postgres://[user]:[password]@[host]:[port]/[database]?[parameters]
Use sslmode=require or sslmode=verify-full in production environments.
db.max_idle_conns
integer
default:"10"
Maximum number of idle connections in the pool.Idle connections are kept open for reuse. Increase for high-traffic applications.
db.max_open_conns
integer
default:"10"
Maximum number of open connections to the database.Limits total concurrent connections. Should be set based on your PostgreSQL max_connections setting.Recommended: Set to PostgreSQL’s max_connections divided by number of application instances.
db.conn_max_life_time
duration
default:"15m"
Maximum amount of time a connection can be reused.
db:
  conn_max_life_time: "30m"
Helps prevent connection leaks and ensures connections are refreshed periodically.
db.max_query_timeout
duration
default:"500ms"
Maximum execution time for individual database queries.
db:
  max_query_timeout: "2s"
Queries exceeding this timeout will be cancelled.

Connection String Parameters

Common PostgreSQL connection parameters:
  • sslmode - SSL connection mode
    • disable - No SSL (development only)
    • require - Require SSL but don’t verify certificate
    • verify-ca - Require SSL and verify certificate
    • verify-full - Require SSL, verify certificate and hostname
  • connect_timeout - Connection timeout in seconds
  • application_name - Application name for PostgreSQL logs
  • search_path - Default schema search path

Example Configurations

db:
  driver: postgres
  url: postgres://frontier:frontier@localhost:5432/frontier?sslmode=disable
  max_idle_conns: 5
  max_open_conns: 10
  conn_max_life_time: 15m
  max_query_timeout: 500ms

Database Initialization

Frontier automatically runs migrations on startup. To initialize the database:
# Run migrations
frontier server migrate

# Check migration status
frontier server migrate --check

Performance Tuning

For production deployments:
  1. Connection Pool Sizing
    db:
      max_open_conns: 100  # Based on your traffic
      max_idle_conns: 25   # ~25% of max_open_conns
      conn_max_life_time: 30m
    
  2. Query Timeout
    db:
      max_query_timeout: 2s  # Fail fast on slow queries
    
  3. PostgreSQL Settings (postgresql.conf)
    max_connections = 200
    shared_buffers = 256MB
    effective_cache_size = 1GB
    maintenance_work_mem = 64MB
    checkpoint_completion_target = 0.9
    wal_buffers = 16MB
    default_statistics_target = 100
    random_page_cost = 1.1
    effective_io_concurrency = 200
    work_mem = 4MB
    min_wal_size = 1GB
    max_wal_size = 4GB
    

SpiceDB Configuration

SpiceDB is Frontier’s authorization database, implementing Google Zanzibar-style permissions.

Requirements

  • SpiceDB v1.22.0 or higher
  • Running SpiceDB instance (see SpiceDB installation)
  • Network connectivity between Frontier and SpiceDB

Configuration

spicedb.host
string
required
Hostname or IP address of the SpiceDB service.
spicedb:
  host: spicedb.localhost
  # Or for Kubernetes:
  # host: spicedb-service.default.svc.cluster.local
spicedb.port
string
default:"50051"
required
Port number for SpiceDB gRPC API.
spicedb.pre_shared_key
string
required
Authentication key for SpiceDB communication.
spicedb:
  pre_shared_key: "your-secure-random-key"
Generate a secure random key and keep it secret. This key authenticates Frontier to SpiceDB.
spicedb.consistency
string
default:"best_effort"
Consistency mode for SpiceDB operations.Options:
  • full - Guarantees fresh data, slower performance
  • best_effort - Balances freshness and performance (recommended)
  • minimize_latency - Prioritizes speed, may return slightly stale data
spicedb:
  consistency: "best_effort"
spicedb.check_trace
boolean
default:"false"
Enable detailed tracing for SpiceDB permission checks.
Adds significant latency to check operations. Only enable for debugging in non-production environments.
spicedb.fully_consistent
boolean
default:"false"
Deprecated: Use consistency: "full" instead.Ensures fully consistent API responses at the cost of performance.

Example Configurations

spicedb:
  host: localhost
  port: 50051
  pre_shared_key: "dev-key-not-for-production"
  consistency: "minimize_latency"
  check_trace: true

SpiceDB Deployment

Using Docker

docker run -d \
  --name spicedb \
  -p 50051:50051 \
  -e SPICEDB_GRPC_PRESHARED_KEY="your-secure-key" \
  authzed/spicedb serve \
  --grpc-preshared-key "your-secure-key" \
  --datastore-engine memory

Using Docker Compose

docker-compose.yml
version: '3.8'
services:
  spicedb:
    image: authzed/spicedb:latest
    command: serve --grpc-preshared-key "dev-key"
    ports:
      - "50051:50051"
    environment:
      - SPICEDB_GRPC_PRESHARED_KEY=dev-key
      - SPICEDB_DATASTORE_ENGINE=postgres
      - SPICEDB_DATASTORE_CONN_URI=postgres://spicedb:spicedb@postgres:5432/spicedb?sslmode=disable
    depends_on:
      - postgres
  
  postgres:
    image: postgres:15
    environment:
      - POSTGRES_USER=spicedb
      - POSTGRES_PASSWORD=spicedb
      - POSTGRES_DB=spicedb
    volumes:
      - spicedb-data:/var/lib/postgresql/data

volumes:
  spicedb-data:

Production Deployment

For production, SpiceDB should use PostgreSQL or CockroachDB as its datastore:
spicedb serve \
  --grpc-preshared-key "${SPICEDB_KEY}" \
  --datastore-engine postgres \
  --datastore-conn-uri "postgres://spicedb:password@db:5432/spicedb?sslmode=require" \
  --grpc-addr ":50051"

Consistency Modes Explained

ModeUse CaseTrade-offs
fullFinancial transactions, critical operationsHighest consistency, slower performance
best_effortGeneral application useBalanced consistency and speed (recommended)
minimize_latencyRead-heavy applications, dashboardsFastest, may show slightly stale data

Monitoring SpiceDB

SpiceDB exposes metrics at :9090/metrics (Prometheus format). Key metrics:
  • grpc_server_handled_total - Total requests
  • grpc_server_handling_seconds - Request duration
  • spicedb_datastore_read_namespaces_total - Read operations

Complete Example

db:
  driver: postgres
  url: postgres://frontier:frontier@localhost:5432/frontier?sslmode=require
  max_idle_conns: 10
  max_open_conns: 50
  conn_max_life_time: 30m
  max_query_timeout: 2s

spicedb:
  host: spicedb.localhost
  port: 50051
  pre_shared_key: "your-secure-random-key"
  consistency: "best_effort"
  check_trace: false

Troubleshooting

PostgreSQL Connection Issues

Problem: connection refused
# Check PostgreSQL is running
pg_isready -h localhost -p 5432

# Test connection
psql "postgres://frontier:password@localhost:5432/frontier"
Problem: too many connections
  • Reduce max_open_conns in Frontier config
  • Increase PostgreSQL max_connections
  • Check for connection leaks
Problem: Slow queries
-- Find slow queries in PostgreSQL
SELECT * FROM pg_stat_statements 
ORDER BY mean_exec_time DESC 
LIMIT 10;

SpiceDB Connection Issues

Problem: unauthenticated
  • Verify pre_shared_key matches SpiceDB configuration
  • Check SpiceDB logs for authentication errors
Problem: deadline exceeded
  • Check network connectivity to SpiceDB
  • Verify SpiceDB is running and healthy
  • Consider adjusting consistency mode
Problem: Permission checks are slow
  • Disable check_trace if enabled
  • Use minimize_latency consistency mode
  • Scale SpiceDB horizontally

See Also

Build docs developers (and LLMs) love