← Docs

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.

goldlapel.toml
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:

  1. CLI flags (--mode waiter)
  2. Shell environment variables (GOLDLAPEL_MODE=waiter)
  3. .env file in the working directory
  4. goldlapel.toml config file
  5. 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:

.env
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.

goldlapel.toml
[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.

goldlapel.toml
[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 FlagDefaultDescription
--upstreamlocalhost:5432Postgres connection string or host:port
--proxy-port7932Port Gold Lapel listens on (--port and GOLDLAPEL_PORT still work as aliases)
--modewaiterOperating mode: waiter (full optimization) or bellhop (observe only)
--dashboard-portproxy-port + 1Web dashboard port — auto-derives from proxy-port (default 7933). Set to 0 to disable.
--invalidation-portproxy-port + 2L1 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-timeout60Seconds 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-decodingtrueSubscribe to PostgreSQL WAL for write detection (requires wal_level=logical, falls back to NOTIFY)
--notify-fallbackfalseForce 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.
--verbosefalseEnable verbose INFO-level logging (default: clean banner only)

Replicas & failover

CLI FlagDefaultDescription
--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-secs5Seconds after a write to keep reads on primary

TLS

CLI FlagDescription
--tls-certPEM certificate file for client-facing TLS
--tls-keyPEM private key file for client-facing TLS
--tls-client-caPEM CA file for mTLS client certificate verification

L1 — Native cache

CLI FlagDefaultDescription
--l1-enabledtrueEnable L1 native cache (subscriber-based invalidation)
--l1-cache-size32768Max entries in the L1 native cache (LRU). Proxy sends configured value to wrappers automatically via invalidation protocol.
--l1-subscriber-connections1Number of WAL subscriber connections

L2 — Proxy cache

CLI FlagDefaultDescription
--l2-result-cachetrueEnable L2 result cache
--l2-result-cache-size65536Max cached query results
--l2-prepared-cachetrueEnable prepared statement cache
--l2-prepared-cache-size1024Max cached prepared statements

L3 — Materialized views & indexes

CLI FlagDefaultDescription
--l3-matviewstrueEnable materialized view creation
--l3-indexestrueEnable automatic index creation
--l3-threshold1Minimum pattern hits before materializing
--l3-refresh-interval60Seconds between matview refreshes
--l3-shadow-verificationtrueVerify matview correctness before routing

SQL optimization

CLI FlagDefaultDescription
--sql-rewritetrueEnable transparent query rewriting
--sql-join-reordertrueOptimize JOIN order
--sql-subquery-flattentrueFlatten correlated subqueries
--sql-predicate-pushdowntruePush predicates into subqueries

Thresholds

CLI FlagDefaultDescription
--min-pattern-count1Queries before a pattern is evaluated for optimization
--refresh-interval-secs60How often to check for stale matviews (seconds)
--pattern-ttl-secs604800Drop matviews for patterns not seen in this many seconds (0 = never expire)
--max-tables-per-view6Max tables in a consolidated matview before splitting
--max-columns-per-view30Max columns in a consolidated matview before splitting
--deep-pagination-threshold1000OFFSET above this value triggers a warning
--report-interval-secs10Seconds between stats report log entries

Caching

CLI FlagDefaultDescription
--result-cache-size65536Max entries in the local cache (LRU). 0 = unbounded.
--prepared-cache-size1024Max prepared statements cached per connection
--batch-cache-size64Max entries in the N+1 batch cache (LRU)
--batch-cache-ttl-secs300TTL for batch cache entries in seconds (0 to disable)

N+1 detection

CLI FlagDefaultDescription
--n1-threshold5Queries within window before per-connection N+1 fires
--n1-window-ms500Sliding window for N+1 detection (ms)
--n1-cross-threshold10Queries within window before cross-connection N+1 fires

Write acceleration

CLI FlagDefaultDescription
--enable-async-commit-Async commits for faster writes — ~10ms durability window, matching MongoDB's default w:1 behavior
--copy-threshold50Row count that triggers automatic COPY rewrite for bulk inserts (0 to disable)
--parallel-copy-threshold10000Row count that triggers parallel COPY — splits bulk loads across multiple streams
--parallel-copy-streams4Number of parallel COPY streams — increase for high-core systems with fast storage

Connection pooling

CLI FlagDefaultDescription
--pool-enabledtrueEnable connection pooling
--pool-size20Max upstream connections in the pool
--pool-modesessionPool mode: session or transaction. Auto-set to transaction when replicas/fallback configured.
--pool-idle-timeout300Idle connection timeout in seconds
--pool-timeout-secs30Seconds to wait for a pool slot before rejecting

Exclusions

CLI FlagDescription
--exclude-tablesComma-separated list of tables to exclude from optimization

OIDC (SSO)

CLI FlagDescription
--oidc-issuerOIDC provider URL (e.g. https://accounts.google.com or your Okta domain). Enables SSO for dashboard access.
--oidc-client-idOAuth client ID from your identity provider.
--oidc-client-secretOAuth client secret from your identity provider.
--oidc-redirect-uriOAuth callback URL. Defaults to dashboard URL + /auth/oidc/callback.

SAML 2.0 (SSO)

CLI FlagDescription
--saml-idp-metadata-urlSAML Identity Provider metadata URL. Enables SAML SSO for dashboard access.
--saml-sp-entity-idService Provider entity ID. Defaults to dashboard URL.
--saml-acs-urlAssertion Consumer Service URL. Defaults to dashboard URL + /auth/saml/acs.

Disable toggles

All strategies are enabled by default. Disable individually.

Naming pattern: --disable-{feature}
matviews Stop creating materialized views
consolidation Stop consolidating views with the same join graph
btree-indexes Stop creating B-tree indexes
trigram-indexes Stop creating trigram indexes for LIKE queries
tsvector-indexes Stop creating full-text search indexes for @@ queries
fuzzymatch-indexes Stop creating phonetic search indexes for soundex()/dmetaphone() queries
pgvector-indexes Stop creating HNSW indexes for vector similarity queries
expression-indexes Stop creating expression indexes
partial-indexes Stop creating partial indexes
rewrite Stop rewriting queries (observe and create only)
prepared-cache Stop promoting rewritten queries to prepared statements
result-cache Disable the local cache
n1 Disable N+1 detection, prefetch, and batch serving
n1-cross-connection Disable cross-connection N+1 detection
shadow-mode Skip matview verification — activate rewriting immediately
pool 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.

Naming pattern: --enable-{feature}
coalescing Share results for identical concurrent queries instead of sending duplicates upstream