Skip to main content

Configuration

Configure your ekoDB instance at runtime using the REST API. All configuration changes take effect immediately without requiring a restart.

Admin Access Required

Configuration endpoints require admin permissions.

API Endpoints​

Get Configuration​

Retrieve the current configuration:

GET /api/config
Authorization: Bearer {ADMIN_TOKEN}

Update Configuration​

Update one or more configuration options. Only the fields you include in the request body will be changed — all other settings remain unchanged.

PUT /api/config
Content-Type: application/json
Authorization: Bearer {ADMIN_TOKEN}

{
"use_typed_values": false,
"storage_mode": "balanced",
"durable_operations": true
}

Response:

{
"status": "success",
"message": "Configuration updated successfully"
}

Core Settings​

OptionTypeDefaultRangeDescription
use_typed_valuesBooleantrue—When true, responses include type metadata (e.g., {"type": "String", "value": "Alice"}). When false, returns plain values.
default_ttlInteger36000–604800Default time-to-live for new records in seconds. 0 disables expiration. Max 7 days (604,800 seconds).
token_expiry_hoursInteger11–168JWT token lifetime in hours. Max 7 days (168 hours).
encrypt_idsBooleantrue—Encrypt record IDs with AES-GCM. Disable only for testing/benchmarks.
access_modeString"read_write""read", "write", "read_write"Node access permissions. Use "read" for read replicas, "write" for write-only nodes.

Example — Configure a read-only replica:

{
"access_mode": "read",
"token_expiry_hours": 24
}

Storage & Durability​

Storage Mode​

OptionTypeDefaultValuesDescription
storage_modeString"fast""fast", "balanced"Record persistence strategy.
ModeDescriptionBest For
fastIn-memory primary with WAL-only persistenceLow-latency reads (default)
balancedLRU cache with periodic checkpoint batching to diskGeneral-purpose workloads

Durability & WAL​

OptionTypeDefaultRangeDescription
durable_operationsBooleantrue—When true, writes are fsynced to disk before responding. When false, writes are buffered and fsynced in the background for higher throughput.
insert_returns_recordBooleanfalse—When true, an insert echoes the full stored record (server-applied fields included) instead of just {id}. Costs a read; opt in per-request with ?return_record=true.
update_returns_recordBooleantrue—When true (default), an update returns the full merged record. When false, it returns {id, updated:true}. The merge already loads the record, so returning it is free.
delete_returns_recordBooleanfalse—When false (default), a delete returns the minimal {id, deleted:true} ack and skips loading the record body — the fast path. When true, it loads and returns the full deleted record. Override per-request with ?return_record=true.
group_commitsBooleantrue—Batch concurrent writes together with a single fsync. Dramatically improves throughput under concurrent load while maintaining durability.
group_commit_delay_msInteger20–100Batching window in milliseconds for group commits. Lower = lower latency, higher = more batching throughput.
group_commit_modeString"leader_election""leader_election", "channel"Group-commit completion strategy. "leader_election" (default, highest throughput): writers share a generation counter. "channel": each writer gets its own per-operation write result (per-write error isolation). Both are equally durable.
wal_shardsInteger41–16Number of parallel WAL shards for concurrent fsync. More shards = higher write throughput under concurrent load.
wal_max_retry_delay_msInteger300001000–300000Maximum exponential backoff delay for WAL write retries, in milliseconds. Caps the delay to prevent excessive wait times when many retries accumulate.
wal_group_commit_timeout_secsInteger305–300Timeout in seconds for the WAL group-commit flusher task. Writers are unblocked automatically if the flusher crashes or stalls.
wal_ship_interval_secsInteger51–3600Interval (seconds) between WAL-shipment passes to WAL-mode replicas. A cheap no-op unless a WAL-mode ripple is configured. See Ripples — WAL Mode.
wal_truncate_threshold_bytesIntegerMemory-scaled, up to 268435456 (256 MiB)≥ 65536Live-WAL size at which the background checkpoint flushes every durable store and truncates the WAL, so WAL size and restart replay time stay bounded with uptime. Applies on the next checkpoint without a restart. Not enforced while disable_maintenance is true. Values below 65536 are raised to 65536. Setting exactly 268435456 clears the override and the memory-scaled default applies; use 268435455 to pin the default's 256 MiB ceiling; larger values are accepted.

