muscles

Configuration variables

The server reads these environment variables. A value in muscles.yaml under the key in the third column applies when the variable is not set.

Server / HTTP

VariableYAML keyDefaultDescription
MUSCLES_HTTP_PORThttp.port18080TCP port the HTTP server listens on.
MUSCLES_HTTP_ADDRhttp.addr127.0.0.1Address the HTTP server binds to.
MUSCLES_LISTEN_SOCKEThttp.listen_socket(unset)Path of a Unix domain socket to listen on instead of a TCP port.
MUSCLES_DRAIN_TIMEOUTlifecycle.drain_timeout30sHow long in-flight requests get to finish after SIGTERM, as a duration such as 45s or 2m.
MUSCLES_HTTP_GZIPhttp.gziptrueCompresses responses with gzip for clients that send Accept-Encoding: gzip.
MUSCLES_HTTP_GZIP_MIN_BYTEShttp.gzip_min_bytes1024Smallest response body, in bytes, that the server compresses.
MUSCLES_HTTP_READ_TIMEOUT_MShttp.read_timeout_ms15000Time in milliseconds a client has to send a whole request, head and body, before the server closes the connection.
MUSCLES_HTTP_WRITE_TIMEOUT_MS15000Time in milliseconds the socket may refuse a response slice before the server closes the connection.
MUSCLES_HTTP_RESPONSE_MAX_MS1800000 (30 min)Longest time in milliseconds the server spends writing one buffered response before it cuts the connection.
MUSCLES_HTTP_STREAM_MIN_BYTES65536Least number of bytes a streaming reader must take in each window set by MUSCLES_HTTP_STREAM_MIN_WINDOW_MS, or the server disconnects it.
MUSCLES_HTTP_STREAM_MIN_WINDOW_MS30000Length in milliseconds of the write-time window for MUSCLES_HTTP_STREAM_MIN_BYTES.
MUSCLES_HTTP_WORKERShttp.workers32Number of threads that accept and serve connections on the shared listener.
MUSCLES_HTTP_KEEPALIVE_TIMEOUT_MShttp.keepalive_timeout_ms5000How long an idle persistent connection waits for its next request, in milliseconds.
MUSCLES_HTTP_KEEPALIVE_MAX_REQUESTShttp.keepalive_max_requests100Most requests the server handles on one persistent connection before it closes the connection.
MUSCLES_HTTP_MAX_CONN_PER_IPhttp.max_conn_per_ip0 (off)Most simultaneous connections one client IP address may hold, so a few slow clients cannot occupy every worker.
MUSCLES_HTTP_MAX_HEAD_CONN_PER_IP8Most connections per IP address that may still be reading their first request before authentication, beyond which the request must arrive within 250 ms.

Authentication & RBAC

