Configuration
Sensible defaults. Works as-is. Options when you need them.
You need one setting: upstream.
Point Gold Lapel at your Postgres instance. Everything else has sensible defaults — connection pooling, thresholds, caching, N+1 detection — all tuned and ready. Configure only what you want to change.
goldlapel --upstream 'postgresql://user:pass@localhost:5432/mydb' Example goldlapel.toml
A production-ready config file. All fields are optional — Gold Lapel only needs upstream. Copy what you need, ignore the rest.
upstream = "postgresql://goldlapel:password@localhost:5432/mydb"
mode = "waiter"
proxy_port = 7932
dashboard_port = 7933
invalidation_port = 7934
logical_decoding = true
fallback = "postgresql://goldlapel:password@standby:5432/mydb"
replicas = [
"postgresql://goldlapel:password@replica1:5432/mydb",
"postgresql://goldlapel:password@replica2:5432/mydb",
]
[l1]
enabled = true
cache_size = 32768
subscriber_connections = 1
[l2]
result_cache = true
result_cache_size = 65536
prepared_cache = true
prepared_cache_size = 1024
[l3]
matviews = true
indexes = true
threshold = 1
refresh_interval_secs = 60
shadow_verification = true
[sql]
rewrite = true
join_reorder = true
subquery_flatten = true
predicate_pushdown = true
[thresholds]
min_pattern_count = 1
refresh_interval_secs = 60
pattern_ttl_secs = 604800
read_after_write_secs = 5
[cache]
result_cache_size = 65536
prepared_cache_size = 1024
batch_cache_size = 64
batch_cache_ttl_secs = 300
[pool]
enabled = true
size = 50
mode = "transaction"
idle_timeout_secs = 300
timeout_secs = 10
[tls]
cert = "/path/to/server.crt"
key = "/path/to/server.key"
[n1]
threshold = 5
window_ms = 500
cross_threshold = 10
[disable]
trigram_indexes = true
[enable]
coalescing = true
[exclude]
tables = ["migrations", "sessions"]
# [oidc]
# issuer = "https://accounts.google.com"
# client_id = "your-client-id"
# client_secret = "your-client-secret"
# redirect_uri = "https://gl.example.com:7933/auth/oidc/callback"
# [saml]
# idp_metadata_url = "https://login.microsoftonline.com/.../federationmetadata/2007-06/federationmetadata.xml"
# sp_entity_id = "https://gl.example.com:7933"
# acs_url = "https://gl.example.com:7933/auth/saml/acs" How configuration works
Precedence
Configuration sources are checked in order, highest priority first:
- CLI flags (
--mode waiter) - Shell environment variables (
GOLDLAPEL_MODE=waiter) .envfile in the working directorygoldlapel.tomlconfig file- Built-in defaults
Higher-priority sources always win. A CLI flag overrides the same setting from any other source. At startup, Gold Lapel logs every non-default setting with its resolved value and source (cli, env, .env, config, default).
Config file (goldlapel.toml)
Run goldlapel init to generate a fully commented config file with all settings documented and default values:
goldlapel init Gold Lapel auto-discovers goldlapel.toml in the current directory on startup. Use --config to load from a different location:
goldlapel --config /etc/goldlapel/production.toml All fields are optional — only set what you want to change. Unknown keys are rejected (catches typos before they become silent misconfigurations). The example config above shows the full TOML format.
Environment variables
Set environment variables directly in your shell:
export GOLDLAPEL_UPSTREAM='postgresql://goldlapel:password@localhost:5432/mydb'
export GOLDLAPEL_POOL_SIZE=50
goldlapel Or create a .env file in the directory where you run Gold Lapel:
GOLDLAPEL_UPSTREAM=postgresql://goldlapel:password@localhost:5432/mydb
GOLDLAPEL_POOL_SIZE=50
GOLDLAPEL_RESULT_CACHE_SIZE=65536 Every CLI flag has a GOLDLAPEL_ env var equivalent — see the full reference tables below.
Wrapper config objects
Language wrappers accept a config dict/object that maps directly to CLI flags. Every setting in the reference tables below can be set via the config object.
Python (snake_case)
import goldlapel
gl = goldlapel.start("postgresql://user:pass@localhost/mydb", config={
"pool_size": 50,
"disable_matviews": True,
"replica": ["postgresql://user:pass@replica1/mydb"],
}) JavaScript (camelCase)
import * as goldlapel from 'goldlapel';
const gl = await goldlapel.start('postgresql://user:pass@localhost/mydb', {
config: {
poolSize: 50,
disableMatviews: true,
replica: ['postgresql://user:pass@replica1/mydb'],
},
}); Naming convention: Python, Ruby, Go, and PHP use snake_case keys. JavaScript, Java, and .NET use camelCase keys. Both map to the same CLI flags (pool_size / poolSize → --pool-size).
Boolean keys like disable_matviews are flags — True enables them, False (or omitting) leaves them off. Array keys like replica produce repeated CLI flags.
Unknown keys raise an error immediately with the full list of valid keys. Use config_keys() to see all valid keys programmatically:
# Python
goldlapel.config_keys()
# JavaScript
import { configKeys } from 'goldlapel'
configKeys() Live reload
Gold Lapel polls goldlapel.toml every 30 seconds. Every setting live-reloads — edit the file, save, and changes take effect automatically. No restart, no dropped connections. Parse errors keep the current config.
Authentication (SSO)
When the dashboard is exposed beyond localhost, I would strongly recommend securing it with single sign-on. Gold Lapel supports both OIDC and SAML 2.0 for dashboard authentication. Localhost access remains unauthenticated for local development — SSO applies only when the dashboard is network-accessible.
OIDC
Configure your identity provider (Google, Okta, Auth0, or any OIDC-compliant issuer) and provide the credentials in your config file. The redirect URI defaults to your dashboard URL with /auth/oidc/callback appended — override it only if your setup requires a different path.
[oidc]
issuer = "https://accounts.google.com"
client_id = "your-client-id"
client_secret = "your-client-secret"
# redirect_uri defaults to dashboard URL + /auth/oidc/callback SAML 2.0
For enterprise identity providers that speak SAML (Azure AD, Okta, OneLogin), point Gold Lapel at your IdP metadata URL. The service provider entity ID and assertion consumer service URL default to sensible values derived from your dashboard URL.
[saml]
idp_metadata_url = "https://login.microsoftonline.com/.../federationmetadata.xml"
# sp_entity_id defaults to dashboard URL
# acs_url defaults to dashboard URL + /auth/saml/acs Gold Lapel exposes its SP metadata at GET /auth/saml/metadata on the dashboard port — provide this URL to your identity provider during setup.
Write detection & NOTIFY auto-enable
Gold Lapel uses PostgreSQL logical decoding (wal_level=logical) as its primary write detection mechanism. When logical decoding is unavailable, NOTIFY trigger-based detection now starts automatically whenever a management connection is available — no configuration needed. This means cache invalidation works out of the box on hosts that don't support logical decoding.
If you prefer to disable automatic NOTIFY detection entirely, use --disable-notify (or [disable] notify = true in your config file). To force NOTIFY instead of logical decoding even when WAL is available, use --notify-fallback.
Tuning tips
Aggressive optimization
The default min_pattern_count = 1 optimizes immediately. GL is already aggressive out of the box — cold matviews cost nothing to maintain.
Conservative optimization
Increase min_pattern_count so GL waits for more evidence before optimizing. Good for mixed OLTP/OLAP workloads with many one-off queries.
Stable workloads
Set pattern_ttl_secs = 0 to keep matviews forever. The default (7 days) suits most workloads, but long-lived reporting views benefit from never expiring.
Fresher data
Lower refresh_interval_secs if your app needs near-real-time data in matviews. Increases database load from refresh operations.
Burst traffic
Many identical queries hitting at once? [enable] coalescing deduplicates them with zero added latency.
Connection tuning
Set pool size to match your Postgres max_connections headroom. Use pool mode = "transaction" for many short-lived connections.
Management connection
The default mgmt_idle_timeout_secs = 60 disconnects the management connection after 60 seconds of inactivity and reconnects on the next query (~100ms). For the snappiest experience, set it to 0 (always-on). Leave the timeout in place if your Postgres host charges for idle connections — Neon, Supabase, Aurora Serverless, and similar.
Upstream pooler detection
Supabase Supavisor, Neon pooler, RDS Proxy, and PgBouncer are recognized — Gold Lapel disables its own pool to avoid stacking. Override with explicit --pool-size.
Full reference
Pick your config method. Tables show the relevant key, default, and description.
All settings live-reload — edit goldlapel.toml and changes take effect automatically.
Core
| CLI Flag | Default | Description |
|---|---|---|
--upstream | localhost:5432 | Postgres connection string or host:port |
--proxy-port | 7932 | Port Gold Lapel listens on (--port and GOLDLAPEL_PORT still work as aliases) |
--mode | waiter | Operating mode: waiter (full optimization) or bellhop (observe only) |
--dashboard-port | proxy-port + 1 | Web dashboard port — auto-derives from proxy-port (default 7933). Set to 0 to disable. |
--invalidation-port | proxy-port + 2 | L1 native cache invalidation port — auto-derives from proxy-port (default 7934). Managed automatically. |
--config | - | Path to TOML config file |
--license | - | Path to license key file |
--mgmt-idle-timeout | 60 | Seconds of inactivity before closing the management connection (0 = always-on). We recommend 0 for most users — only use a timeout if your Postgres host charges for idle connections (Neon, Supabase, Aurora Serverless). |
--exclude-tables | - | Tables GL should never optimize (comma-separated, case-insensitive) |
--client | - | Client type identifier (set automatically by wrappers) |
--mesh-peers | - | Manual mesh peer endpoints — mesh is enabled per-instance via the account page (auto-discovery via database is default) |
--logical-decoding | true | Subscribe to PostgreSQL WAL for write detection (requires wal_level=logical, falls back to NOTIFY) |
--notify-fallback | false | Force NOTIFY trigger-based write detection instead of logical decoding. NOTIFY now starts automatically when a management connection is available — use --disable-notify to opt out. |
--verbose | false | Enable verbose INFO-level logging (default: clean banner only) |
Replicas & failover
| CLI Flag | Default | Description |
|---|---|---|
--replica | - | Read replica connection strings (repeatable flag, semicolon-separated env, array in config) |
--fallback | - | Failover endpoint. 3 failures routes traffic; 2 successes restores primary. |
--read-after-write-secs | 5 | Seconds after a write to keep reads on primary |
TLS
| CLI Flag | Description |
|---|---|
--tls-cert | PEM certificate file for client-facing TLS |
--tls-key | PEM private key file for client-facing TLS |
--tls-client-ca | PEM CA file for mTLS client certificate verification |
L1 — Native cache
| CLI Flag | Default | Description |
|---|---|---|
--l1-enabled | true | Enable L1 native cache (subscriber-based invalidation) |
--l1-cache-size | 32768 | Max entries in the L1 native cache (LRU). Proxy sends configured value to wrappers automatically via invalidation protocol. |
--l1-subscriber-connections | 1 | Number of WAL subscriber connections |
L2 — Proxy cache
| CLI Flag | Default | Description |
|---|---|---|
--l2-result-cache | true | Enable L2 result cache |
--l2-result-cache-size | 65536 | Max cached query results |
--l2-prepared-cache | true | Enable prepared statement cache |
--l2-prepared-cache-size | 1024 | Max cached prepared statements |
L3 — Materialized views & indexes
| CLI Flag | Default | Description |
|---|---|---|
--l3-matviews | true | Enable materialized view creation |
--l3-indexes | true | Enable automatic index creation |
--l3-threshold | 1 | Minimum pattern hits before materializing |
--l3-refresh-interval | 60 | Seconds between matview refreshes |
--l3-shadow-verification | true | Verify matview correctness before routing |
SQL optimization
| CLI Flag | Default | Description |
|---|---|---|
--sql-rewrite | true | Enable transparent query rewriting |
--sql-join-reorder | true | Optimize JOIN order |
--sql-subquery-flatten | true | Flatten correlated subqueries |
--sql-predicate-pushdown | true | Push predicates into subqueries |
Thresholds
| CLI Flag | Default | Description |
|---|---|---|
--min-pattern-count | 1 | Queries before a pattern is evaluated for optimization |
--refresh-interval-secs | 60 | How often to check for stale matviews (seconds) |
--pattern-ttl-secs | 604800 | Drop matviews for patterns not seen in this many seconds (0 = never expire) |
--max-tables-per-view | 6 | Max tables in a consolidated matview before splitting |
--max-columns-per-view | 30 | Max columns in a consolidated matview before splitting |
--deep-pagination-threshold | 1000 | OFFSET above this value triggers a warning |
--report-interval-secs | 10 | Seconds between stats report log entries |
Caching
| CLI Flag | Default | Description |
|---|---|---|
--result-cache-size | 65536 | Max entries in the local cache (LRU). 0 = unbounded. |
--prepared-cache-size | 1024 | Max prepared statements cached per connection |
--batch-cache-size | 64 | Max entries in the N+1 batch cache (LRU) |
--batch-cache-ttl-secs | 300 | TTL for batch cache entries in seconds (0 to disable) |
N+1 detection
| CLI Flag | Default | Description |
|---|---|---|
--n1-threshold | 5 | Queries within window before per-connection N+1 fires |
--n1-window-ms | 500 | Sliding window for N+1 detection (ms) |
--n1-cross-threshold | 10 | Queries within window before cross-connection N+1 fires |
Write acceleration
| CLI Flag | Default | Description |
|---|---|---|
--enable-async-commit | - | Async commits for faster writes — ~10ms durability window, matching MongoDB's default w:1 behavior |
--copy-threshold | 50 | Row count that triggers automatic COPY rewrite for bulk inserts (0 to disable) |
--parallel-copy-threshold | 10000 | Row count that triggers parallel COPY — splits bulk loads across multiple streams |
--parallel-copy-streams | 4 | Number of parallel COPY streams — increase for high-core systems with fast storage |
Connection pooling
| CLI Flag | Default | Description |
|---|---|---|
--pool-enabled | true | Enable connection pooling |
--pool-size | 20 | Max upstream connections in the pool |
--pool-mode | session | Pool mode: session or transaction. Auto-set to transaction when replicas/fallback configured. |
--pool-idle-timeout | 300 | Idle connection timeout in seconds |
--pool-timeout-secs | 30 | Seconds to wait for a pool slot before rejecting |
Exclusions
| CLI Flag | Description |
|---|---|
--exclude-tables | Comma-separated list of tables to exclude from optimization |
OIDC (SSO)
| CLI Flag | Description |
|---|---|
--oidc-issuer | OIDC provider URL (e.g. https://accounts.google.com or your Okta domain). Enables SSO for dashboard access. |
--oidc-client-id | OAuth client ID from your identity provider. |
--oidc-client-secret | OAuth client secret from your identity provider. |
--oidc-redirect-uri | OAuth callback URL. Defaults to dashboard URL + /auth/oidc/callback. |
SAML 2.0 (SSO)
| CLI Flag | Description |
|---|---|
--saml-idp-metadata-url | SAML Identity Provider metadata URL. Enables SAML SSO for dashboard access. |
--saml-sp-entity-id | Service Provider entity ID. Defaults to dashboard URL. |
--saml-acs-url | Assertion Consumer Service URL. Defaults to dashboard URL + /auth/saml/acs. |
Disable toggles
All strategies are enabled by default. Disable individually.
--disable-{feature}matviews Stop creating materialized viewsconsolidation Stop consolidating views with the same join graphbtree-indexes Stop creating B-tree indexestrigram-indexes Stop creating trigram indexes for LIKE queriestsvector-indexes Stop creating full-text search indexes for @@ queriesfuzzymatch-indexes Stop creating phonetic search indexes for soundex()/dmetaphone() queriespgvector-indexes Stop creating HNSW indexes for vector similarity queriesexpression-indexes Stop creating expression indexespartial-indexes Stop creating partial indexesrewrite Stop rewriting queries (observe and create only)prepared-cache Stop promoting rewritten queries to prepared statementsresult-cache Disable the local cachen1 Disable N+1 detection, prefetch, and batch servingn1-cross-connection Disable cross-connection N+1 detectionshadow-mode Skip matview verification — activate rewriting immediatelypool Disable connection pooling (1:1 client-to-upstream)notify Disable automatic NOTIFY write detection (NOTIFY now auto-enables when a management connection is available)Enable toggles
These strategies are disabled by default. Enable individually.
--enable-{feature}coalescing Share results for identical concurrent queries instead of sending duplicates upstream