Example — Maximum write throughput:

{
"durable_operations": true,
"group_commits": true,
"group_commit_delay_ms": 5,
"group_commit_mode": "leader_election",
"wal_shards": 8
}

Example — Low-latency single-writer:

{
"durable_operations": true,
"group_commits": false
}
Disabling Durability

Setting durable_operations to false means data written within the last flush window (typically 0–1 second) may be lost on crash. Only disable for non-critical data like analytics or bulk ingestion.

Transactions​

OptionTypeDefaultRangeDescription
default_isolation_levelString"ReadUncommitted""ReadUncommitted", "ReadCommitted", "RepeatableRead", "Serializable"Server-wide default isolation level for a transaction that does not specify one. A per-transaction value (passed to begin) overrides it. ReadUncommitted (default) is the zero-cost fast path; higher levels validate more at commit. Changeable at runtime.

The default applies only when a transaction does not request a level. Official client methods now leave the level unset when it is omitted, so the server setting remains authoritative. See Transactions for the full semantics.


OptionTypeDefaultRangeDescription
max_vector_kInteger10001–1000000Upper bound a vector search's k (number of nearest neighbors) is clamped to. Bounds the result heap a single query can allocate.
max_ef_searchInteger40001–1000000Upper bound a vector search's HNSW ef_search (beam width) is clamped to. Bounds the per-query work a single search can demand.

A vector search request asking for a larger k or ef_search is clamped to these caps, so a single query cannot exhaust memory or CPU. Raise them via PUT /api/config if your workload genuinely needs larger values.


Resource Allocation​

OptionTypeDefaultRangeDescription
memory_allocation_percentInteger501–80Percentage of system RAM to use for database caching.
cpu_utilization_percentInteger10010–100Percentage of CPU cores to use for concurrent operations.

Guidelines:

ScenarioMemoryCPU
Dedicated database server50–70%100%
Shared server with other services25–40%50%
Background/minimal service10–20%25%

Example — Shared server configuration:

{
"memory_allocation_percent": 30,
"cpu_utilization_percent": 50
}

LLM Providers​

Configure LLM providers for Chat/RAG functionality. You can configure multiple providers and select which to use per chat session.

OpenAI​

OptionTypeDefaultDescription
openai_api_keyString—API key for OpenAI. Required to use OpenAI models.
openai_api_urlString"https://api.openai.com"Custom API URL for OpenAI-compatible APIs (e.g., LM Studio, Ollama).
openai_default_modelString—Default model for OpenAI chat sessions (e.g., "gpt-4", "gpt-4o").

Anthropic​

OptionTypeDefaultDescription
anthropic_api_keyString—API key for Anthropic. Required to use Anthropic models.
anthropic_api_urlString—Custom API URL for Anthropic.
anthropic_default_modelString—Default model (e.g., "claude-sonnet-4-5-20250929").
anthropic_default_versionString—Anthropic API version string.

Perplexity​

OptionTypeDefaultDescription
perplexity_api_keyString—API key for Perplexity. Required to use Perplexity models.
perplexity_api_urlString—Custom API URL for Perplexity.
perplexity_default_modelString—Default model for Perplexity chat sessions.

Gemini​

OptionTypeDefaultDescription
gemini_api_keyString—API key for Google Gemini. Required to use Gemini models.
gemini_api_urlString"https://generativelanguage.googleapis.com/v1beta/openai"Gemini's OpenAI-compatible endpoint. Override only if Google changes the URL.
gemini_default_modelString"gemini-2.5-flash"Default model for Gemini chat sessions.

Embedding​

The embedding endpoint is configured separately from chat, so a local embedding model can serve search while a remote LLM serves chat (or the other way round). The key and the URL fall back to the OpenAI setting of the same name; the model has its own default.

OptionTypeDefaultDescription
embedding_api_keyStringopenai_api_keyAPI key for the embedding provider.
embedding_api_urlStringopenai_api_urlOpenAI-compatible URL for embeddings (e.g. "http://localhost:1234" for LM Studio).
embedding_modelString"text-embedding-ada-002"The embedding model (e.g. "nomic-embed-text-v1.5" for a local model).