VariableYAML keyDefaultDescription
MUSCLES_AUTH_SECRETauth.secret(none)Key that signs session tokens.
MUSCLES_INTERNAL_SECRETauth.internal_secret(none)Key that signs /internal/* requests between nodes, such as query fragments, forwarded ingest and drain.
MUSCLES_AUTH_DEV_INSECUREauth.dev_insecurefalseFor local development only: lets the server start without a secret and accept any login.
MUSCLES_ADMINSauth.admins(empty)Comma-separated user names with administrator rights, or a file that lists them.
MUSCLES_VIEWERSauth.viewers(empty)Comma-separated identities that may sign in through OIDC as viewers.
MUSCLES_METRICS_TOKEN_FILEauth.metrics_token_file(none)File holding the bearer token that /metrics and /statusz require.
MUSCLES_USERS_FILEauth.users_file(none)File of local users, one username:role:hash line each with an Argon2id password hash, which enables password login.
MUSCLES_TRUST_PROXY_AUTHauth.trust_proxy_authfalseTrusts the user name that a co-located oauth2-proxy sends in X-Auth-Request-Email or X-Forwarded-User.
MUSCLES_CH_HTTP_STRICT_SETTINGShttp.ch_http_strict_settingsfalseRefuses ClickHouse HTTP URL settings that muscles does not support, with error code 115.
MUSCLES_SESSION_MAX_MSauth.session_max_ms86400000 (24 h)Longest lifetime of a login session in milliseconds, from 1 to 31536000000.
MUSCLES_TRUSTED_PROXIESauth.trusted_proxies(empty)Comma-separated addresses or address/prefix blocks of the reverse proxies whose X-Forwarded-For header names the client for login throttling.

Native OAuth2 / OIDC login

VariableYAML keyDefaultDescription
MUSCLES_OAUTH_ENABLEDoauth.enabledfalseTurns on OIDC sign-in.
MUSCLES_OAUTH_ISSUERoauth.issuer(none)Base URL of the OIDC issuer, such as https://idp.example.com.
MUSCLES_OAUTH_DISCOVERY_URLoauth.discovery_url(derived)Discovery URL to use instead of the one derived from the issuer.
MUSCLES_OAUTH_CLIENT_IDoauth.client_id(none)Client ID registered for muscles at the identity provider.
MUSCLES_OAUTH_CLIENT_SECREToauth.client_secret(none)Client secret registered at the identity provider.
MUSCLES_OAUTH_REDIRECT_URIoauth.redirect_uri(none)Callback URL registered at the identity provider, matched exactly, such as https://muscles.example.com/oauth2/callback.
MUSCLES_OAUTH_PATH_PREFIXoauth.path_prefix/oauth2Base path of the login and callback routes, which are <prefix>/login and <prefix>/callback.
MUSCLES_OAUTH_SCOPESoauth.scopesopenid email profileSpace-separated OIDC scopes to request.
MUSCLES_OAUTH_ALLOWED_DOMAINSoauth.allowed_domains(none)Comma-separated email domains allowed to sign in.
MUSCLES_OAUTH_REQUIRE_VERIFIED_EMAILoauth.require_verified_emailtrueRejects sign-ins whose token has email_verified=false.
MUSCLES_OAUTH_IDENTITY_CLAIMoauth.identity_claimemailID-token claim that names the user, one of email, preferred_username or sub.
MUSCLES_OAUTH_UNLISTED_ROLEoauth.unlisted_rolenoneRole given to an OIDC user who is not in MUSCLES_ADMINS, MUSCLES_VIEWERS or the users file, either none or viewer.
MUSCLES_OAUTH_AUTHORIZE_URLoauth.{authorize,token,jwks}_url(discovery)Authorize, token and JWKS URLs to use instead of the discovered ones.
MUSCLES_OAUTH_INSECURE_TLSoauth.insecure_tlsfalseFor development only: skips TLS verification for calls to the identity provider.

Federation — external-source connectors

VariableYAML keyDefaultDescription
MUSCLES_FEDERATION_CONFIG(unset, so off)Path of a YAML file that declares external tables in an external_tables: list.
MUSCLES_FEDERATION_ALLOW_INLINE_SECREToffFor development only: lets CREATE EXTERNAL TABLE carry a password in the statement instead of the name of an environment variable.

Storage & durability

VariableYAML keyDefaultDescription
MUSCLES_PARTS_DIRstorage.parts_dirmuscles-data/partsDirectory where flushed parts are stored.
MUSCLES_WAL_DIRwal.dirmuscles-data/walDirectory for write-ahead log segments, with one subdirectory per table.
MUSCLES_WAL_ON_CORRUPTIONfailWhat recovery does with a corrupt write-ahead log frame that was already fsynced, either fail or salvage.
MUSCLES_DATA_DIR_MODE_CHECKrefuseStartup check on the permissions of the data directories, with the values refuse, warn and off.
MUSCLES_RECOVERY_THREADS0 (auto)Threads that read and validate part manifests in parallel at boot.
MUSCLES_MV_STALE_WAL_MAX_BYTESstorage.mv_stale_wal_max_bytes0 (off)Size in bytes of the write-ahead log that a stale materialized view may hold before the server drops that view.
MUSCLES_PART_CODECstorage.part_codeclz4Default compression chain for newly written parts, which a column's CODEC(...) overrides.
MUSCLES_PART_BLOCK_MAX_BYTESstorage.part_block_max_bytes32 MiBLargest column block in bytes, which also limits a single cell to half of that size.
MUSCLES_SCAN_PREFETCHstorage.scan_prefetch_depth0 (OFF)Number of upcoming granules whose column blocks a scan reads ahead while it decodes the current granule.
MUSCLES_QUERY_PARALLELISMstorage.query_parallelism1 for other queries, effective CPU count for KNNWorker threads for one single-node SELECT scan.
MUSCLES_INSERT_DEDUP_WINDOWingest.insert_dedup_window1000Number of recent INSERT block ids each table remembers, so a retried INSERT is acknowledged without storing its rows again.
MUSCLES_MIGRATE_FROM_TOKENnoneunsetBearer token muscles migrate sends to the source server when --from-token and --token are absent.
MUSCLES_MIGRATE_TO_TOKENnoneunsetBearer token muscles migrate sends to the target server when --to-token and --token are absent.
MUSCLES_FLUSH_MAX_ROWSflush.max_rows1048576Flushes a table's segment once this many rows are unflushed.
MUSCLES_FLUSH_INTERVAL_MSflush.interval_ms60000Flushes a table this many milliseconds after its previous flush, even below MUSCLES_FLUSH_MAX_ROWS.
MUSCLES_FLUSH_POLL_MSflush.poll_ms1000How often the background flusher checks whether a table must be flushed, in milliseconds.
MUSCLES_MEMTABLE_MAX_BYTESstorage.memtable_seal_bytesa 32nd of the effective memory limit, from 8 MiB to 256 MiBSize in bytes at which a table's in-memory data is sealed, given as a plain number without a suffix.
MUSCLES_MERGE_ENABLED1Set 0 to stop background merges in an emergency, for example when merges run the node out of memory.
MUSCLES_IVF_MIN_ROWSstorage.ivf_min_rows2048 (rows)Smallest number of rows a sealed part needs before muscles builds a vector index for its vector columns.
MUSCLES_QUERY_PROFILE_MAXquery.profile_max256How many finished per-query plan graphs the server keeps in memory, dropping the oldest first.
MUSCLES_QUERY_PROGRESSquery.progress1 (ON)Turns on live per-query progress reports that stream over SSE.
MUSCLES_QUERY_PROGRESS_INTERVAL_MSquery.progress_interval_ms100How often progress samples are sent over SSE, in milliseconds, limited to the range 20 to 2000.
MUSCLES_PART_LOG_MAX_ROWS100000Most rows system.part_log keeps, where 0 turns the log off.
MUSCLES_PART_LOG_TTL_DAYS7Age in days after which system.part_log rows expire, where 0 keeps them until the row cap removes them.
MUSCLES_TRACE_LOG_MAX_ROWS100000Most rows system.trace_log keeps, where 0 turns the log off.
MUSCLES_TRACE_LOG_TTL_DAYS7Age in days after which system.trace_log rows expire, where 0 keeps them until the row cap removes them.
MUSCLES_PROCESSORS_PROFILE_LOG_MAX_ROWS100000Most rows system.processors_profile_log keeps, where 0 turns the log off.
MUSCLES_PROCESSORS_PROFILE_LOG_TTL_DAYS7Age in days after which system.processors_profile_log rows expire, where 0 keeps them until the row cap removes them.
MUSCLES_QUERY_HISTORY1 (ON)Archives every query durably in system.query_history, where 0 turns it off.
MUSCLES_QUERY_HISTORY_TTL_DAYS30Age in days after which archived queries expire, where 0 means no age limit.
MUSCLES_QUERY_HISTORY_MAX_ROWS100000Most archived queries kept in system.query_history, dropping the parts with the oldest rows first.
MUSCLES_QUERY_HISTORY_SYNCgroupHow the query history is committed to disk, one of sync, group or off.
MUSCLES_QUERY_HISTORY_PLAN_BYTES16384Largest query plan in bytes that is archived with a query.
MUSCLES_QUERY_HISTORY_END_USER1 (ON)Records the end-user name that a trusted proxy forwards.

Ingestion

VariableYAML keyDefaultDescription
MUSCLES_KAFKA_BOOTSTRAPingest.kafka.bootstrap(unset, so ingest is off)Host of the Kafka bootstrap broker, which turns ingestion on when set.
MUSCLES_KAFKA_PORTingest.kafka.port9092Port of the Kafka broker.
MUSCLES_KAFKA_SHARE_GROUPingest.kafka.share_group(default group)Name of the KIP-932 share group that this node joins as one member.
MUSCLES_KAFKA_TOPICSingest.kafka.topics(discover)Comma-separated list of topics to ingest, or a YAML list.
MUSCLES_KAFKA_MAX_DECOMPRESSED_BYTESingest.kafka.max_decompressed_bytes64 MiBLargest size in bytes that a compressed record batch may inflate to before it is rejected.
MUSCLES_KAFKA_POLL_MSingest.kafka.poll_ms500Pause in milliseconds between ingest cycles once the node has caught up.
MUSCLES_KAFKA_RECONNECT_BACKOFF_MSingest.kafka.reconnect_backoff_ms1000First wait in milliseconds before reconnecting to a failed broker, doubling on each retry up to the maximum.
MUSCLES_KAFKA_MAX_BACKOFF_MSingest.kafka.max_backoff_ms30000Longest wait in milliseconds between broker reconnect attempts.
MUSCLES_KAFKA_READ_TIMEOUT_MSingest.kafka.read_timeout_ms30000Time in milliseconds a broker response read may make no progress before it counts as a transient error.
MUSCLES_KAFKA_MAX_TOPICSingest.kafka.max_topics64Most topics tracked, beyond which topics are not ingested.
MUSCLES_KAFKA_MAX_PARTITIONSingest.kafka.max_partitions256Most partitions tracked per topic, beyond which partitions are not ingested.
MUSCLES_KAFKA_FORWARD_DEADLINE_MSingest.kafka.forward_deadline_ms10000Time in milliseconds to connect to the owning shard and receive its durable acknowledgement when forwarding a record.
MUSCLES_KAFKA_TOPIC_MAX_FAILURESingest.kafka.topic_max_failures3Consecutive unrecoverable errors after which a topic is quarantined.
MUSCLES_KAFKA_QUARANTINE_COOLDOWN_MSingest.kafka.quarantine_cooldown_ms60000How long a quarantined topic stays skipped before one probe cycle.
MUSCLES_KAFKA_FORWARD_INBOX_RECORDSingest.kafka.forward_inbox_records4096Most forwarded records a shard holds unprocessed before it answers new forwards with 503.
MUSCLES_KAFKA_FORWARD_INBOX_BYTESingest.kafka.forward_inbox_bytes64 MiBMost forwarded bytes a shard holds unprocessed before it answers new forwards with 503.
MUSCLES_KAFKA_STORE_OFFSETingest.kafka.store_offsetoffAdds the columns _kafka_partition, _kafka_offset and _kafka_topic to every Kafka row so you can check for gaps.
MUSCLES_KAFKA_EAGER_TABLESingest.kafka.eager_tablesonCreates a discovered topic's table from its Schema Registry subject at discovery, before this node consumes a record.
MUSCLES_SCHEMA_POLICYingest.schema_policyevolveSchema policy for ingested topics, either evolve or strict, in any letter case.
MUSCLES_SCHEMA_REGISTRY_HOSTingest.schema_registry_host127.0.0.1Host of the Confluent Schema Registry that resolves Avro schemas.
MUSCLES_SCHEMA_REGISTRY_PORTingest.schema_registry_port18085Port of the Schema Registry.
MUSCLES_KAFKA_KEYED_INGESTcluster.keyed_ingestoffSends each Kafka record to the shard that owns its shard key.
MUSCLES_KAFKA_KEYED_DEDUP_TARGETSoffSet to 1 to declare that every keyed topic writes to a KAFKA DEDUP or Replacing table.
MUSCLES_KAFKA_INGEST_THREADScluster.kafka_ingest_threads1Consumer threads per shard in keyed mode, at most 32.
MUSCLES_KAFKA_ALIGNEDcluster.kafka_alignedoffDeclares that producers partition keyed topics with a hash that matches shardOf, which is Wyhash modulo the shard count.

Topic-owner metadata

VariableYAML keyDefaultDescription
MUSCLES_TOPIC_METADATAtopic_metadata: (structured block)(none)Owner, contact, team and other keys for each topic, shown when you hover the source node in the pipeline view.

Query governor & limits

VariableYAML keyDefaultDescription
MUSCLES_MAX_EXECUTION_TIME_MSquery.max_execution_time_ms0Longest time in milliseconds one query may run.
MUSCLES_MAX_ROWS_TO_READquery.max_rows_to_read0Most rows one query may scan.
MUSCLES_MAX_RESULT_ROWSquery.max_result_rows0Most rows one query may return.
MUSCLES_MAX_MEMORY_BYTESquery.max_memory_byteshalf the effective memory limitBytes one query may hold.
MUSCLES_MAX_TOTAL_QUERY_MEMORY_BYTESquery.max_total_query_memory_bytesthree quarters of the effective memory limitBytes all running queries may hold together.
MUSCLES_MAX_BYTES_BEFORE_EXTERNAL_GROUP_BYquery.max_bytes_before_external_group_by0Size of aggregate state in bytes at which a GROUP BY writes its groups to temporary files instead of failing.
MUSCLES_MAX_BYTES_BEFORE_EXTERNAL_SORTquery.max_bytes_before_external_sort0Size of buffered ORDER BY rows in bytes at which a sort writes sorted runs to temporary files instead of failing.
MUSCLES_MAX_TEMP_SPACE_BYTESquery.max_temp_space_bytes8589934592 (8 GiB)Bytes of GROUP BY and ORDER BY spill files all queries may hold on disk together.
MUSCLES_SPILL_DIRquery.spill_dirspill next to MUSCLES_PARTS_DIRDirectory for GROUP BY and ORDER BY spill files, one subdirectory per running query.
MUSCLES_MAX_CONCURRENT_QUERIESquery.max_concurrent_queries0Most queries that may run at once on the server.
MUSCLES_IMPORT_DIRquery.import_dirempty (off)Directory that IMPORT PARQUET '<path>' INTO <table> may read local files from.
MUSCLES_EXPORT_DIRquery.export_dirempty (off)Directory that Parquet exports with INTO OUTFILE may write to.
MUSCLES_PARQUET_MAX_DECODED_BYTESquery.parquet_max_decoded_bytes2147483648 (2 GiB)Most memory in bytes that one decoded Parquet file may hold during an import or an Iceberg read.
MUSCLES_MAX_QUERY_ROWSquery.max_query_rows1000000Default limit on the rows a query returns, from 1 to 1000000000.
MUSCLES_RULES_MAXrules.max64Most recording rules one node holds.
MUSCLES_RULE_MAX_SERIESrules.max_series1000Most series one recording rule evaluation may export (rows times numeric columns).
MUSCLES_RULES_MAX_SERIES_TOTALrules.max_series_total10000Most series all recording rules on the node may export together.

Alert delivery

VariableYAML keyDefaultDescription
MUSCLES_ALERTMANAGER_URLSalerting.alertmanager_urlsunsetComma-separated Alertmanager base URLs, at most 8, such as http://alertmanager:9093.
MUSCLES_ALERTMANAGER_AUTH_FILEalerting.alertmanager_auth_fileunsetFile whose trimmed content is sent as the Authorization header to every Alertmanager, for example Basic dXNlcjpwYXNz or Bearer <token>.
MUSCLES_ALERT_WEBHOOK_URLSalerting.webhook_urlsunsetComma-separated webhook URLs, at most 8.
MUSCLES_ALERT_WEBHOOK_AUTH_FILEalerting.webhook_auth_fileunsetLike MUSCLES_ALERTMANAGER_AUTH_FILE, for every webhook.
MUSCLES_ALERT_RESEND_INTERVAL_Salerting.resend_interval_s60How often, in seconds, an unchanged firing or resolved alert is sent again.
MUSCLES_ALERT_DELIVERY_TIMEOUT_MSalerting.delivery_timeout_ms10000Time in milliseconds one delivery request may take to connect, send and read the reply.
MUSCLES_ALERT_DELIVERY_RETRIESalerting.delivery_retries3Extra attempts after a timeout, transport error, 429 or 5xx reply, waiting from 0.5 s up to 10 s.
MUSCLES_ALERT_QUEUE_CAPACITYalerting.queue_capacity10000Alerts one target may hold waiting for delivery; past it the oldest is dropped and counted.

Resource-priority scheduling

VariableYAML keyDefaultDescription
MUSCLES_SCHED_PRIORITYscheduling.priorityoffWhether ingest gets the CPU ahead of queries under contention, with the values off, cooperative and on.
MUSCLES_SCHED_YIELD_SPINSscheduling.yield_spins32Most CPU hand-offs a deferred scan batch makes before it runs, from 0 to 4096.
MUSCLES_SCHED_MAX_YIELD_MSscheduling.max_yield_ms1000Total time in milliseconds a query may be deferred for ingest before it stops yielding.

Distributed query

VariableYAML keyDefaultDescription
MUSCLES_DQ_TIMEOUT_MSquery.distributed.timeout_ms10000Time budget in milliseconds for a whole distributed query.
MUSCLES_DQ_MAX_FRAGMENT_BYTESquery.distributed.max_fragment_bytes256 MiBLargest response in bytes that one query fragment may send or receive.
MUSCLES_DQ_DISTINCT_MAXquery.distributed.distinct_max1048576Most COUNT(DISTINCT) values kept per aggregate and fragment.
MUSCLES_DQ_CONSISTENCYquery.distributed.consistencyfullDefault read consistency when a request has no ?consistency= parameter, either full or partial.
MUSCLES_DQ_CHUNK_ROWSquery.distributed.chunk_rows0 (8192)Rows per chunk of a streamed fragment, which limits coordinator memory.
MUSCLES_DQ_COMPRESSquery.distributed.compressfalseCompresses each fragment chunk with lz4.

User-defined tiered disks

VariableYAML keyDefaultDescription
MUSCLES_DISKSstorage.disks(none)Comma-separated list of data disks as name:path[:capacity], such as fast:/mnt/nvme:500Gi.
MUSCLES_STORAGE_POLICYstorage.policy(disks in declared order)Volumes in order from fastest to slowest, separated by semicolons.
MUSCLES_TIER_MOVE_FACTOR0.10Smallest fraction of a disk that must stay free, between 0 and 1, before the disk stops receiving new parts.

Tiered storage

VariableYAML keyDefaultDescription
MUSCLES_TIER_COLD_AFTER_MStiering.cold_after_ms0 (off)A part whose newest row is older than this moves to S3.
MUSCLES_S3_ENDPOINTtiering.s3.endpoint(AWS default)Endpoint URL of the S3 service, which you set for MinIO or any other non-AWS store.
MUSCLES_S3_BUCKETtiering.s3.bucket(none)Bucket for the cold tier, required when tiering is enabled.
MUSCLES_S3_PREFIXtiering.s3.prefix(none)Key prefix under the bucket.
MUSCLES_S3_ACCESS_KEYtiering.s3.access_key(ambient credentials)Static S3 access key, which you must set together with the secret key.
MUSCLES_S3_INSECURE_TLStiering.s3.insecure_tlsfalseFor development only: disables TLS verification for a self-signed https:// endpoint.
MUSCLES_S3_CONNECT_TIMEOUT_MStiering.s3.connect_timeout_ms5000Time in milliseconds to connect to S3, so an unreachable endpoint fails quickly.
MUSCLES_S3_REQUEST_TIMEOUT_MStiering.s3.request_timeout_ms30000Time in milliseconds that one S3 request may stall without moving bytes.
MUSCLES_S3_MULTIPART_THRESHOLD_BYTEStiering.s3.multipart_threshold_bytes67108864Size in bytes from which a part bundle uploads as an S3 multipart upload staged from a file.
MUSCLES_TIER_DELETE_AFTER_MStiering.delete_after_ms0 (never)A part whose newest row is older than this many milliseconds is deleted.
MUSCLES_TIER_DOWNSAMPLE_AFTER_MStiering.downsample_after_ms0 (off)Age in milliseconds after which a raw part becomes a candidate for dropping once rollups cover its range.
MUSCLES_TIER_DOWNSAMPLE_ENABLEDtiering.downsample_drop_enabledfalseLets the server delete raw parts whose range rollups cover.
MUSCLES_TIER_POLL_MStiering.poll_ms60000How often the tier mover looks for parts to move, in milliseconds.
MUSCLES_TIER_ORPHAN_SWEEP_MS3600000Interval in milliseconds between sweeps for S3 objects that no local part references.
MUSCLES_TIER_UPLOAD_CONCURRENCYtiering.upload_concurrency2Most uploads the tier mover runs at the same time in one cycle.
MUSCLES_TIER_GC_SINGLE_OWNERfalseDeclares that this node is the only owner of its S3 prefix, which allows it to delete expired and orphaned objects.
MUSCLES_COLD_CACHE_DIRtiering.cold_cache.dir(sibling of parts)Directory of the cache for cold granules.
MUSCLES_COLD_CACHE_MAX_BYTEStiering.cold_cache.max_bytes1 GiBSize limit in bytes for the cold granule cache.
MUSCLES_COLD_FAULT_CONCURRENCYtiering.cold_cache.fault_concurrency4Most ranged S3 reads that run at once when a scan loads several cold columns.

Local data retention

VariableYAML keyDefaultDescription
MUSCLES_RETENTION_ENABLEDstorage.retention_enabledfalseStarts the background sweeper that enforces table retention.
MUSCLES_RETENTION_POLL_MSstorage.retention_poll_ms300000 (5 min)How often the retention sweeper runs, in milliseconds.

Replication — emitter hook

VariableYAML keyDefaultDescription
MUSCLES_REPLICATION_EMITreplication.emitfalseShips each flushed or merged part to S3 and to the commit log.
MUSCLES_REPLICATION_COMMIT_TOPICreplication.commit_topicmuscles-commit-logKafka topic that receives part commits, which every replica of the shard drains.
MUSCLES_REPLICATION_S3_BUCKETreplication.s3_bucket*(falls back to MUSCLES_S3_BUCKET)*Bucket that part bundles are uploaded to, which defaults to the tiering bucket when empty.
MUSCLES_REPLICATION_SCHEMA_SNAPSHOT_EVERYreplication.schema_snapshot_every64Number of schema epochs between two schema snapshots.

Replication — drain-loop worker

VariableYAML keyDefaultDescription
MUSCLES_REPLICATION_DRAINreplication.drainfalseRuns the background worker that applies commit-log parts to this node.
MUSCLES_REPLICATION_CATCHUPreplication.catchupfalseInstalls the parts missing on this node from the S3 manifest once at startup, and never removes parts.
MUSCLES_REPLICATION_ROLEreplication.rolereplicaReplication role of this node, either primary or replica.
MUSCLES_REPLICATION_REPLICA_WRITESreplication.replica_writesfalseA replica refuses client INSERT, DDL, DELETE and forwarded ingest with HTTP 409 unless this is 1.
MUSCLES_SHARD_GENERATION0Ownership generation of this node's shard, which you raise when you promote a replica.
MUSCLES_REPLICATION_NODE_ID*(MUSCLES_POD_NAME)*Stable identity of this node, hashed into the commit emitter_id and required to turn on emit.
MUSCLES_REPLICATION_SIGNING_KEY_FILE(none)File with the 32-byte Ed25519 signing seed of the primary, as 64 hex characters.
MUSCLES_REPLICATION_PUBLIC_KEY(none)One to four Ed25519 public keys of 64 hex characters each, separated by commas or whitespace.

Cluster / node role

VariableYAML keyDefaultDescription
MUSCLES_NODE_MODEcluster.node_modeallWhat this node does, one of all, query, data or ingest.
MUSCLES_SHARDcluster.shard(none)Index of this node's shard.
MUSCLES_SHARD_MAPcluster.shard_map(none)Map from each shard to its endpoint, which also marks the deployment as clustered.
MUSCLES_NODE_ADDRS*(this node's own MUSCLES_SHARD_MAP entry)*Comma-separated host:port names, as written in MUSCLES_SHARD_MAP, that signed node-to-node requests may target.
MUSCLES_SHARD_KEYcluster.shard_key(none)Column used to prune a query to one shard when its filter names a key value.
MUSCLES_SHARD_KEY_UNSAFE_QUERY_ONLYoffSet to 1 only if rows are placed on shardOf(key) outside muscles.
MUSCLES_POD_NAME(none)Pod name that the server logs once at startup.
MUSCLES_POD_IP(none)Pod IP address that the server logs once at startup.

Logging

VariableYAML keyDefaultDescription
MUSCLES_LOG_LEVELinfoLowest message level that is logged, one of debug, info, warn or error.
MUSCLES_LOG_FORMATtextLog line format, either text or json.

Tracing

VariableYAML keyDefaultDescription
MUSCLES_TRACE_ENABLEDtracing.enabledfalseTurns on tracing.
MUSCLES_TRACE_SAMPLE_RATIOtracing.sample_ratio0.0Probability from 0.0 to 1.0 that a query not asked for tracing is traced anyway.
MUSCLES_TRACE_SERVICE_NAMEtracing.service_namemusclesValue of the OTLP service.name attribute, which you can set per role, such as muscles-query.
MUSCLES_TRACE_ENDPOINTtracing.endpoint""Base URL of the OTLP/HTTP collector, such as http://jaeger:4318.
MUSCLES_TRACE_SUBSYSTEMStracing.subsystems""Sampling ratio for each subsystem, as name=ratio pairs such as merge=1.0,flush=0.0.
MUSCLES_TRACE_SLOW_QUERY_MStracing.slow_query_ms0Queries that run at least this many milliseconds are always exported, whatever the sample ratio.
MUSCLES_TRACE_SPAN_LOG_MAX_ROWStracing.span_log_max_rows100000Most rows system.opentelemetry_span_log keeps, where 0 turns the span log off.
MUSCLES_TRACE_SPAN_LOG_TTL_SECONDStracing.span_log_ttl_seconds3600Age in seconds after which span log rows expire, where 0 keeps them until the row cap removes them.
MUSCLES_TRACE_EXPORT_INTERVAL_MStracing.export_interval_ms1000How often the exporter sends queued traces, in milliseconds.
MUSCLES_TRACE_QUEUE_DEPTHtracing.queue_depth256Most trace batches the exporter queue holds before it drops new ones.
MUSCLES_TRACE_EXPORT_TIMEOUT_MStracing.export_timeout_ms5000Time in milliseconds to connect to the collector, so an unreachable one fails quickly.
MUSCLES_TRACE_MAX_BATCH_TRACEStracing.max_batch_traces64Most traces sent in one OTLP request per export interval.
MUSCLES_TRACE_MAX_SPANStracing.max_spans128Most spans and events one flush, merge, boot or query trace keeps, from 8 to 4096.

Tamper-evident audit log

VariableYAML keyDefaultDescription
MUSCLES_AUDIT_ENABLEDaudit.enabledfalseTurns on the audit log.
MUSCLES_AUDIT_MODEaudit.modeasyncWhether audit records are written before a query answers (sync) or in the background (async).
MUSCLES_AUDIT_QUEUE_FULLaudit.queue_fullblockWhat async mode does when its queue is full, either block or drop_oldest.
MUSCLES_AUDIT_WAIT_TIMEOUT_MSaudit.wait_timeout_ms5000Longest wait in milliseconds for the audit disk before a request fails with 503.
MUSCLES_AUDIT_TIERaudit.tiermetadataHow much each audit record holds, either metadata or verbose.
MUSCLES_AUDIT_QUERY_TEXTaudit.query_texthash_onlyHow verbose audit records store the query text, as full, redacted or hash_only.
MUSCLES_AUDIT_SEAL_ROWSaudit.seal_rows4096Number of queued rows at which async mode seals a block.
MUSCLES_AUDIT_SEAL_INTERVAL_MSaudit.seal_interval_ms1000Longest time in milliseconds between seals in async mode, where 0 means seal by size only.
MUSCLES_AUDIT_MAX_QUEUEaudit.max_queue65536Most rows the in-memory audit queue holds.
MUSCLES_AUDIT_END_USERaudit.end_user0 (OFF)Records the unverified end-user name that a trusted proxy forwards in each audit record.
MUSCLES_AUDIT_DIRaudit.dirmuscles-data/auditDirectory that holds the sealed audit blocks.
MUSCLES_AUDIT_IMMUTABLE—0Forbids every deletion of the audit log and of system.query_history, and is read once at startup.
MUSCLES_AUDIT_RETENTION_DAYS—0Age in days after which sealed audit blocks are deleted, only when MUSCLES_AUDIT_IMMUTABLE is 0, where 0 keeps them forever.
MUSCLES_AUDIT_MAX_BYTES—0Size cap in bytes for the audit directory, enforced only when MUSCLES_AUDIT_IMMUTABLE is 0, where 0 means no cap.
MUSCLES_AUDIT_S3_BUCKET—unsetBucket for the audit archive in S3, which turns the archive on when set.
MUSCLES_AUDIT_S3_PREFIX—auditKey prefix of archive objects in the bucket.
MUSCLES_AUDIT_S3_ENDPOINT——S3 endpoint as host[:port], optionally with a scheme, required when the bucket is set.
MUSCLES_AUDIT_S3_REGION—us-east-1Region used to sign S3 requests.
MUSCLES_AUDIT_S3_ACCESS_KEY[_FILE]——Access key for the audit bucket, required when the bucket is set and never defaulted from MUSCLES_S3_*.
MUSCLES_AUDIT_S3_SECRET_KEY[_FILE]——Secret key for the audit bucket, required when the bucket is set.
MUSCLES_AUDIT_S3_INSECURE_TLS—0Skips TLS verification, for a self-signed MinIO only.
MUSCLES_AUDIT_S3_INTERVAL_MS—60000How often the audit archive uploads sealed blocks, in milliseconds.
MUSCLES_AUDIT_S3_MAX_BATCH_BYTES—67108864Most raw bytes of concatenated blocks in one archive object, from 4096 to 1073741824.
MUSCLES_AUDIT_S3_CODEC—zstdCompression of archive objects, either zstd or none.
MUSCLES_AUDIT_S3_OBJECT_LOCK—offWhether archive objects get S3 Object Lock retention, either off or require.
MUSCLES_AUDIT_S3_LOCK_MODE—complianceS3 Object Lock mode of archive objects, either compliance or governance.
MUSCLES_AUDIT_S3_LOCK_DAYS——Retention in days, from 1 to 36500, stamped on every archived object.
MUSCLES_AUDIT_S3_PARQUET_MIRROR—0Writes a Parquet copy of the audit trail to S3 for auditors.
MUSCLES_AUDIT_S3_DIGEST—0Writes one small digest object per archived batch so that muscles audit-verify can check the chain.

LLM runtime

VariableYAML keyDefaultDescription
MUSCLES_LLM_ENDPOINTllm.endpoint(empty, off)Base URL of the model endpoint, such as http://127.0.0.1:11434.
MUSCLES_LLM_API_STYLEllm.api_styleollamaRequest style of the endpoint, either ollama or openai.
MUSCLES_LLM_ALLOWED_HOSTSllm.allowed_hosts(empty)Comma-separated host names allowed besides localhost and IPv4 literals.
MUSCLES_LLM_ALLOWED_CIDRSllm.allowed_cidrs(empty)Extra network ranges allowed besides loopback, private and link-local addresses, comma-separated, such as 100.64.0.0/10.
MUSCLES_LLM_DEFAULT_MODELllm.default_model(empty)Model for calls that name none.
MUSCLES_LLM_API_KEY_FILEllm.api_key_file(empty, no key)File that holds the bearer token for the endpoint.
MUSCLES_LLM_CACHE_DIRllm.cache_dirllm-cache next to the parts directoryDirectory of the result cache log.
MUSCLES_LLM_CACHE_MAX_BYTESllm.cache_max_bytes67108864Byte budget of the cache; the oldest entries are evicted first.
MUSCLES_LLM_CACHE_MAX_ENTRIESllm.cache_max_entries65536Most entries kept (ceiling 1048576).
MUSCLES_LLM_TIMEOUT_MSllm.timeout_ms60000Time in milliseconds that one HTTP exchange with the endpoint may take.
MUSCLES_LLM_MAX_CONCURRENTllm.max_concurrent2Most model calls in flight at once in the process, after which a call fails with Busy.
MUSCLES_LLM_MAX_PROMPT_BYTESllm.max_prompt_bytes32768Largest input text of one call, in bytes.
MUSCLES_LLM_MAX_RESPONSE_BYTESllm.max_response_bytes262144Largest HTTP response body accepted, in bytes.
MUSCLES_LLM_MAX_OUTPUT_TOKENSllm.max_output_tokens512Output tokens requested per call.
MUSCLES_LLM_QUERY_MAX_CALLSllm.query_max_calls1000Model calls one query may make; cache hits are free.
MUSCLES_LLM_QUERY_MAX_TOKENSllm.query_max_tokens1000000Tokens one query may use, as reported by the endpoint.
MUSCLES_LLM_QUERY_TIMEOUT_MSllm.query_timeout_ms600000Time in milliseconds that the model calls of one query may take in total.