Advanced Runtime Variables
This page lists the advanced server-side tuning variables. None of them are required for a first-time deployment; keep the defaults unless you are dealing with a specific performance, capacity, rate-limiting, or compatibility problem. For basic deployment, authentication, storage, vector, integration, and Compose variables, see Environment Variable Overview. Sandbox and frontend build variables are covered in Sandbox Variables and Frontend Build Variables.
Except for AIVORY_TOOLS_WEB_FETCH_JINA_FALLBACK, AIVORY_TOOLS_WEB_FETCH_JINA_BASE, and AIVORY_TOOLS_WEB_FETCH_JINA_URL_MODE, all AIVORY_* variables are read when the application process starts, and changes require a restart of app. These three web-fetch fallback variables are read on every fetch, and changes take effect starting with the next fetch. Duration values use formats like 30s, 5m, and 2h; byte caps are given as decimal byte counts, e.g. 20971520 means 20 MiB; integers, floats, and booleans must use valid formats, and invalid values fall back to the default. Suffixes such as _2 and _3 in variable names are stable compatibility names and do not imply that you can number them freely.
Before tuning, record the current values, the stress-test results or evidence of the problem, and a rollback plan. Raising concurrency, request body sizes, timeouts, or tool limits simultaneously increases cost, memory usage, upstream pressure, and the abuse surface.
1. LLM Conversation / Orchestration / Internal Model Calls
The main conversation flow, tool loops, the TTFT watchdog, and internal model calls for compaction / memory / moderation / validation / deep research / document generation.
Tool-count limits apply to Aivory system tools only. Provider-hosted tools remain configured in every mode and do not consume these counters; for Fast Mode system tools, 0 hides the tool and a positive value both exposes it and sets its cap.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_LLM_APPLY_ANTHROPIC_THINKING_SETTINGS | int | 2048 | Token margin added on top of the extended-thinking budget_tokens when raising the Anthropic max_tokens, so the output can fit thinking plus the reply. |
AIVORY_LLM_MAX_ITER | int | 20 | Hard cap on native tool-call rounds (Messages API calls) in the Anthropic streaming loop. |
AIVORY_LLM_MAX_TOK | int | 64000 | Default max_tokens sent with each Anthropic Messages request in the streaming tool loop (unless the request itself overrides it). |
AIVORY_LLM_MAX_TOK_2 | int | 64000 | Default max_tokens for a single Anthropic call in prompt-tool mode (promptRunOnce) (unless the request overrides it). |
AIVORY_LLM_INFLIGHT_GRACE | duration | 2h | Grace period during which assistant message rows with status=streaming are exempt from summarization before being treated as crash leftovers; values below AIVORY_API_MAX_GEN_DURATION plus the final-persistence margin are automatically raised. |
AIVORY_LLM_T | int | 4 | Structural token overhead added per message in compaction token estimation (role markers, framing). |
AIVORY_LLM_MESSAGE_TOKEN_MEMO_CACHE_BOUND | int | 100000 | Maximum entries allowed in the per-message token estimation memo cache map before it is reset in place to bound memory. |
AIVORY_LLM_SUMMARY_TOKENS_CLAMP_FLOOR | int | 256 | Lower bound for the admin-side summary_max_tokens setting; configured values below this floor reset to the default summary budget. |
AIVORY_LLM_SUMMARY_TARGET_MIN_TOKENS | int | 384 | Minimum detail target for new compaction summary requests when allowed by the administrator-configured hard output cap. |
AIVORY_LLM_SUMMARY_TARGET_PER_ROUND_TOKENS | int | 96 | Per-user-turn token contribution to the adaptive summary target, preventing many brief decisions from being collapsed into one generic paragraph. |
AIVORY_LLM_SUMMARY_TARGET_HEADROOM_NUM | int | 5 | Numerator of the output headroom ratio above the adaptive summary target (default 5/4). |
AIVORY_LLM_SUMMARY_TARGET_HEADROOM_DEN | int | 4 | Denominator of the output headroom ratio above the adaptive summary target (default 5/4). |
AIVORY_LLM_SUMMARY_SHORT_RETRY_THRESHOLD_NUM | int | 1 | Numerator of the length ratio below which a summary draft is judged clearly too short and a retry is triggered (default below 1/4 of the target). |
AIVORY_LLM_SUMMARY_SHORT_RETRY_THRESHOLD_DEN | int | 4 | Denominator of the clearly-too-short summary retry threshold (default 1/4 of the target). |
AIVORY_LLM_SUMMARY_SHORT_RETRY_SOURCE_FACTOR | int | 2 | Minimum required "source content / target" multiple before retrying a short summary, avoiding forced padding of content that is inherently sparse. |
AIVORY_LLM_BIG_TOKEN_OVERFLOW_NUM | int | 5 | Numerator of the token trigger-threshold multiple (num/den, default 5/4 = 1.25x) that triggers inline summarization within the current round. |
AIVORY_LLM_BIG_TOKEN_OVERFLOW_DEN | int | 4 | Denominator of the token trigger-threshold multiple (num/den, default 5/4 = 1.25x) that triggers inline summarization within the current round. |
AIVORY_LLM_INLINE_COMPACTION_BACKLOG_FACTOR | int | 3 | Multiple of the un-summarized tail length relative to keepRounds*2; above it the current round forces inline (rather than asynchronous) compaction. The planner additionally keeps one batch of buffer above the asynchronous high-water mark. |
AIVORY_LLM_ATTEMPT | int | 4 | Maximum compare-and-swap (CAS) retry attempts when appending a new summary block to the conversation's summary_blocks. |
AIVORY_LLM_TOOL_OUTPUT_TOKENS | int | 2048 | Per-item token cap used when normalizing internal tool result blocks, if a complete and recognizable native tool result cannot be recovered from the provider Raw output. Fully recovered, recognized results are no longer truncated here; lossless map-reduce chunking bounds each model request size instead. The short preview shown in the UI is unchanged. |
AIVORY_LLM_TOOL_INPUT_TOKENS | int | 2048 | Per-tool-call input token cap when rendering tool-call arguments into compaction requests. |
AIVORY_LLM_COMPACTION_METADATA_TOKENS | int | 512 | Token cap per referenced item when rendering attachment, citation, document, and artifact metadata into compaction requests. |
AIVORY_LLM_COMPACTION_MEDIA_INLINE_BYTES | int64 | 20971520 | Total byte budget when recovering compaction images for vision models; all image references are persisted, and references that are not recovered are marked in metadata form. |
AIVORY_LLM_CHUNK_SIZE | int | 400 | Message-ID batch size per SQL IN(...) query when re-validating that summarized messages still exist (chunked to stay under driver placeholder limits). |
AIVORY_LLM_COMPACTION_LEASE_TTL | duration | 2h | Lifetime of the database-backed per-session compaction lease, preventing inline, asynchronous, and manual summarization from running concurrently; provides mutual exclusion across replicas even without Redis configured. Values below AIVORY_API_MAX_GEN_DURATION plus the final-persistence margin are automatically raised. |
AIVORY_LLM_DR_MAX_ROUNDS | int | 4 | Hard cap on the number of search-then-verify rounds in a deep research engine run. |
AIVORY_LLM_DR_QUERIES_PER_ROUND | int | 6 | Maximum number of search queries dispatched per deep research round. |
AIVORY_LLM_DR_FETCH_PER_ROUND | int | 5 | Maximum number of new source candidates picked and read per deep research round. |
AIVORY_LLM_DR_MIN_DEEP_READS | int | 5 | Minimum number of deeply read sources deep research must reach before it is allowed to wrap up (even if coverage gaps already look sufficient). |
AIVORY_LLM_DR_SEARCH_TOP_K | int | 8 | Number of results requested per deep research search call (top_k). |
AIVORY_LLM_DR_WALL_CLOCK | duration | 5m | Total wall-clock timeout bounding an entire deep research engine run. |
AIVORY_LLM_DR_CALL_TIMEOUT | duration | 30s | Per-call timeout for a single deep research search or fetch request. |
AIVORY_LLM_DEEP_RESEARCH_VALIDATE_TIMEOUT | duration | 75s | Timeout for the deep research validate phase, which reviews weak / single-source claims before writing. |
AIVORY_LLM_SCORE_A | float | 9 | Ranking score added for candidate sources whose URL trust level is A (trust dominates ranking). |
AIVORY_LLM_SCORE_B | float | 6 | Ranking score added for candidate sources whose URL trust level is B. |
AIVORY_LLM_SCORE_C | float | 3 | Ranking score added for candidate sources whose URL trust level is C. |
AIVORY_LLM_SCORE_KW | float | 1 | Ranking score added for each question keyword hit (length > 3) in a candidate source's title or snippet. |
AIVORY_LLM_SCORE_FRESH_DOMAIN | float | 2 | Ranking bonus added for candidate sources from domains not yet seen in this research run. |
AIVORY_LLM_MAX_ITER_4 | int | 20 | Hard cap on native tool-call rounds (generateContent calls) in the Gemini streaming loop. |
AIVORY_LLM_GEMINI_MAX_TOK | int | 64000 | Default generationConfig.maxOutputTokens per request in the Gemini streaming loop (unless the request overrides it). |
AIVORY_LLM_GEMINI_MAX_TOK_2 | int | 64000 | Default generationConfig.maxOutputTokens in Gemini prompt-tool mode calls (unless the request overrides it). |
AIVORY_LLM_CONF | float | 0.7 | Fallback confidence assigned to extracted memories when the extractor returns a confidence outside (0,1]. |
AIVORY_STORE_M_CONFIDENCE | float | 0.8 | Fallback value written only when the confidence passed to CreateMemory is exactly 0; it is a default, not a confidence filter or retrieval threshold. |
AIVORY_STORE_LIST_MEMORIES_ACTIVE | int | 20 | Combined cap on ACTIVE and QUERY_DEPENDENT memories returned when injecting into the system prompt, selected by most recently updated first. |
AIVORY_LLM_OFFICIAL_TOOL_SPEC | string | "medium" | Used only as the search_context_size when converting legacy OpenAI Responses "web_search" string configurations to the current object format; new models no longer default to any provider-hosted tools, and request JSON explicitly filled in by administrators is stored verbatim. |
AIVORY_LLM_MAX_ITER_2 | int | 20 | Hard cap on native tool-call rounds in the OpenAI streamChat (Chat Completions) loop. |
AIVORY_LLM_MAX_ITER_3 | int | 20 | Hard cap on native tool-call rounds in the OpenAI streamResponses (Responses API) loop. |
AIVORY_LLM_INLINE_QUOTE_SOURCE_INJECTION_CAP | int | 8000 | Maximum characters (runes) of source message text injected alongside the highlighted excerpt in an inline-quote sub-conversation, before truncation. |
AIVORY_LLM_ATTACHMENT_IMAGE_INLINE_BYTES | int64 | 20971520 | Standalone hard cap for a single validated image attachment before it is base64-encoded into a channel request; reads are bounded the same way, so stale incorrect size metadata cannot bypass the limit. |
AIVORY_LLM_TOOL_ROUTE_TIMEOUT | duration | 5s | End-to-end latency budget for waiting on the dedicated routing model in automatic tool mode; on timeout, tools are enabled per the fail-open rule. |
AIVORY_LLM_TOOL_ROUTE_SCHEMA_TOKEN_THRESHOLD | int | 512 | When tool declarations estimate at or below this many tokens, automatic mode skips the extra routing request and lets the main model decide natively. Set to 0 to route every ambiguous request through classification. |
AIVORY_LLM_SANDBOX_EXEC_TIMEOUT_CLAMP_RANGE_MAX | int | 600 | Upper bound (seconds) to which the administrator-configured sandbox_exec_timeout_sec is clamped when timing the python_execute call context. |
AIVORY_LLM_SANDBOX_EXEC_TIMEOUT_CLAMP_RANGE_MIN | int | 10 | Lower bound (seconds) to which the administrator-configured sandbox_exec_timeout_sec is clamped when timing the python_execute call context. |
AIVORY_LLM_SANDBOX_EXEC_CTX_SAFETY_MARGIN | duration | 150s | Extra margin added on top of the clamped sandbox exec timeout when timing the python_execute context, so the context times out later than the sandbox HTTP client. |
AIVORY_LLM_PER_TURN_TOOL_LIMITS_WEB_SEARCH | int | 16 | Per-message cap on aivory_web_search calls allowed in normal mode; calls beyond it fail. |
AIVORY_LLM_PER_TURN_TOOL_LIMITS_WEB_FETCH | int | 12 | Per-message cap on web_fetch calls allowed in normal mode; calls beyond it fail. |
AIVORY_LLM_PER_TURN_TOOL_LIMITS_IMAGE_GENERATE | int | 8 | Per-message cap on image_generate calls allowed in normal mode; calls beyond it fail. |
AIVORY_LLM_PER_TURN_TOOL_LIMITS_PYTHON_EXECUTE | int | 16 | Per-message cap on python_execute sandbox executions allowed in normal mode; calls beyond it fail. |
AIVORY_LLM_FAST_TOOL_LIMITS_WEB_SEARCH | int | 4 | Fast-mode cap for the aivory_web_search system tool; 0 hides it. |
AIVORY_LLM_FAST_TOOL_LIMITS_WEB_FETCH | int | 3 | Fast-mode cap for the web_fetch system tool; 0 hides it. |
AIVORY_LLM_FAST_TOOL_LIMITS_FETCH_IMAGE | int | 0 | Fast-mode cap for the fetch_image system tool; 0 hides it, while a positive value still requires its normal dependencies and permissions. |
AIVORY_LLM_FAST_TOOL_LIMITS_IMAGE_GENERATE | int | 2 | Fast-mode cap for the image_generate system tool; 0 hides it. |
AIVORY_LLM_FAST_TOOL_LIMITS_PYTHON_EXECUTE | int | 0 | Fast-mode cap for the python_execute system tool; 0 hides it, while a positive value still requires a configured sandbox and normal permissions. |
AIVORY_LLM_DEEP_RESEARCH_TOOL_LIMITS_WEB_SEARCH | int | 40 | Per-message cap on aivory_web_search calls allowed during deep research runs; calls beyond it fail. |
AIVORY_LLM_DEEP_RESEARCH_TOOL_LIMITS_WEB_FETCH | int | 25 | Per-message cap on web_fetch calls allowed during deep research runs; calls beyond it fail. |
AIVORY_LLM_DEEP_RESEARCH_TOOL_LIMITS_IMAGE_GENERATE | int | 4 | Per-message cap on image_generate calls allowed during deep research runs; calls beyond it fail. |
AIVORY_LLM_DEEP_RESEARCH_TOOL_LIMITS_PYTHON_EXECUTE | int | 8 | Per-message cap on python_execute sandbox executions allowed during deep research runs; calls beyond it fail. |
AIVORY_LLM_MAX_TOOL_CALLS_PER_TURN | int | 48 | Global per-message cap on total tool calls across all tools in normal mode, layered on top of the per-tool limits. |
AIVORY_LLM_MAX_TOOL_CALLS_PER_TURN_DEEP | int | 150 | Global per-message cap on total tool calls across all tools during deep research runs. |
AIVORY_LLM_MAX_TOOL_CALLS_PER_TURN_FAST | int | 12 | Independent global per-message cap on total tool calls across all tools in fast mode. |
AIVORY_LLM_MAX_TOOL_TIME_PER_TURN | duration | 15m | Cumulative wall-clock time budget for all tool executions in a normal message. Once exhausted, all tools are removed and the model is allowed a single tool-free wrap-up request. Set to a non-positive value to disable the time budget. |
AIVORY_LLM_MAX_TOOL_TIME_PER_TURN_DEEP | duration | 4m | Cumulative tool-execution time budget for deep research, reserving time within the five-minute research window for one tool-free report-writing request. Set to a non-positive value to disable the time budget. |
AIVORY_LLM_MAX_TOOL_TIME_PER_TURN_FAST | duration | 3m | Cumulative tool-execution time budget for fast mode; once exhausted, only a single tool-free wrap-up request runs. Set to a non-positive value to disable the time budget. |
AIVORY_LLM_TOOL_TIMEOUTS | duration | 10s | Per-call timeout cap for a single aivory_web_search tool call. |
AIVORY_LLM_TOOL_TIMEOUTS_2 | duration | 60s | Per-call timeout for web_fetch, leaving time for Jina fallback after the direct attempt. |
AIVORY_LLM_TOOL_TIMEOUTS_3 | duration | 600s | Per-call timeout cap for a single image_generate tool call (a generous window for slow third-party image gateways). |
AIVORY_LLM_TOOL_TIMEOUT_DEFAULT | duration | 100s | Fallback per-call timeout for tools not listed in the per-type toolTimeouts map. |
AIVORY_LLM_PROMPT_MAX_ITER | int | 10 | Maximum iterations in the prompt-mode tool loop before the round ends (each iteration = one model generation plus optional tool calls). |
AIVORY_LLM_PROMPT_MAX_RETRY | int | 2 | Maximum retries for resending malformed <tool_call> JSON or retrying failed tool executions in prompt mode. |
AIVORY_LLM_PROVIDER_REQUEST_BODY_MAX_BYTES | int | 131072 | Maximum length to which the captured provider request body/header JSON snapshot used for diagnostics is clamped. |
AIVORY_LLM_PROVIDER_REQUEST_VALUE_MAX_BYTES | int | 8192 | Maximum length to which each individually captured provider request value (URL, header value) is clamped. |
AIVORY_LLM_IMAGE_DOCUMENT_FLAT_TOKEN_ALLOWANCE | int | 1024 | Fixed number of tokens counted per image/document block when estimating request tokens, since base64 cannot be tokenized as text. |
AIVORY_LLM_OUTPUT_RESERVE | int | 2000 | Fixed output-token reserve added on top of estimated input tokens when computing the pre-flight credit-affordability estimate. |
AIVORY_LLM_MAX_CONCURRENT_TOOLS | int | 4 | Cap on concurrently executed tools within one round (semaphore capacity bounding concurrent executor fan-out). |
AIVORY_LLM_VCTX | duration | 45s | Timeout bounding the post-answer validation/audit LLM call, so slow cross-vendor audits do not hold up the round. |
2. RAG Document Parsing / Vector Search
Document chunking, embedding batching and concurrency, the Qdrant client, MinerU OCR polling, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_RAG_EMBEDDING_RETRY_DELAY | duration | 1s | Base delay of the exponential backoff between embedding batch retries, scaled by 2^min(attempts,4). |
AIVORY_RAG_EMBEDDING_RETRY_DELAY_2 | duration | 30s | Cap on the computed embedding retry backoff delay. |
AIVORY_RAG_EMBEDDING_RETRY_DELAY_3 | duration | 1000ms | Random jitter range added to each embedding retry backoff delay, to de-synchronize concurrent batches. |
AIVORY_RAG_DASH_SCOPE_EMBED_CONCURRENCY | int | 2 | Per-document cap on concurrent upstream embedding batches when the provider is DashScope. |
AIVORY_RAG_DASH_SCOPE_GLOBAL_EMBED_CONCURRENCY | int | 2 | Process-wide cap on concurrent DashScope embedding requests (capacity of the shared-slot semaphore). |
AIVORY_RAG_DASH_SCOPE_EMBED_ATTEMPT_TIMEOUT | duration | 60s | Single-attempt request timeout for DashScope embedding calls, set below the client's 3-minute cap so stuck calls fail visibly. |
AIVORY_RAG_EMBED_CONCURRENCY | int | 4 | Per-document cap on concurrent upstream embedding batches for non-DashScope providers. |
AIVORY_RAG_MAX_ATTEMPTS | int | 2 | Maximum attempts for a single embedding batch POST before giving up (retrying with backoff on transient failures). |
AIVORY_RAG_PDF_INSPECTION_TIMEOUT | duration | 8s | Deadline the parent process enforces on the child-process PDF text-layer detection probe, killing it when the deadline expires. |
AIVORY_RAG_OFFICE_XML_ZIP_ENTRY_READ_CAP | int64 | 16777216 | Byte cap when reading each DOCX/PPTX zip entry (body/header/footer/slide XML) during Office plain-text extraction. |
AIVORY_RAG_PDF_INSPECTION_SAMPLE_LIMIT | int | 3 | Maximum number of uniformly sampled pages when probing whether a PDF is a scan or native digital text. |
AIVORY_RAG_PDF_THIN_CHARS_PER_PAGE | int | 200 | Below this per-sampled-page character threshold, a PDF containing images is flagged as "text-sparse" and routed to OCR. |
AIVORY_RAG_CMD_WAIT_DELAY | duration | 500ms | Grace period before a force kill after the PDF detection subprocess context timeout (cmd.WaitDelay). |
AIVORY_RAG_PDF_RAW_SIGNALS_STRONG_SCAN_IMAGE | int | 5 | Image-count multiplier in the raw-byte "strong scan" rule imageCountN >= pagesM, used to classify a PDF as image-only. |
AIVORY_RAG_PDF_RAW_SIGNALS_STRONG_SCAN_PAGE | int | 4 | Page-count multiplier in the raw-byte "strong scan" rule imageCountN >= pagesM, used to classify a PDF as image-only. |
AIVORY_RAG_MINERU_SOURCE_OBJECT_CLEANUP_TIMEOUT | duration | 30s | Timeout for the best-effort deletion of the bucket source object uploaded for MinerU OCR after parsing. |
AIVORY_RAG_MINERU_POLL_DEADLINE | duration | 20m | Total time cap for the whole loop polling a MinerU extraction task while waiting for done/failed status. |
AIVORY_RAG_MINERUZIPCLIENT_TIMEOUT | duration | 5m | HTTP client timeout when downloading the MinerU result zip through the SSRF-protected client. |
AIVORY_RAG_FULL_MD_READ_CAP_INSIDE_ZIP | int64 | 33554432 | Byte cap on reading the full.md markdown body from inside the MinerU result zip. |
AIVORY_RAG_MAX_ZIP | int64 | 524288000 | Byte cap on the downloaded MinerU result zip; larger downloads are rejected rather than buffered into memory. |
AIVORY_RAG_MINERUCLIENT_TIMEOUT | duration | 5m | http.Client timeout for each round trip (submit, poll, download) when calling the MinerU cloud API. |
AIVORY_RAG_MINERU_SOURCE_TTLSECONDS | int | 3600 | Validity period (seconds) of the presigned GET URL for the source document handed to MinerU. |
AIVORY_RAG_SPREADSHEET_PREVIEW_MAX_FILE_BYTES | int64 | 31457280 | Maximum file size accepted for in-process spreadsheet parsing that produces a bounded inline preview when python_execute is not exposed to the model; larger files are skipped. |
AIVORY_RAG_RAG_FAST_QUEUE_CONCURRENCY | int | 4 | asynq worker concurrency for the "rag-fast" ingestion channel serving text/table documents. |
AIVORY_RAG_RAG_SLOW_QUEUE_CONCURRENCY | int | 4 | asynq worker concurrency for the slow "rag" ingestion channel serving OCR/heavy documents. |
AIVORY_RAG_INGEST_PIPELINE_TIMEOUT | duration | 70m | Context deadline for the full parse/embed ingestion pipeline (runIngestWithRetries) of one document. |
AIVORY_RAG_INGEST_TASK_TIMEOUT | duration | 75m | asynq per-task processing timeout (asynq.Timeout) for the rag.ingest task. |
AIVORY_RAG_INGEST_UNIQUE_TTL | duration | 80m | asynq uniqueness lock TTL (asynq.Unique), suppressing duplicate enqueue of the same document. |
AIVORY_RAG_INGEST_HEARTBEAT_INTERVAL | duration | 30s | Interval of ingestion heartbeat writes (TouchDocumentIngest), keeping running documents from being judged stale. |
AIVORY_RAG_INGEST_STALE_AFTER | duration | 4m | A document mid parse/embed whose heartbeat is older than this is considered abandoned, reclaimed, and re-enqueued. |
AIVORY_RAG_INGEST_PENDING_STALE_AFTER | duration | ingestUniqueTTL | A document still "pending" longer than this is considered stuck, reclaimed, and re-enqueued. |
AIVORY_RAG_INGEST_RECOVERY_INTERVAL | duration | 1m | Scan interval of the recovery loop that reclaims stale abandoned ingestion documents. |
AIVORY_RAG_INGEST_FINALIZE_TIMEOUT | duration | 30s | Timeout for the vector-store DeleteByDocument cleanup when finalizing a failed ingestion. |
AIVORY_RAG_INGEST_ASYNQ_LEASE_MAX_RETRIES | int | 1 | asynq MaxRetry reserved for lease/process loss; handler failures are retried separately inside the pipeline. |
AIVORY_RAG_INGEST_ASYNQ_RETRY_DELAY | duration | 2m | Delay asynq waits before rerunning an ingestion task that lost its lease (RetryDelayFunc). |
AIVORY_RAG_INGEST_QUEUE_NAME | duration | 2s | Timeout for the GetDocument query used to sort documents into the fast/slow ingestion queues. |
AIVORY_RAG_RUN_INGEST_WITH_RETRIES | int | 3 | Maximum whole-pipeline ingestion attempts before a document is finalized as failed. |
AIVORY_RAG_RUN_INGEST_WITH_RETRIES_2 | duration | 3s | Base backoff between whole-pipeline ingestion retries, multiplied by attempt count. |
AIVORY_RAG_START_INGEST_HEARTBEAT | duration | 5s | Timeout for each ingestion heartbeat write (TouchDocumentIngest). |
AIVORY_RAG_FINALIZE_CHUNK_CLEANUP_TIMEOUT | duration | 10s | Timeout for DeleteChunksByDocument cleanup when finalizing a failed ingestion. |
AIVORY_RAG_FINALIZE_STATUS_TIMEOUT | duration | 10s | Timeout for the final UpdateDocumentStatus write marking a failed document as "failed". |
AIVORY_RAG_DENSE_SEARCH_LEG_LIMIT | int | 30 | Top-N hits requested from the dense/vector leg (vec.Search) of hybrid retrieval. |
AIVORY_RAG_KEYWORD_SEARCH_LEG_LIMIT | int | 30 | Top-N hits requested from the keyword leg (vec.SearchKeyword) of hybrid retrieval. |
AIVORY_RAG_SNIPPET_OF | int | 240 | Default byte-length cap for result snippets when the caller specifies no limit (truncated rune-safely). |
AIVORY_RAG_SPLIT_PARAGRAPHS_AND_TABLES | int | 800 | Image markdown paragraphs shorter than this byte length are kept as a single atomic chunk and not split further. |
AIVORY_RAG_ROUTER_CALL_TIMEOUT | duration | 12s | Timeout for the task-routing JSON LLM call (task.router) on the first-token hot path, before falling back to plain retrieval. |
AIVORY_RAG_MAP_REDUCE_SUMMARISE | int | 200 | Character-count cap (≤N characters) requested from the task model in map-reduce grouped summary prompts. |
AIVORY_RAG_COLLECT_DOC_HINTS | int | 120 | Leading bytes of each document body kept in router document hint lines, to resolve pronoun references. |
AIVORY_RAG_COLLECT_DOC_HINTS_2 | int | 12 | Maximum number of per-document hint lines collected for the retrieval router. |
AIVORY_RAG_RETRIEVAL_NEIGHBOR_CHUNKS | int | 1 | Number of adjacent child chunks additionally pulled from the same parent chunk, in document order, per retrieved child-chunk hit. |
AIVORY_RAG_FUSE_RECIPROCAL_RANK | int | 60 | Rank constant k in the reciprocal-rank fusion formula 1/(rank+k) that merges the vector and keyword retrieval legs. |
AIVORY_RAG_RETRIEVED_SNIPPET_CHARS | int | 2000 | Context-window byte budget expandHit builds around each retrieved child-chunk hit before injection. |
AIVORY_RAG_CHILD_TARGET_CHARS | int | 2000 | Target byte length each embedded child chunk trends toward when merging split atomic units. |
AIVORY_RAG_PARENT_TARGET_CHARS | int | 4800 | Byte length to which parent section bodies are truncated to provide retrieval-time context. |
AIVORY_RAG_CHUNK_OVERLAP_CHARS | int | 250 | Trailing bytes of the previous child chunk prepended to the next one as sliding-window overlap. |
AIVORY_RAG_MAPREDUCE_GROUPTOKENS | int | 6000 | Estimated token budget per chunk group when map-reduce summarizing an over-budget corpus. |
AIVORY_RAG_MAPREDUCE_MAXGROUPS | int | 8 | Maximum number of chunk groups the map-reduce summarizer processes for a single query. |
AIVORY_RAG_BATCH_SIZE | int | 64 | Number of chunks embedded per Embed call when rebuilding vectors from the admin console. |
AIVORY_VECTOR_QDRANT_SCROLL_PAGE_SIZE_EXISTINGCHUNKIDS | int | 256 | Points fetched per Qdrant scroll page when listing chunk IDs already present in an index. |
AIVORY_VECTOR_QDRANT_SCROLL_PAGE_SIZE_VECTORCHUNKSTATUSES | int | 256 | Points fetched per Qdrant scroll page when scanning payloads and vectors for the admin vector status audit. |
AIVORY_VECTOR_DELETE_CONCURRENCY | int | 4 | Maximum number of concurrent per-collection delete requests when clearing a document's points across all dimensions. |
3. Sandbox Code Execution
The python_execute sandbox. Go-side variables take effect after restarting the API process; SANDBOX_* variables apply to the sandbox-service process and require restarting that service. The runner network is not configurable: every session always uses Docker --network none. Required Python dependencies must be preinstalled into the runner image; there is no SANDBOX_NETWORK escape hatch for runtime downloads.
| Environment variable | Type | Default | Description |
|---|---|---|---|
SANDBOX_MAX_OUTPUT_BYTES | int | 32768 | Byte cap at which the sandbox truncates the captured exec stdout/stderr streams. |
SANDBOX_MAX_ARTIFACT_BYTES | int | 20971520 | Maximum byte size of a single output artifact file collected by the sandbox. |
SANDBOX_S3_MAX_ATTEMPTS | int | 3 | botocore max_attempts retry count bounding each S3 storage SDK call. |
SANDBOX_S3_CONNECT_TIMEOUT_S | float | 10 | Connect timeout (seconds) applied to each S3 storage SDK call. |
SANDBOX_S3_READ_TIMEOUT_S | float | 120 | Read timeout (seconds) applied to each S3 storage SDK call. |
SANDBOX_OSS_CONNECT_TIMEOUT_S | float | 30 | Connect timeout (seconds) of the Aliyun OSS bucket client. |
AIVORY_SANDBOX_MAX_SANDBOX_RESP_BYTES | int64 | 268435456 | Byte cap on each sidecar HTTP response body decoded per exec call, preventing an API-process OOM. |
AIVORY_SANDBOX_EXEC_CLIENT_OVERHEAD | duration | 120s | Duration appended on top of each exec cap to set the sandbox HTTP client timeout, covering post-deadline cleanup on the sidecar. |
AIVORY_SANDBOX_SANDBOX_ERROR_BODY_READ_CAP | int64 | 65536 | Byte cap when reading 4xx/5xx sidecar error response bodies for error messages. |
4. Built-in Tools (Search / Python / Web Security)
aivory_web_search result counts and timeouts, Python safe mode, SSRF / web security guardrails, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_TOOLS_IN_TOP_K | int | 5 | Default result count for the aivory_web_search tool when the model call does not specify top_k. |
AIVORY_TOOLS_WEB_FETCH_RESPONSE_BODY_READ_CAP | int64 | 262144 | Byte cap on the HTTP response body web_fetch reads before stripping HTML. |
AIVORY_TOOLS_WEB_FETCH_EXTRACTED_TEXT_CHAR_CAP | int | 32000 | Character cap on web_fetch text after HTML stripping, before truncation with an ellipsis marker. |
AIVORY_TOOLS_PYTHON_EXECUTE_UPLOAD_STAGING_FILE_SIZE | int64 | 41943040 | Per-file size cap above which a session's uploaded file is skipped when staging files into the Python sandbox. When raising it, also make sure the sidecar's SANDBOX_MAX_UPLOAD_BYTES and SANDBOX_MAX_BODY_BYTES are large enough. |
AIVORY_TOOLS_PYTHON_EXECUTE_STDOUT_STDERR_TRUNCATION_CAP | int | 32768 | Character cap on python_execute stdout/stderr truncation before presenting them to the model. |
AIVORY_TOOLS_IN_N | int | 4 | Maximum number of images a single image_generate call may request. |
AIVORY_TOOLS_IN_SIZE | string | "" | Optional override used when image_generate specifies no size. Leave empty to let the provider decide automatically; GPT image editing infers the nearest supported aspect ratio when it can be parsed. |
AIVORY_TOOLS_DAILY_IMAGE_LIMIT_RESET_WINDOW | duration | 24h | Time window used to round Now() when computing the start boundary of each user's image-generation quota ledger. |
AIVORY_TOOLS_IMAGE_IMAGE_INPUT_IMAGE_CAP | int | 0 | Global override for the number of reference images in image-to-image generation. 0 means per-model caps apply (DALL-E 1, OpenAI 16, the Gemini 3 series 14, other Gemini 3). |
AIVORY_TOOLS_FETCHREMOTEIMAGE_DOWNLOAD_CAP | int64 | 33554432 | Byte cap when downloading image URLs returned in image API responses through the SSRF-safe client. |
AIVORY_TOOLS_CONFIDENCE | float | 0.95 | Confidence score stored on each memory record created by the save_memory tool. |
5. Sessions / Messages / Streaming API
SSE heartbeats, stream recovery windows, generation duration caps, pagination and search limits, message-path caching, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_API_LIMIT_2 | int | 200 | Default page size for the list-conversations endpoint when the request omits the limit parameter. |
AIVORY_API_LIMIT_3 | int | 500 | Hard cap on the ?limit query parameter for the conversation list endpoint; larger values are clamped to it. |
AIVORY_API_SEARCH_MESSAGE_HIT_LIMIT | int | 40 | Maximum number of message-body hits returned by the conversation search endpoint (title hits have a separate cap). |
AIVORY_API_IMPORT_MAX_CONVERSATIONS | int | 1000 | Maximum number of conversations a single import request may create; imports beyond it are rejected. |
AIVORY_API_IMPORT_MAX_MESSAGES_PER_CONV | int | 10000 | Maximum messages allowed for a single conversation in an import request; imports beyond it are rejected. |
AIVORY_API_IMPORT_MAX_CONTENT_BYTES | int | 204800 | Byte cap on a single message body during import; the excess is truncated to this many bytes. |
AIVORY_API_INLINE_THREAD_QUOTE_CAP | int | 4000 | Maximum character (rune) length of quoted text when creating an inline sub-thread; longer text is truncated. |
AIVORY_API_GETCONVERSATION_ACTIVE_PATH_LIMIT | int | 200 | Cap on the ?limit parameter for active-path pagination when fetching a conversation; beyond it the full path is returned. |
AIVORY_API_LIMIT_4 | int | 30 | Default tail-window page size for the message list endpoint when no ?limit is provided. |
AIVORY_API_LISTMESSAGES_PAGE_LIMIT | int | 200 | Maximum accepted value for the ?limit parameter of the message list endpoint; larger values fall back to the default page size. |
AIVORY_API_RATE_LIMIT_USER | int | 20 | Per-user rate-limit allowance: maximum knowledge base document uploads per minute before returning 429. |
AIVORY_API_CONFIDENCE | float | 0.95 | Confidence score (0-1 range) stored on memory entries created manually by users. |
AIVORY_API_MAX_GEN_DURATION | duration | 90m | Wall-clock timeout cap for a single detached generation turn; after it the context is canceled. |
AIVORY_API_SSE_PING_HEARTBEAT_POST | duration | 15s | Send interval of SSE keep-alive pings on the send-message streaming endpoint. |
AIVORY_API_SSE_PING_HEARTBEAT_REGENERATE | duration | 15s | Send interval of SSE keep-alive pings on the regenerate-message streaming endpoint. |
AIVORY_API_SSE_PING_HEARTBEAT_STREAM | duration | 15s | Send interval of SSE keep-alive pings on the stream reconnect (attach) endpoint. |
AIVORY_API_STREAM_STATUS_RECHECK_INTERVAL | duration | 5s | Interval at which the stream reconnect handler re-polls message generation status to detect terminal states. |
AIVORY_API_STREAM_REPLAY_BATCH_SIZE | int | 200 | Number of buffered stream events read per batch when replaying/catching up a reconnected SSE stream. |
AIVORY_API_ONLINE_PRESENCE_TOUCH_THROTTLE | duration | 1m | Throttle interval between user online-presence seen touches, i.e. the TTL of the seen-cache marker. |
AIVORY_API_CONCURRENT_GEN_SLOT_SAFETY_TTL | duration | 30m | Safety TTL for the per-user concurrent-generation slot counter, letting stale held slots expire automatically. |
AIVORY_API_REQUEST_SIGNATURE_REPLAY_WINDOW_FUTURE | int64 | 300 | Request-signature replay protection: maximum seconds by which the X-Req-Ts timestamp may lag the server time before it is rejected as expired. |
AIVORY_API_REQUEST_SIGNATURE_REPLAY_WINDOW_PAST | int64 | 60 | Request-signature replay protection: maximum seconds by which the X-Req-Ts timestamp may lead the server time (clock-skew tolerance); larger values are rejected. |
AIVORY_API_CREDIT_MULTIPLIER | float | 5.0 | Divisor converting a model's combined input+output price into the relative credit multiplier shown in the selector. |
AIVORY_API_JSON_REQUEST_BODY_SIZE_CAP | int64 | 4194304 | Maximum accepted bytes for a JSON request body; larger bodies are rejected by MaxBytesReader. |
AIVORY_API_PROJECT_DETAIL_CONVERSATIONS_PAGE_SIZE | int | 200 | Number of active conversations loaded in the project detail response (fetch cap, offset 0). |
AIVORY_API_RATE_LIMIT_USER_2 | int | 20 | Per-user rate-limit allowance: maximum project document uploads per minute before returning 429. |
AIVORY_API_RATE_LIMIT_REGISTER_MAX | int | 5 | Per-IP allowance for POST /api/auth/register: maximum registration attempts per window before returning 429. |
AIVORY_API_RATE_LIMIT_REGISTER_WINDOW | duration | 60s | Rolling window of the per-IP rate limit on POST /api/auth/register. |
AIVORY_API_RATE_LIMIT_LOGIN_MAX | int | 10 | Per-IP allowance for POST /api/auth/login: maximum login attempts per window before returning 429. |
AIVORY_API_RATE_LIMIT_LOGIN_WINDOW | duration | 60s | Rolling window of the per-IP rate limit on POST /api/auth/login. |
AIVORY_API_RATE_LIMIT_LOGIN_2FA_MAX | int | 10 | Per-IP allowance for POST /api/auth/login/2fa: maximum two-factor attempts per window before returning 429. |
AIVORY_API_RATE_LIMIT_LOGIN_2FA_WINDOW | duration | 60s | Rolling window of the per-IP rate limit on POST /api/auth/login/2fa. |
AIVORY_API_RATE_LIMIT_LOGOUT_MAX | int | 30 | Per-IP allowance for POST /api/auth/logout: maximum logout requests per window before returning 429. |
AIVORY_API_RATE_LIMIT_LOGOUT_WINDOW | duration | 60s | Rolling window of the per-IP rate limit on POST /api/auth/logout. |
AIVORY_API_RATE_LIMIT_REFRESH_MAX | int | 30 | Per-IP allowance for POST /api/auth/refresh: maximum token refresh requests per window before returning 429. |
AIVORY_API_RATE_LIMIT_REFRESH_WINDOW | duration | 60s | Rolling window of the per-IP rate limit on POST /api/auth/refresh. |
AIVORY_API_RATE_LIMIT_VERIFY_EMAIL_MAX | int | 10 | Per-IP allowance for POST /api/auth/verify-email: maximum email verification attempts per window before returning 429. |
AIVORY_API_RATE_LIMIT_VERIFY_EMAIL_WINDOW | duration | 5m | Rolling window of the per-IP rate limit on POST /api/auth/verify-email. |
AIVORY_API_RATE_LIMIT_SEND_CODE_MAX | int | 3 | Maximum requests per IP within the window to POST /api/auth/send-code (sends login/verification code emails). |
AIVORY_API_RATE_LIMIT_SEND_CODE_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/auth/send-code code-sending endpoint. |
AIVORY_API_RATE_LIMIT_FORGOT_PASSWORD_MAX | int | 5 | Maximum requests per IP within the window to POST /api/auth/forgot-password (triggers the password-reset email). |
AIVORY_API_RATE_LIMIT_FORGOT_PASSWORD_WINDOW | duration | 15m | Fixed time window counting per-IP requests to the /api/auth/forgot-password endpoint. |
AIVORY_API_RATE_LIMIT_RESET_PASSWORD_MAX | int | 5 | Maximum requests per IP within the window to POST /api/auth/reset-password (resets the password with a code). |
AIVORY_API_RATE_LIMIT_RESET_PASSWORD_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/auth/reset-password endpoint. |
AIVORY_API_RATE_LIMIT_CAPTCHA_ISSUE_MAX | int | 20 | Maximum requests per IP within the window to GET /api/public/captcha (issues a slider CAPTCHA challenge). |
AIVORY_API_RATE_LIMIT_CAPTCHA_ISSUE_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the GET /api/public/captcha challenge-issuance endpoint. |
AIVORY_API_RATE_LIMIT_CAPTCHA_VERIFY_MAX | int | 20 | Maximum requests per IP within the window to POST /api/public/captcha/verify (validates a CAPTCHA answer). |
AIVORY_API_RATE_LIMIT_CAPTCHA_VERIFY_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/public/captcha/verify answer-validation endpoint. |
AIVORY_API_RATE_LIMIT_FIRST_RUN_SETUP_MAX | int | 10 | Maximum requests per IP within the window to POST /api/setup (first-run creation of the first administrator). |
AIVORY_API_RATE_LIMIT_FIRST_RUN_SETUP_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the POST /api/setup first-run bootstrap endpoint. |
AIVORY_API_RATE_LIMIT_PUBLIC_SHARED_CONVERSATION_MAX | int | 60 | Maximum requests per IP within the window to GET /api/public/shared/:token (viewing a shared conversation without login). |
AIVORY_API_RATE_LIMIT_PUBLIC_SHARED_CONVERSATION_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/public/shared/:token shared-view endpoint. |
AIVORY_API_RATE_LIMIT_SHARED_ASSETS_FILES_ARTIFACTS_MAX | int | 240 | Maximum requests per IP within the window to shared-conversation file and artifact resource routes. |
AIVORY_API_RATE_LIMIT_SHARED_ASSETS_FILES_ARTIFACTS_WINDOW | duration | 60s | Fixed time window counting per-IP requests to shared-conversation file/artifact resource routes. |
AIVORY_API_RATE_LIMIT_OAUTH_START_CALLBACK_HANDOFF_MAX | int | 20 | Maximum requests per IP within the window to the OAuth start, callback, and cross-domain handoff routes. |
AIVORY_API_RATE_LIMIT_OAUTH_START_CALLBACK_HANDOFF_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the OAuth start/callback/handoff routes. |
AIVORY_API_RATE_LIMIT_PASSWORD_CHANGE_SET_MAX | int | 5 | Maximum requests per IP within the window to the /api/me/password change-password and /api/me/password/set set-password endpoints. |
AIVORY_API_RATE_LIMIT_PASSWORD_CHANGE_SET_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/me/password change/set password endpoints. |
AIVORY_API_RATE_LIMIT_IDENTITY_LINK_START_MAX | int | 20 | Maximum requests per IP within the window to POST /api/me/identities/:id/link (starts an OAuth account link). |
AIVORY_API_RATE_LIMIT_IDENTITY_LINK_START_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the OAuth identity-link start endpoint. |
AIVORY_API_RATE_LIMIT_2FA_SETUP_ENABLE_DISABLE_MAX | int | 10 | Maximum requests per IP within the window to the setup, enable, and disable endpoints of /api/me/2fa. |
AIVORY_API_RATE_LIMIT_2FA_SETUP_ENABLE_DISABLE_WINDOW | duration | 5m | Fixed time window counting per-IP requests to the 2FA setup/enable/disable endpoints. |
AIVORY_API_RATE_LIMIT_REDEEM_CODE_MAX | int | 10 | Maximum requests per IP within the window to POST /api/me/redeem (redeem-code exchange). |
AIVORY_API_RATE_LIMIT_REDEEM_CODE_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/me/redeem exchange endpoint. |
AIVORY_API_RATE_LIMIT_WORKSPACE_JOIN_MAX | int | 30 | Maximum requests per IP within the window to /api/workspaces/join/:token (invite info and join). |
AIVORY_API_RATE_LIMIT_WORKSPACE_JOIN_WINDOW | duration | 60s | Fixed time window counting per-IP requests to the /api/workspaces/join/:token endpoint. |
AIVORY_API_SELF_USAGE_LOOKBACK_WINDOW | int | 30 | Days of lookback when GET /api/me/usage counts the caller's own messages. |
AIVORY_API_LIMIT | int | 200 | Default maximum number of workspaces returned by the admin workspace list endpoint when the request has no ?limit. |
AIVORY_API_ADMIN_WORKSPACE_DETAIL_CONVERSATIONS_PAGE_SIZE | int | 500 | Maximum number of conversations loaded in the admin workspace detail (triage) view. |
AIVORY_QUEUE_IN_PROCESS_WORKERS | int | 8 | Number of concurrent worker goroutines in the in-process background job pool. |
AIVORY_QUEUE_PROCESS_JOB_BUFFER | int | 256 | Buffered slots of the in-process job channel; when the buffer is full, Enqueue hands new jobs to the backpressure fallback path. |
AIVORY_QUEUE_QUEUE_BACKPRESSURE_JOB_TIMEOUT | duration | 30m | Context timeout for jobs run on the backpressure fallback goroutine when the in-process job buffer is full. |
AIVORY_QUEUE_QUEUE_WORKER_JOB_TIMEOUT | duration | 30m | Context timeout applied per job by the in-process queue workers. |
6. Authentication / Sessions / CAPTCHA
Token caches, verification-code validity and attempt limits, TOTP time windows, OAuth state TTLs, and more (excluding conventional format constants such as verification-code length).
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_API_MAX_CODE_ATTEMPTS | int | 5 | Allowed wrong attempts against an emailed verification/reset code before the code is invalidated. |
AIVORY_API_CODE_FAILURE_COUNTER_TTL | duration | 10m | Lifetime (TTL) of the per-email counter tracking wrong verification/reset code attempts. |
AIVORY_API_MINIMUM_PASSWORD_LENGTH | int | 8 | Minimum character length required for user-chosen account passwords at registration and password change. |
AIVORY_API_EMAIL_VERIFICATION_CODE_TTL | duration | 10m | Validity period of account email verification codes sent by email. |
AIVORY_API_PASSWORD_RESET_CODE_TTL | duration | 10m | Validity period of password reset codes sent by email. |
AIVORY_API_CAP_TOL | float | 0.025 | Tolerance allowed between the submitted slide position and the actual gap position for a slider CAPTCHA to pass. |
AIVORY_API_CAPTCHA_CHALLENGE_CACHE_TTL | duration | 2m | Time an unanswered slider CAPTCHA challenge stays valid in cache. |
AIVORY_API_CAPTCHA_PASS_TTL | duration | 10m | Validity of the signed pass token attesting a recent CAPTCHA pass. |
AIVORY_API_OAUTH_2FA_HANDOFF_COOKIE_TTL | duration | 300s | Max-Age of the short-lived HttpOnly cookie that hands the two-factor login ticket to the frontend after OAuth login. |
AIVORY_API_OAUTH_STATE_CACHE_TTL | duration | 10m | Validity of the OAuth flow state cache entry used as CSRF protection. |
AIVORY_API_OAUTH_TOKEN_EXCHANGE_CONTEXT_TIMEOUT | duration | 40s | Timeout cap for exchanging the authorization code for tokens (including one retry for a transient network failure) and fetching user info in an OAuth callback. |
AIVORY_API_OAUTH_CROSS_DOMAIN_HANDOFF_TOKEN_TTL | duration | 60s | Validity of the one-time cross-domain OAuth handoff token the frontend uses to exchange for a session. |
AIVORY_API_2FA_LOGIN_TICKET_BURN_THRESHOLD | int64 | 5 | Allowed wrong TOTP codes against a two-factor login ticket before the ticket is invalidated. |
AIVORY_API_ISSUE_TWOFA_TICKET | duration | 5m | Validity of the two-factor login ticket issued after a correct password, while the TOTP code is pending. |
AIVORY_OAUTH_APPLE_CLIENT_SECRET_JWT_EXPIRY | duration | 30m | Validity of the generated Apple OAuth client-secret JWT. |
7. Uploads / Files / Sharing
Image processing, storage cleanup cycles, direct-upload parts, share tokens, download cache TTLs, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_API_ADMIN_ICON_UPLOAD_SIZE | int64 | 262144 | Maximum bytes accepted for a model icon image uploaded by an administrator. |
AIVORY_API_AUDIO_TRANSCRIPTION_UPSTREAM_HTTP_TIMEOUT | duration | 120s | HTTP request timeout when forwarding audio to the upstream transcription API. |
AIVORY_API_AUDIO_TRANSCRIPTION_USER_RATE_LIMIT | int | 20 | Maximum audio transcription requests a single user may start per minute. |
AIVORY_API_TRANSCRIPTION_UPSTREAM_RESPONSE_READ_CAP | int64 | 1048576 | Byte cap on reading an upstream transcription response into memory. |
AIVORY_API_AUDIO_STREAM_USER_RATE_LIMIT | int | 30 | Maximum real-time voice streaming (WebSocket) sessions a single user may start per minute. |
AIVORY_API_AUDIO_STREAM_MAX_BYTES | int64 | 25165824 | Maximum audio bytes allowed to be relayed in a single real-time voice streaming session; the connection is closed when exceeded. |
AIVORY_API_AUDIO_STREAM_MAX_SESSION | duration | 15m | Hard duration cap for a single real-time voice streaming session (microphone → Volcano ASR relay). |
AIVORY_ASR_DEBUG | bool | false | Logs every decoded Volcano ASR response frame (message code, final-packet flag, transcript text length, raw JSON payload) to troubleshoot real-time transcription. Off by default — raw payloads contain user speech content and must be explicitly enabled. |
AIVORY_API_UPLOAD_RATE_LIMIT_MAX | int | 20 | Maximum file uploads a single user may perform within the upload rate-limit window. |
AIVORY_API_UPLOAD_RATE_LIMIT_WINDOW | duration | 1m | Time window used to count user file uploads for rate limiting. |
AIVORY_API_OBJECT_STORAGE_DELETE_TIMEOUT_CLEANUP | duration | 30s | Timeout for deleting a single orphaned file from object storage during storage cleanup. |
AIVORY_STORAGE_S3_DIRECT_UPLOAD_MIN_CLIENT_TIMEOUT | duration | 20m | Minimum HTTP client timeout required for direct S3/OSS uploads; if a reused client is below this, a new one is created. |
AIVORY_STORAGE_DIRECT_S3_OSS_UPLOAD_HTTP_CLIENT | duration | 20m | Timeout of the freshly created HTTP client for direct S3/OSS uploads when the reused client's timeout is too short. |
AIVORY_STORAGE_ALIYUN_OSS_CLIENT_CONNECT_READ_TIMEOUTS_CONNECT | int64 | 30 | Connect timeout (seconds) of the Aliyun OSS client used for direct uploads. |
AIVORY_STORAGE_ALIYUN_OSS_CLIENT_CONNECT_READ_TIMEOUTS_RW | int64 | 300 | Read/write timeout (seconds) of the Aliyun OSS client used for direct uploads. |
AIVORY_STORAGE_PRESIGN_URL_TTL | duration | 1h | Expiration applied to direct-upload presigned GET URLs when the caller specifies no validity period. |
AIVORY_STORAGE_PRESIGN_URL_TTL_CLAMP_CEILING | duration | 24h | Ceiling for clamping the validity period of caller-requested direct-upload presigned GET URLs. |
AIVORY_STORAGE_SIDECAR_STORAGE_CLIENT_HTTP_TIMEOUT | duration | 5m | HTTP round-trip timeout when calling the sandbox sidecar's object-storage put/delete endpoints. |
8. Admin Background Jobs (Backup / Vector Maintenance / Redeem Codes)
Backup size caps and asynchronous polling, vector maintenance batches, redeem-code limits, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_API_BACKUP_EXPORT_JOB_HISTORY_RETENTION | int | 20 | Number of past backup export job records kept in the in-memory history before the oldest are pruned. |
AIVORY_API_BACKUP_EXPORT_JOB_RUNTIME | duration | 12h | Maximum wall-clock runtime allowed for a background backup export job before it is canceled. |
AIVORY_API_CONFIG_IMPORT_MULTIPART_MEMORY_BUFFER | int64 | 16777216 | In-memory buffer for parsing admin config import multipart uploads; excess spills to a temporary file. |
AIVORY_API_BACKUP_IMPORT_MULTIPART_MEMORY_BUFFER | int64 | 33554432 | In-memory buffer for parsing full backup import multipart uploads; excess spills to a temporary file. |
AIVORY_API_MAX_CONFIG_SIZE | int64 | 536870912 | Maximum request body size accepted when importing an admin configuration archive. |
AIVORY_API_QDRANT_ARCHIVE_REQUEST_TIMEOUT | duration | 5m | Single HTTP request timeout for calls to Qdrant when exporting or importing backup archives. |
AIVORY_API_QDRANT_EXPORT_SCROLL_PAGE_SIZE | int | 256 | Points pulled per /points/scroll page when exporting a Qdrant collection to an archive. |
AIVORY_API_QDRANT_IMPORT_UPSERT_FLUSH_BATCH_SIZE | int | 128 | Points accumulated per batch before flushing an upsert when importing a Qdrant collection. |
AIVORY_API_ADMIN_USER_LIST_PAGE_SIZE_CAP | int | 50 | Default number of rows returned by the admin user list endpoint when the request does not explicitly specify limit. |
AIVORY_API_ADMIN_CREATED_USER_MIN_PASSWORD_LENGTH | int | 8 | Minimum password length enforced when an administrator creates a user account. |
AIVORY_API_ADMIN_PASSWORD_RESET_MIN_LENGTH | int | 8 | Minimum character length required for the new password in the admin password-reset endpoint. |
AIVORY_API_ADMIN_USER_CONVERSATIONS_LISTING_CAP | int | 500 | Maximum number of conversations returned when an administrator views a single user's conversations (for support/abuse triage). |
AIVORY_API_USAGE_REPORT_PAGE_SIZE_CAP | int | 50 | Default page size used by the admin usage-record report when the requested page_size is missing or outside the 1-200 range. |
AIVORY_API_ANALYTICS_WINDOW | int | 30 | Default lookback window (days) for the admin analytics dashboard when no days query parameter is provided. |
AIVORY_API_ANALYTICS_WINDOW_2 | int | 365 | Maximum days accepted for the admin analytics window days query parameter; out-of-range values are ignored. |
AIVORY_STORE_ADMIN_USAGE_RECORDS_LIMIT | int | 500 | Maximum positive pagination limit accepted by AdminUsageRecords; above it, the code falls back to AIVORY_STORE_ADMIN_USAGE_RECORDS_LIMIT_2 instead of clamping to the cap. |
AIVORY_STORE_ADMIN_USAGE_RECORDS_LIMIT_2 | int | 50 | Fallback page size used by AdminUsageRecords when the limit is ≤ 0 or exceeds AIVORY_STORE_ADMIN_USAGE_RECORDS_LIMIT. |
AIVORY_STORE_USAGE_TREND_WINDOW | int | 7 | Default lookback days used by AdminUsageTrend only when days ≤ 0; callers of AdminUsageTrendBetween pass explicit bounds. |
AIVORY_STORE_USAGE_TREND_HOURLY_BUCKET_THRESHOLD | int | 2 | UsageBucketWidth buckets day windows of at most this threshold by hour; in the remaining windows, ranges over 90 days bucket by week and the rest by day. |
AIVORY_STORE_USAGE_TOTALS_WINDOW | int | 7 | Default lookback days used by AdminUsageTotals only when days ≤ 0; callers of AdminUsageTotalsBetween pass explicit bounds. |
AIVORY_STORE_USAGE_BREAKDOWN_TOP_N | int | 8 | Default number of rows returned by AdminUsageBreakdownBetween only when limit equals 0; a negative limit returns everything. The current main admin analytics route passes -1, bypassing this cap. |
AIVORY_STORE_USAGE_BREAKDOWN_WINDOW | int | 7 | Default lookback days used by AdminUsageBreakdown only when days ≤ 0; callers of AdminUsageBreakdownBetween pass explicit bounds. |
AIVORY_STORE_USAGE_SERIES_WINDOW | int | 7 | Default lookback days used by AdminUsageSeries only when days ≤ 0; the current main admin analytics route does not call this legacy time-series wrapper. |
AIVORY_API_BULK_REDEEM_CODE_GENERATION_QUANTITY | int | 1000 | Maximum number of redeem codes a single bulk-generation request may mint. |
AIVORY_API_MAX_SKILL_ASSET_BYTES | int64 | 20971520 | Maximum bytes for a single skill asset file (template/script/small data) upload. |
AIVORY_API_VECTOR_MAINTENANCE_JOB_HISTORY_RETENTION | int | 20 | Number of recent vector maintenance jobs kept in the in-memory history; older ones are dropped. |
AIVORY_API_VECTOR_MAINTENANCE_JOB_RUNTIME | duration | 12h | Context timeout for a single vector maintenance job run (index audit or rebuild) before cancellation. |
9. Server Startup / Configuration Loading
HTTP server timeouts, graceful shutdown, startup-flow constants, and more.
| Environment variable | Type | Default | Description |
|---|---|---|---|
VECTOR_BACKEND | string | "auto" | Selects the vector backend used at process start. auto preserves compatible behavior: use Qdrant when QDRANT_URL is set, otherwise disable vector search and use the full-text context fallback; qdrant requires QDRANT_URL to be set; sqlite requires DATABASE_URL to not be PostgreSQL and enables SQLite embedded exact-cosine search; disabled always turns off vector search. Invalid values or combinations print a clear error and refuse to start. |
AIVORY_CMD_ARCHIVE_GC_BOOT_SETTLE_DELAY | duration | 2m | Delay between server start and the first archived-workspace GC sweep, avoiding an immediate sweep on a cold start. |
AIVORY_CMD_RUN_PRUNE | duration | 5m | Context timeout for a single archived-workspace GC prune run (against object storage). |
AIVORY_CMD_ARCHIVE_GC_SWEEP_INTERVAL | duration | 6h | Interval between archived-workspace GC sweeps, which delete expired /workspace archive bundles from object storage. |
Variables Added in the Current Version
The following variables are part of the current supported runtime but were not in the earlier tuning tables. Except for the web-fetch Jina fallback switch and base address, which are read on every fetch, they are all read at app startup and take effect after a restart.
| Environment variable | Type | Default | Description |
|---|---|---|---|
AIVORY_API_EVENTS_HEARTBEAT | duration | 25s | Interval at which live SSE connections send keep-alive comments; too long may get the connection cut by proxies, too short adds connection overhead. |
AIVORY_API_EVENTS_MAX_CONNS_PER_USER | int | 16 | Number of live event connections a single user may hold at once; when the cap is reached, the oldest connection is evicted. |
AIVORY_API_EVENTS_CONN_BUFFER | int | 16 | Buffered messages per live event connection; when the buffer fills, events are dropped and the client catches up on the next refresh or reconnect. |
AIVORY_API_RATE_LIMIT_PAYMENT_CHECKOUT_MAX | int | 15 | Maximum requests per IP allowed within the payment checkout rate-limit window. |
AIVORY_API_RATE_LIMIT_PAYMENT_CHECKOUT_WINDOW | duration | 60s | Payment checkout rate-limit window. |
AIVORY_API_RATE_LIMIT_PAYMENT_WEBHOOK_MAX | int | 600 | Maximum requests per IP allowed within the payment webhook rate-limit window; you should still rely on provider signature verification. |
AIVORY_API_RATE_LIMIT_PAYMENT_WEBHOOK_WINDOW | duration | 60s | Payment webhook rate-limit window. |
AIVORY_API_USER_DELETE_JOB_RUNTIME | duration | 2h | Total runtime cap for an asynchronous user-deletion job. |
AIVORY_API_USER_DELETE_FINAL_CLEANUP_TIMEOUT | duration | 1h | Separate time budget for cleaning up files, objects, and other physical resources in the user-deletion final phase. |
AIVORY_API_USER_DELETE_CONV_BATCH | int | 200 | Conversations processed per batch during asynchronous user deletion; larger values improve throughput but increase SQLite/database lock pressure. |
AIVORY_API_USER_DELETE_USAGE_BATCH | int | 10000 | Usage records cleaned per batch during asynchronous user deletion. |
AIVORY_API_USER_DELETE_JOB_HISTORY_RETENTION | int | 20 | Completed user-deletion job records kept in memory. |
AIVORY_API_USER_DELETE_PROGRESS_EVERY | int | 50 | Processing interval at which the user-deletion job updates its progress. |
AIVORY_LLM_PER_TURN_TOOL_LIMITS_FETCH_IMAGE | int | 16 | Per-message cap on fetch_image calls in normal mode. |
AIVORY_LLM_DEEP_RESEARCH_TOOL_LIMITS_FETCH_IMAGE | int | 12 | Per-message cap on fetch_image calls in deep research mode. |
AIVORY_LLM_TOOL_TIMEOUTS_FETCH_IMAGE | duration | 45s | Timeout cap for a single fetch_image tool call. |
AIVORY_RAG_SPREADSHEET_INDEX_MAX_FILE_BYTES | int64 | 31457280 | Maximum size of CSV/TSV/XLSX/XLSM files entering knowledge base indexing, 30 MiB by default. |
AIVORY_RAG_SPREADSHEET_INDEX_MAX_ROWS | int | 2000 | Maximum number of rows read per spreadsheet during indexing. |
AIVORY_RAG_SPREADSHEET_INDEX_MAX_COLS | int | 128 | Maximum number of columns read per spreadsheet during indexing. |
AIVORY_RAG_SPREADSHEET_INDEX_MAX_SHEETS | int | 32 | Maximum number of worksheets processed per workbook. |
AIVORY_RAG_SPREADSHEET_INDEX_MAX_TEXT_BYTES | int | 4194304 | Maximum bytes of extracted spreadsheet text written into the index, 4 MiB by default; the excess is explicitly marked as truncated. |
AIVORY_TOOLS_WEB_FETCH_DIRECT_TIMEOUT | duration | 12s | Single-attempt timeout for web fetch connecting directly to the target site. |
AIVORY_TOOLS_WEB_FETCH_JINA_FALLBACK | bool | true | Whether to fall back to Jina Reader when direct web fetch fails; disabling it reduces the set of URLs sent to a third party. |
AIVORY_TOOLS_WEB_FETCH_JINA_BASE | string | https://r.jina.ai | Base address of the Jina Reader fallback service; it should only point to a controlled, trusted compatible service. |
AIVORY_TOOLS_WEB_FETCH_JINA_URL_MODE | string | escaped | How the target URL is appended to the reader base. Use escaped for Jina Reader and raw for compatible services such as https://markdown.new; unknown values use escaped. |
AIVORY_PDF_INSPECTION_TEST_SLEEP | string | Not set | Only used in automated tests to simulate PDF inspection delay; it should not be set in production and does not improve parsing performance. |