Example — Configure OpenAI with a local LM Studio endpoint:

{
"openai_api_key": "lm-studio",
"openai_api_url": "http://localhost:1234",
"openai_default_model": "llama-3.1-8b"
}

Example — Configure multiple providers:

{
"openai_api_key": "sk-...",
"openai_default_model": "gpt-4o",
"anthropic_api_key": "sk-ant-...",
"anthropic_default_model": "claude-sonnet-4-5-20250929"
}

Key verification on save​

A provider's key or URL changed through PUT /api/config is probed the moment it is saved — one call to the provider's models endpoint where the provider has one (Perplexity does not, and reports ok with verified: false), no retries, a 15-second budget — and the outcome comes back in the response as provider_checks, keyed by provider (openai, anthropic, perplexity, gemini, and embedding for the embedding endpoint):

{
"status": "success",
"message": "Configuration updated successfully",
"provider_checks": {
"openai": {
"status": "auth_failed",
"verified": true,
"http_status": 401,
"message": "Failed to fetch OpenAI models: 401 Unauthorized: ..."
}
}
}

The save itself never fails on a rejected key: a wrong key is something the response tells you, not something it refuses. The status vocabulary is the one GET /api/chat_models uses — see Provider status. Perplexity has no models endpoint and reports ok with verified: false.


Chat Settings​

Fine-tune chat/RAG behavior for each LLM provider. See Chat & RAG for usage.

General Chat Settings​

OptionTypeDefaultDescription
chat_max_context_snippetsInteger5Maximum number of context snippets returned from search results for each chat query.
chat_max_tokensInteger4096Maximum number of tokens for LLM responses.
chat_max_merged_messagesInteger10000Maximum messages to merge when loading chat history.

Provider Temperature & Sampling​

Control the creativity and determinism of LLM responses per provider.

OptionTypeDefaultRangeDescription
chat_openai_temperatureFloat0.60.0–2.0OpenAI response temperature. Lower = more focused.
chat_openai_top_pFloat1.00.0–1.0OpenAI nucleus sampling.
chat_anthropic_temperatureFloat1.00.0–1.0Anthropic response temperature.
chat_anthropic_top_pFloat0.990.0–1.0Anthropic nucleus sampling.
chat_perplexity_temperatureFloat0.20.0–2.0Perplexity response temperature.
chat_perplexity_top_pFloat0.90.0–1.0Perplexity nucleus sampling.

These settings control how chat queries use collection schemas to improve search results.

OptionTypeDefaultDescription
chat_schema_search_min_resultsInteger3Minimum text search results before triggering schema-based field matching.
chat_schema_search_min_word_lengthInteger3Minimum word length for query terms to be used in schema field matching.
chat_schema_field_match_scoreFloat0.5Score added when a query term matches a schema field name.
chat_field_name_boost_multiplierFloat0.3Score boost multiplier for results with matching field names.
chat_schema_sample_recordsInteger1Number of sample records to fetch when schema field names match the query.

Custom Collection Names​

Override the default collection names used by the chat system.

OptionTypeDefaultDescription
chat_configurations_collectionString"chat_configurations_{db_name}"Collection for storing chat session configurations.
chat_messages_collectionString"chat_messages_{db_name}"Collection for storing chat messages.

Write Performance Tuning​

Control which features run inline (synchronous) versus in the background during insert and update operations. Setting features to false defers them to background tasks for maximum write throughput.

Insert Features​

OptionTypeDefaultDescription
insert_features.search_indexBooleantrueUpdate text/vector search indexes inline during insert. When false, search indexes update asynchronously.
insert_features.query_indexBooleantrueUpdate query indexes inline during insert. When false, query indexes update asynchronously.
insert_features.constraintsBooleantrueRun schema constraint validation (unique, required, enum, min, max, regex) during insert. When false, constraints are skipped entirely.
insert_features.disk_cacheBooleantrueWrite to disk cache inline during insert. When false, disk cache writes are deferred (WAL still provides durability).

Update Features​

