How It Works
Understand compilation and how FraiseQL maps your schema to SQL.
FraiseQL uses a single fraiseql.toml file for all configuration. TOML is human-readable, git-friendly, and has no YAML gotchas.
[project]name = "my-api"
[database]url = "${DATABASE_URL}"That’s it. Everything else has sensible defaults.
The following sections are confirmed valid in fraiseql.toml. Unknown sections cause a hard parse error at fraiseql compile.
# ============================================# Project Metadata# ============================================[project]name = "my-api"version = "1.0.0"
# ============================================# Database Configuration# ============================================[database]url = "${DATABASE_URL}"pool_min = 2 # default: 2pool_max = 20connect_timeout_ms = 5000idle_timeout_ms = 600000ssl_mode = "prefer" # disable | allow | prefer | require
# ============================================# Server Configuration# ============================================[server]host = "0.0.0.0" # default: 0.0.0.0port = 8080 # default: 8080request_timeout_ms = 30000keep_alive_secs = 75
[server.cors]origins = ["https://app.example.com"]credentials = true
[server.tls]cert = "/path/to/cert.pem"key = "/path/to/key.pem"
# ============================================# Security# ============================================[security]default_policy = "authenticated" # or "public"
[[security.rules]]name = "owner_only"rule = "user.id == object.owner_id"cacheable = truecache_ttl_seconds = 300
[[security.policies]]name = "admin_only"type = "rbac"roles = ["admin"]strategy = "any"
[security.error_sanitization]enabled = truehide_implementation_details = truesanitize_database_errors = truecustom_error_message = "An internal error occurred"
[security.rate_limiting]enabled = truerequests_per_second = 100burst_size = 200
[security.state_encryption]enabled = truealgorithm = "chacha20-poly1305"key_source = "env"key_env = "STATE_ENCRYPTION_KEY"
[security.pkce]enabled = truecode_challenge_method = "S256"state_ttl_secs = 600
[security.enterprise]audit_logging_enabled = trueaudit_log_level = "info"
# ============================================# Query Defaults# ============================================[query_defaults]# Default limits and pagination settings
# ============================================# Federation# ============================================[federation]enabled = true
[federation.circuit_breaker]enabled = truefailure_threshold = 5timeout_secs = 30Use ${VAR_NAME} syntax in fraiseql.toml to reference environment variables:
[database]url = "${DATABASE_URL}"
[server]port = 8080Some settings are only configurable via environment variables (no TOML equivalent):
| Variable | Description |
|---|---|
DATABASE_URL | Database connection string |
JWT_SECRET | JWT signing secret (HS256) or public key path (RS256/ES256) |
JWT_ALGORITHM | HS256 | RS256 | ES256 (default: HS256) |
JWT_ISSUER | Expected iss claim (optional) |
JWT_AUDIENCE | Expected aud claim (optional) |
RUST_LOG | Log level: error | warn | info | debug | trace |
OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry collector endpoint |
OTEL_SERVICE_NAME | Service name for traces |
Use separate fraiseql.toml files per environment, or use environment variable substitution to vary values:
# DevelopmentDATABASE_URL=postgresql://localhost:5432/myapp_dev fraiseql run
# Production (different .env file or secrets manager)DATABASE_URL=postgresql://prod-host:5432/myapp fraiseql runYou can also maintain separate config files:
# Use a different config filefraiseql run --config fraiseql.production.tomlFraiseQL validates your fraiseql.toml when you run fraiseql compile. Unknown sections cause a hard parse error — this is intentional, so configuration mistakes are caught at build time rather than at runtime.
fraiseql compile# Error: unknown field `[auth]` in fraiseql.toml at line 12[project]name = "my-api"
[database]url = "postgresql://localhost:5432/myapp_dev"
[server]port = 8080# Development loggingRUST_LOG=debug fraiseql run[project]name = "my-api"
[database]url = "${DATABASE_URL}"pool_min = 5pool_max = 20ssl_mode = "require"
[server]host = "0.0.0.0"port = 8080
[server.cors]origins = ["https://app.example.com"]credentials = true
[security.error_sanitization]enabled = true
[security.rate_limiting]enabled = truerequests_per_second = 100burst_size = 200# Production env varsJWT_SECRET=your-256-bit-secretRUST_LOG=infoOTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317[project]name = "multi-tenant-api"
[database]url = "${DATABASE_URL}"# JWT includes tenant_id claim — extracted in middlewareJWT_SECRET=your-256-bit-secretSee Multi-Tenancy Guide for RLS and schema-per-tenant patterns.
How It Works
Understand compilation and how FraiseQL maps your schema to SQL.
Schema Definition
Define your types in Python, TypeScript, or Go.
CLI Reference
All CLI commands for building and serving your API.
Type System
Understand the type system and how Python types map to GraphQL.