Skip to content
Configuration

Configuration

Every key in ephpm.toml, with type, default, and a short description. The source of truth is crates/ephpm-config/src/lib.rs — if a field has been added there but not here, that’s a doc bug.

All sections and keys are optional. Missing sections use defaults; Config::default_config() produces a fully working configuration.

[server]

KeyTypeDefaultDescription
listenstring"0.0.0.0:8080"Address to listen on.
document_rootpath"."Document root for static files and PHP scripts.
sites_dirpath(none)Virtual host directory. Each subdirectory is named after a domain. Omit for single-site mode.
index_filesarray of strings["index.php", "index.html"]Index file names to try when a directory is requested.
fallbackarray of strings["$uri", "$uri/", "/index.php?$query_string"]URL fallback chain. Variables: $uri, $query_string. Last entry is the fallback (prefix = for status code, e.g. =404).

[server.request]

KeyTypeDefaultDescription
max_body_sizeu64 (bytes)10_485_760 (10 MiB)Max request body. 0 = unlimited. Exceeding sends 413.
max_header_sizeusize (bytes)8192Max total request header size.
trusted_hostsarray of strings[]Allowed Host header values. Empty = allow all. Mismatched hosts get 421.

[server.timeouts] (all in seconds)

KeyTypeDefaultDescription
header_readu6430Time to receive complete request headers after connect.
idleu6460Idle connection timeout.
requestu64300Total request timeout including PHP execution.
shutdownu6430Grace period for in-flight connections during shutdown.

[server.response]

KeyTypeDefaultDescription
compressionbooltrueEnable gzip compression for text responses.
compression_levelu321gzip level (1=fastest, 9=best).
compression_min_sizeusize (bytes)1024Minimum response size before compression applies.
headersarray of [string, string][]Custom headers added to every response.

[server.static]

KeyTypeDefaultDescription
cache_controlstring""Cache-Control header value for static files. Empty = no header.
hidden_filesstring"deny"How to handle dot-files: "deny" (403), "ignore" (404), "allow".
etagbooltrueEmit ETag headers and serve 304 Not Modified on conditional requests.

[server.php_etag_cache]

KeyTypeDefaultDescription
enabledboolfalseCache PHP-emitted ETags in the KV store; serve 304s without re-running PHP.
ttl_secsi64300TTL for cached entries. <=0 means cache indefinitely.
key_prefixstring"etag:"KV key prefix for cached entries.

[server.security]

KeyTypeDefaultDescription
trusted_proxiesarray of strings[]CIDR ranges trusted for X-Forwarded-For/X-Forwarded-Proto.
blocked_pathsarray of strings[]Glob patterns blocked with 403.
allowed_php_pathsarray of strings[]When non-empty, only matching PHP paths execute. Others get 403.
open_basedirbooltrue if sites_dir set, else falseRestrict PHP filesystem access to the site’s document root.
disable_shell_execbooltrue if sites_dir set, else falseDisable exec, shell_exec, system, passthru, proc_open, popen, pcntl_exec.

[server.logging]

KeyTypeDefaultDescription
accessstring""Path to access log file. Empty = disabled.
levelstring"info"Log level: trace, debug, info, warn, error. Overridden by RUST_LOG.

[server.metrics]

KeyTypeDefaultDescription
enabledboolfalseEnable the Prometheus /metrics endpoint.
pathstring"/metrics"URL path for the metrics endpoint.

[server.limits]

KeyTypeDefaultDescription
max_connectionsusize0Total concurrent connections. 0 = unlimited. New connections beyond limit get 503.
per_ip_max_connectionsusize0Per-IP concurrent connections. 0 = unlimited.
per_ip_ratef640.0Per-IP requests/second (token bucket). 0 = unlimited.
per_ip_burstu3250Burst allowance for per-IP rate limiting.

[server.file_cache]

KeyTypeDefaultDescription
enabledboolfalseIn-memory cache for static file metadata + small-file content.
max_entriesusize10_000Max cached entries. Oldest evicted on overflow.
valid_secsu6430Re-stat interval.
inactive_secsu6460Evict entries not accessed within this many seconds.
inline_thresholdusize (bytes)1_048_576 (1 MiB)Cache file content below this size; metadata-only above.
precompressbooltruePre-compute gzip-compressed variants for small compressible files.

[server.tls]

Two mutually exclusive modes — manual (cert+key) or ACME (domains). If both are set, manual wins.

KeyTypeDefaultDescription
certpath(none)PEM-encoded certificate chain (manual mode).
keypath(none)PEM-encoded private key (manual mode).
domainsarray of strings[]Domains for ACME / Let’s Encrypt (auto mode).
emailstring(none)Contact email for ACME registration.
cache_dirpath"certs"Directory for ACME cert + account key cache. Set this in production.
stagingboolfalseUse Let’s Encrypt staging (untrusted certs, generous rate limits).
listenstring(none)Separate HTTPS listener. When set, [server] listen serves HTTP and this serves HTTPS.
redirect_httpboolfalseWhen listen is set, the HTTP listener redirects everything to HTTPS (301).

[php]

