Configuration
Every knob you'll realistically touch, per component, with its default. Everything ships with working local defaults; you only set what you change.
How configuration works
Java components read an environment variable first, then fall back to a system property (OMS_HTTP_PORT beats -Doms.http.port). Secrets additionally accept a *_FILE variant that reads the value from a file, so nothing sensitive has to sit in the environment. The full exhaustive reference (including constants you'll rarely touch) lives in the match repo: docs/CONFIGURATION.md.
OMS (the API your apps call)
| Setting | Default | What it does |
|---|---|---|
OMS_HTTP_PORT | 8080 | REST API and Prometheus /metrics |
OMS_GRPC_PORT | 9090 | gRPC API |
OMS_AUTH_MODE | api-key | api-key (secure default: no keys configured means every request is rejected), jwt, or dev (accepts everything; local only) |
OMS_API_KEYS / _FILE | empty | API keys for api-key mode |
OMS_JWT_SECRET / _FILE | empty | HS256 secret for jwt mode |
OMS_POSTGRES_URL | jdbc:postgresql://localhost:5432/oms | The ledger database |
OMS_POSTGRES_PASSWORD / _FILE | none | No default. Without valid credentials the OMS runs in-memory only, on purpose (see quick start for schema setup) |
OMS_REDIS_HOST / _PORT | localhost / 6379 | Balance cache; falls back to in-memory if unreachable |
OMS_CORS_ORIGINS | empty | CORS allowlist for browsers calling the REST API |
OMS_AUDIT_LOG | oms-audit.log | Audit log path (off disables) |
OMS_CLUSTER_INGRESS | localhost:9000 | Where the matching cluster listens |
Cluster node (match)
| Setting | Default | What it does |
|---|---|---|
CLUSTER_NODE | 0 | This member's node id (0, 1, 2) |
CLUSTER_ADDRESSES | localhost | Comma-separated member addresses |
CLUSTER_PORT_BASE | 9000 | Base port; node N uses base + 100 × N upward |
BASE_DIR | <cwd>/node<N> | Cluster data directory (log, archive, mark files) |
METRICS_PORT | 9500 + node id | Prometheus metrics for that node |
MATCH_ENGINE_IMPL | array | Matching engine: array (default) or direct (older fallback) |
-Dmatch.engine.book.capacity | 131072 | Resting orders per side; hitting it is a loud BOOK_FULL reject, never silent loss |
Transport / media driver
Aeron moves the bytes. Two profiles matter: dev (shared threads, polite on a laptop) and prod (busy-spin, burns cores, lowest latency).
| Setting | Default | What it does |
|---|---|---|
TRANSPORT_DRIVER_MODE | embedded | embedded (driver inside the JVM, simplest) or external (standalone driver process; the production mode) |
TRANSPORT_IDLE_MODE | busy_spin | busy_spin for lowest latency, backoff for dev machines and CI |
TRANSPORT_TERM_LENGTH | 16m | Aeron term buffer; smaller (1m) for constrained boxes |
ENGINE_DRIVER_PROFILE | dev | (Read by the admin gateway) dev or prod driver tuning for the nodes it launches |
Admin gateway
| Setting | Default | What it does |
|---|---|---|
MATCH_PROJECT_DIR | auto (sibling layout) | Where the match checkout lives. Set explicitly if your layout differs from the quick start's |
OMS_PROJECT_DIR | sibling order-management/ | Where the oms checkout lives |
ADMIN_PORT | 8082 | Operations API port |
ADMIN_BIND | 127.0.0.1 | Bind address. Refuses to bind beyond loopback unless a token is set |
ADMIN_AUTH_TOKEN / _FILE | empty | Bearer token for the ops API; empty means loopback-only dev mode |
ADMIN_LOG_FORMAT | json | Structured json or human text logs |
Trading UI
These are baked in at build time (npm run build), not read at runtime:
| Setting | Default | What it does |
|---|---|---|
VITE_ORDER_API_URL | same origin | OMS REST base URL |
VITE_MARKET_WS_URL | same origin | Market-data WebSocket base URL |
VITE_ADMIN_API_URL | same origin | Admin API base URL |
VITE_AUTH_TOKEN | dev:1 | Bearer token; the default only works against OMS_AUTH_MODE=dev |
Cross-repo gotchas
- Two egress ports by design: the market gateway consumes cluster egress on
9091, the OMS on9093. Two consumers can't share one port. - Set
CLUSTER_ADDRESSESexplicitly in any real deployment; the defaults differ slightly between components and only line up on localhost. - Socket buffers are not optional:
net.core.rmem_max/wmem_max = 16 MB(see the quick start), or replay channels stall and elections hang. - Engine tunables are the exception to env-first:
match.engine.implandmatch.engine.book.capacityprefer the system property.
When in doubt
The defaults are the configuration we run in development every day. Change one thing at a time, and check
/api/admin/status after each change.