Files streamed in parallel through the proxy-upload fallback. Bounds peak server memory (~100 MB per in-flight file × this value). The default direct browser→S3 path uses no server memory.
MULTIPART_URL_EXPIRY
3600
Lifetime (seconds) of each presigned multipart part URL. Parts are signed just-in-time, so this only needs to cover a single part’s upload.
MAX_UPLOAD_SIZE
5368709120 (5 GB)
Maximum total size for a proxy upload request. Does not apply to direct browser→S3 uploads.
Authentication mode: local (username/password) or s3 (log in with S3 access key + secret; access is scoped to each user’s own keys via the provider’s IAM)
ADMIN_USER
admin
Username for the default admin account
ADMIN_PASS
(auto-generated)
Password for the default admin account. If not set, a random password is printed to logs on first startup.
JWT_SECRET
(auto-generated)
Secret key for signing JWT tokens. Set explicitly for multi-instance deployments.
SESSION_HOURS
24
Session duration in hours
SECURE_COOKIE
true
Set to false for HTTP (non-HTTPS) deployments or cookies will silently fail
Seconds between automatic reindex cycles for each bucket
DB_DIR
/data
Directory where SQLite index databases are stored
FULL_CRAWL_INTERVAL
3600
Seconds between full reconcile crawls for large buckets (delta crawls run on RECRAWL_INTERVAL in between)
LARGE_BUCKET_SECONDS
60
A bucket whose full crawl takes longer than this is treated as “large” and kept fresh with delta crawls + periodic full reconcile, instead of full re-crawls every interval
REBUILD_MAX_DURATION
7200
Seconds a search-index rebuild may hold its bucket. Past this the reservation is abandoned so crawls and deltas can resume, mirroring the equivalent ceiling on a crawl. Raise it only if a single bucket’s rebuild legitimately runs longer than two hours.
FTS_PROBE_MS
10000
Milliseconds the search-index health probe may run before it gives up. The probe is three constant-time queries, so only an unreadable or corrupt index reaches this; one that does is treated as unhealthy and rebuilt rather than blocking the caller.
These bound how the incremental delta crawler discovers new data on large buckets. The defaults suit time-partitioned layouts (e.g. year=/month=/day=/hour=); they rarely need changing.
Variable
Default
Description
DELTA_SAMPLE
3000
How many of the most recently-indexed objects to sample to locate the “hot” prefixes a delta crawl should re-list
DELTA_MAX_TARGETS
40
Cap on the number of hot prefixes re-listed per delta crawl
DELTA_BRANCH_FANOUT
8
Levels with more children than this are treated as time partitions (follow only the newest few); fewer means a descriptive branch (follow all)
DELTA_NEWEST_K
2
How many of the newest partitions to re-list at a partition level (current + just-rolled)
DELTA_MAX_DEPTH
12
Safety cap on prefix-walk depth
LIST_CONCURRENCY
16
Total S3 list calls in flight across every bucket the crawler is working on, covering initial crawls, reconciles, delta discovery and delta target listing. The per-bucket settings below bound one bucket; this bounds the process. Raising it raises peak memory, since each in-flight listing holds a response body and a batch buffer. Clamped to S3_MAX_POOL_CONNECTIONS so concurrent lists never overflow the connection pool.
DELTA_LIST_CONCURRENCY
16
Parallel S3 list calls per level during delta discovery, within the LIST_CONCURRENCY total
DELTA_MAX_NODES
2000
Safety cap on folders visited per delta crawl
DELTA_NODE_MAX_PAGES
3
Delimiter pages read per folder during delta discovery, at 1,000 entries each. A folder wider than this is left unvisited and the delta is reported partial rather than certified. Raise it if a single folder legitimately holds more than 3,000 children.
Login attempts are rate-limited with two layers: 10 per minute via slowapi and 10 per 5 minutes per IP via a hardcoded window. Neither is independently configurable.
Send an anonymous usage heartbeat (schema v2: aggregate counts, instance health, and activation timestamps only — never names, keys, paths, or content). Set to false to disable entirely. See Telemetry.
TELEMETRY_INTERVAL
3600
Seconds between heartbeats.
TELEMETRY_URL
https://dashboard.sairo.dev/api/v1/ping
Endpoint the heartbeat is POSTed to. Override to point at your own collector (or leave unset to disable by setting TELEMETRY=false).
SAIRO_STORAGE_EPHEMERAL
(auto)
Optional hint for the telemetry id_persistence field: true if DB_DIR is ephemeral (e.g. emptyDir), false if durable. The Helm chart sets it from persistence.enabled; otherwise Sairo infers it from the mount table.