OptionTypeDefaultDescription
update_features.search_indexBooleantrueUpdate text/vector search indexes inline during update.
update_features.query_indexBooleantrueUpdate query indexes inline during update.
update_features.constraintsBooleantrueRun schema constraint validation during update.
update_features.disk_cacheBooleantrueWrite to disk cache inline during update.

Read Features​

Optional per-read work, runtime-tunable via PUT /api/config. Correctness-critical work (record visibility, TTL, auth) is never affected by these flags.

OptionTypeDefaultDescription
read_features.pattern_loggingBooleantrueRecord access patterns on each read to feed cache warming. When false, per-read access logging is skipped — use for warming-insensitive, read-heavy workloads (e.g. a fully in-memory working set).
read_features.io_metricsBooleantrueRecord per-read I/O metrics for analytics. When false, reads are not counted in I/O analytics.

Example — Maximum insert throughput (defer everything):

{
"insert_features": {
"search_index": false,
"query_index": false,
"constraints": false,
"disk_cache": false
}
}

Example — Fast inserts with constraints still enforced:

{
"insert_features": {
"search_index": false,
"query_index": false,
"constraints": true,
"disk_cache": false
}
}
When to Defer Features
  • Bulk ingestion: Defer all features for maximum throughput, then rebuild indexes after
  • No constraints needed: Skip constraints if the collection has no unique/required fields
  • Search not critical: Defer search indexing if real-time search isn't required

Security & Authentication​

OptionTypeDefaultRangeDescription
jwt_leeway_secondsInteger50–60Clock-skew tolerance for JWT token validation, in seconds. Allows tokens that expired up to this many seconds ago to still be accepted. Limits the replay-attack window if node clocks drift.

Rate Limiting​

Configure rate limiting for public (unauthenticated) endpoints.

OptionTypeDefaultRangeDescription
public_endpoint_rate_limit_enabledBooleantrue—Enable rate limiting on public endpoints (/api/health, /api/auth/register, /api/auth/token).
public_endpoint_rate_limit_per_minuteInteger6010–300Maximum requests per IP per minute for public endpoints.
admin_key_rate_limit_per_minuteInteger51–60Maximum requests per IP per minute for admin key endpoints (/api/auth/*/admin_key). Kept intentionally low to resist brute-force attacks on admin credentials.
Authenticated Rate Limits

Rate limits for authenticated API endpoints are determined by your deployment tier. See Security - Rate Limiting for tier details.


Functions​

OptionTypeDefaultDescription
functions_collectionString"functions_{db_name}"Collection name for storing scheduled functions.
environment_varsObject{}Key-value pairs accessible in functions via {{env.VAR_NAME}} syntax.

Example — Set function environment variables:

{
"environment_vars": {
"WEBHOOK_URL": "https://api.example.com/webhook",
"AUTH_TOKEN": "token123"
}
}

Maintenance​

OptionTypeDefaultDescription
disable_maintenanceBooleanfalseDisable periodic background maintenance tasks (cache cleanup, compaction). Only disable for benchmarking.

Full Configuration Example​

Here's an example configuring a production instance with multiple LLM providers, tuned durability, and resource limits:

curl -X PUT https://{EKODB_API_URL}/api/config \
-H "Authorization: Bearer {ADMIN_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"use_typed_values": true,
"token_expiry_hours": 1,
"default_ttl": 3600,
"storage_mode": "fast",
"durable_operations": true,
"group_commits": true,
"group_commit_delay_ms": 2,
"wal_shards": 4,
"wal_max_retry_delay_ms": 30000,
"wal_group_commit_timeout_secs": 30,
"jwt_leeway_seconds": 5,
"admin_key_rate_limit_per_minute": 5,
"memory_allocation_percent": 50,
"cpu_utilization_percent": 100,
"openai_api_key": "sk-...",
"openai_default_model": "gpt-4o",
"chat_max_context_snippets": 5,
"chat_max_tokens": 4096,
"public_endpoint_rate_limit_enabled": true,
"public_endpoint_rate_limit_per_minute": 60,
"insert_features": {
"search_index": true,
"query_index": true,
"constraints": true,
"disk_cache": true
}
}'