KeyTypeDefaultDescription
max_execution_timeu32 (sec)30PHP max_execution_time per request.
memory_limitstring"128M"PHP memory_limit.
ini_filepath(none)Custom php.ini loaded before ini_overrides.
ini_overridesarray of [string, string][]INI directives applied after ini_file.
workersusizemin(logical_cpus, 16)Dedicated PHP worker threads.

[db]

[db.mysql] / [db.postgres] / [db.tds]

All three share the same backend config schema. Adding a section enables the proxy.

KeyTypeDefaultDescription
urlstring(required)Connection URL: mysql://user:pass@host:port/db, postgres://....
listenstring"127.0.0.1:3306" (mysql), "127.0.0.1:5432" (postgres)TCP address PHP connects to.
socketpath(none)Unix socket path (faster than TCP for local PHP).
min_connectionsu322Warm pool size (idle connections kept open).
max_connectionsu3220Max total backend connections.
idle_timeoutduration string"300s"Close idle backend connections after this.
max_lifetimeduration string"1800s"Recycle connections older than this.
pool_timeoutduration string"5s"Time to wait for a connection before failing.
health_check_intervalduration string"30s"Frequency of backend health checks.
inject_envbooltrueInject DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, DATABASE_URL into PHP.
reset_strategystring"smart""smart" (reset after non-SELECT), "always", "never".
replicas.urlsarray of strings[]Read replica URLs. Reads distributed across; writes go to primary.

[db.sqlite]

KeyTypeDefaultDescription
pathstring"ephpm.db"SQLite database file path.

[db.sqlite.proxy]

KeyTypeDefaultDescription
mysql_listenstring"127.0.0.1:3306"MySQL wire protocol address (PHP connects here with pdo_mysql).
hrana_listenstring(none)Hrana HTTP API listener.
postgres_listenstring(none)PostgreSQL wire protocol listener.
tds_listenstring(none)TDS (SQL Server) wire protocol listener.

[db.sqlite.sqld] (clustered mode only)

KeyTypeDefaultDescription
http_listenstring"127.0.0.1:8081"sqld HTTP listener (litewire → sqld).
grpc_listenstring"0.0.0.0:5001"sqld gRPC listener (inter-node replication).

[db.sqlite.replication] (clustered mode only)

KeyTypeDefaultDescription
rolestring"auto""auto" (gossip-elected), "primary", "replica".
primary_grpc_urlstring""Primary gRPC URL (set automatically in auto mode; required for replica).

[db.read_write_split]

KeyTypeDefaultDescription
enabledboolfalseEnable R/W splitting. Requires backend with replicas.
strategystring"sticky-after-write"After a write, reads stick to primary for sticky_duration. "lag-aware" is parsed but not yet implemented.
sticky_durationduration string"2s"How long reads stay on primary after a write.
max_replica_lagduration string"500ms"Not yet implemented — parsed but unused.

[db.analysis]

KeyTypeDefaultDescription
query_statsbooltrueTrack per-digest timing/throughput metrics.
slow_query_thresholdduration string"1s"Queries exceeding this are logged at WARN.
auto_explainboolfalseNot yet implemented — parsed but unused.
auto_explain_targetstring"stderr"Not yet implemented.
digest_store_max_entriesusize100_000Max in-memory query digests; oldest evicted on overflow.

[kv]

KeyTypeDefaultDescription
memory_limitstring"256MB"Max memory for the KV store.
eviction_policystring"allkeys-lru"noeviction, allkeys-lru, volatile-lru, allkeys-random.
compressionstring"none"none, gzip, brotli, zstd.
compression_levelu3261=fastest, 9=best.
compression_min_sizeusize (bytes)1024Values below this are stored uncompressed.
secretstring(none)Master secret for per-site RESP AUTH. Auto-generated if absent.

[kv.redis_compat]

KeyTypeDefaultDescription
enabledboolfalseEnable the RESP listener. Off by default; in multi-tenant mode keep it off.
listenstring"127.0.0.1:6379"RESP listener address.
socketstring(none)Not yet implemented — parsed but unused.
passwordstring(none)RESP AUTH password.

[cluster]

KeyTypeDefaultDescription
enabledboolfalseEnable gossip clustering.
bindstring"0.0.0.0:7946"Gossip UDP listener.
joinarray of strings[]Seed addresses for initial cluster join.
secretbase64 string""32-byte symmetric key for gossip encryption.
node_idstring(auto)Unique node identifier. Auto-generated if empty.
cluster_idstring"ephpm"Nodes with different cluster_ids ignore each other.

[cluster.kv]

KeyTypeDefaultDescription
small_key_thresholdusize (bytes)512Boundary between gossip tier and TCP data plane.
replication_factorusize2Replicas for large-tier values.
replication_modestring"async""async" or "sync".
hot_key_cachebooltruePromote frequently-fetched remote values to a local cache.
hot_key_thresholdu325Remote fetches in hot_key_window_secs before promotion.
hot_key_window_secsu6410Window for counting fetches.
hot_key_local_ttl_secsu6430Max age of cached hot-key values.
hot_key_max_memorystring"64MB"Memory budget for hot-key cache.
data_portu167947TCP listener for the KV data plane.

See also