perf(selfhost): document retention/concurrency sizing, fix stale runner docs - #4142
Conversation
…er docs (#1828) Prometheus's 180d retention default had no sizing rationale and no comment, unlike the explicitly-justified 336h/14d (Loki) and 168h/7d (Tempo) siblings; git history shows it silently replaced a deliberate 30d default when it became an override-able env var in #1678. Add a comment justifying why metrics can reasonably outlive logs/traces (far cheaper per-day TSDB storage) while lowering the default to 90d, a considered middle ground rather than an unexplained six-month default. QUEUE_CONCURRENCY/QUEUE_BACKGROUND_CONCURRENCY had no core-count-based sizing guidance, unlike PGPOOL_MAX's existing "raise if you see X, watch Y" treatment. Add equivalent guidance anchored to vCPU count. The self-hosting-operations docs claimed the runner service "ships with no CPU/memory limit at all" in two places; this became false once RUNNER_MEM_LIMIT (default 2g) was added for #3893. Fix both occurrences, plus the adjacent table cell making the same now-incorrect claim, to describe the current state: a default memory ceiling with CPU-priority pinning remaining opt-in via docker-compose.override.yml.example.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | e16e74f | Commit Preview URL Branch Preview URL |
Jul 08 2026, 07:40 AM |
|
Warning 🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨🟨 ⏸️ Gittensory review result - manual review recommendedReview updated: 2026-07-08 07:44:13 UTC
⏸️ Suggested Action - Manual Review
Review summary Nits — 8 non-blocking
Linked issue satisfactionPartially addressed Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
|
Went through all 8 nits from the review: 1/4.
2/7. No tests / test-path changes — as the review itself notes for nit 2, expected: the diff is
On the "linked issue satisfaction: partially addressed" note: correct as far as it goes for what this |
Summary
Behavior change, not just documentation: the Prometheus retention default drops from
180dto90d. Any fresh self-host deployment that has not setPROMETHEUS_RETENTION_TIMEexplicitly will get90 days of metrics history instead of 180 on its next
docker compose upfor that service. Existingrunning deployments are unaffected until the
prometheuscontainer is recreated with the new image(Prometheus does not retroactively delete data on a live container from a compose-file-only change);
recreation will prune anything older than 90 days. Operators who want to keep 180d (or any other
value) can set
PROMETHEUS_RETENTION_TIME=180din their.envto opt back in — the var was alreadyoverride-able before this PR, only the unset-fallback value changes.
Issue #1828's earlier work already shipped the per-service memory limits, the resource-profile
matrix, the image-size audit, the dashboard, and the Redis/Loki/Tempo sizing. This closes out the
three remaining gaps found on a direct re-check of the current
docker-compose.yml/.env.example/docs:docker-compose.yml's Prometheus--storage.tsdb.retention.time=${PROMETHEUS_RETENTION_TIME:-180d}had no sizing-rationale comment, unlike the sibling Loki (
336h/14d) and Tempo (168h/7d) settings.Rather than just add a comment defending 180d as-is, I traced its history
(
git log -S "PROMETHEUS_RETENTION_TIME" -- docker-compose.yml): it was a deliberate30ddefaultuntil feat(selfhost): wire Codex reviews and secure observability #1678 silently turned it into an override-able var defaulted to
180dwith zero rationale.Metrics genuinely can justify outliving logs/traces — Prometheus's TSDB compresses numeric samples
to ~1-2 bytes each after compaction, so retaining them longer costs far less disk per day than
Loki's raw log lines or Tempo's full span trees — but six months with no stated reasoning is drift,
not a decision. Lowered the default to
90d(a full quarter for the capacity-planning trend windowthe docs already describe) and added a comment explaining both the "why longer than Loki/Tempo" and
the "why not 180d" reasoning.
.env.example'sQUEUE_CONCURRENCY(src/selfhost/sqlite-queue.ts,src/selfhost/pg-queue.ts,fallback 4) and
QUEUE_BACKGROUND_CONCURRENCY(src/selfhost/queue-common.ts,DEFAULT_BACKGROUND_CONCURRENCY = 1) had no core-count-based sizing guidance, unlike the existingPGPOOL_MAXcomment. Added guidance anchored to vCPU count (a 2-vCPU host is comfortable around thedefault of 4; 4+ vCPUs can reasonably go to 8-12) and scaled
QUEUE_BACKGROUND_CONCURRENCYrelativeto
QUEUE_CONCURRENCY(roughly a quarter to a third of it) rather than as an independent number.apps/gittensory-ui/src/routes/docs.self-hosting-operations.tsxclaimed in two places that therunnerservice "ships with no CPU/memory limit at all." That became false onceRUNNER_MEM_LIMIT(default
2g, docker-compose.yml line ~820) was added for fix(selfhost): add default memory/CPU limits to the runner compose service #3893. Fixed both occurrences plus athird, directly adjacent table cell making the same now-stale claim ("Unbounded by default" in the
Memory column) so the row is internally consistent — all three now correctly describe a default
memory ceiling with CPU-priority pinning remaining opt-in via
docker-compose.override.yml.example.This is a docs + config-comment change; no
src/**/packages/**lines were touched, so there is noCodecov obligation on this diff (verified:
git diff --name-onlyagainstorigin/mainshows onlydocker-compose.yml,.env.example, and the oneapps/gittensory-uiroute file).Closes #1828.
Scope
type(scope): short summaryConventional Commit format, for examplefix(api): restore profile access checks.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #1828) — verified open/unassigned viagh issue view 1828 --json state,assignees.Validation
git diff --checknpm run actionlint(vianpm run test:ci; no workflow files touched, ran anyway as part of the full gate)npm run typechecknpm run test:coveragelocally — 582 passed / 2 skipped, unsharded. Nosrc/**/packages/**lines changed, so no new coverage obligation; ran it anyway to confirm nothing broke.npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderate— 0 vulnerabilitiessrc/**/packages/**code changed, only prose/comments indocker-compose.yml,.env.example, and one docs route.Additionally ran the full
npm run test:cigate (all steps:db:migrations:check,db:schema-drift:check,selfhost:env-reference:check,selfhost:validate-observability,cf-typegen:check,test:coverage,test:workers,build:mcp/test:mcp-pack,build:miner/test:miner-pack,rees:test,ui:openapi:check/ui:openapi:settings-parity,ui:version-audit,docs:drift-check,command-reference:check,ui:lint/ui:typecheck/ui:test/ui:build) — all green. Also validateddocker-compose.ymldirectly withdocker compose -f docker-compose.yml config --quiet(exit 0) andconfirmed
.env.example's new comment lines don't collide withselfhost:env-reference:check's96-reference count (unchanged — these are comment-only edits to already-documented vars).
Safety
ui:openapi:checkconfirms no drift.)UI Evidencesection below with JPG/JPEG or PNG screenshots arranged as organized, captioned, clickable thumbnails. SVG screenshots are not used as review evidence. Review-only screenshots or recordings are not committed to the repository. (No visual/layout change — corrected prose within an existing table cell and an existing paragraph; see UI Evidence below.)UI Evidence
Not applicable: this PR only corrects prose text inside an existing table cell and an existing
paragraph on an already-shipped docs page (
docs.self-hosting-operations.tsx) — no new component,layout, or styling. The rendered structure is identical to what is already live; only the words
describing the runner service's memory/CPU limits changed to match current behavior.
Notes
docker-compose.yml'srunnerservice(
RUNNER_MEM_LIMITdefault2g, added for fix(selfhost): add default memory/CPU limits to the runner compose service #3893) anddocker-compose.override.yml.example'scpu_shares/cpusCPU-priority mitigation (confirms CPU pinning is still opt-in);.env.example'sexisting
PGPOOL_MAXcomment (the style mirrored for the newQUEUE_CONCURRENCY/QUEUE_BACKGROUND_CONCURRENCYguidance);src/selfhost/sqlite-queue.tsandsrc/selfhost/pg-queue.ts(QUEUE_CONCURRENCYfallback of 4) andsrc/selfhost/queue-common.ts(
DEFAULT_BACKGROUND_CONCURRENCY = 1);loki/loki-config.yml(retention_period: 336h) andtempo/tempo.yaml(block_retention: 168h) for the sibling retention comparison; andgit log -S "PROMETHEUS_RETENTION_TIME" -- docker-compose.ymlfor the 30d→180d history behind thenew 90d default.
scripts/validate-observability-configs.mjsandtest/), so lowering the default to90dneeded notest updates. Operators who want the old 180d (or the original 30d) can still set
PROMETHEUS_RETENTION_TIMEexplicitly.as fact in shipped docs/config:
#3893(docker-compose.yml's pre-existingRUNNER_MEM_LIMITcomment, which this PR does not change, only mirrors into the docs route) is a closed issue —
gh api graphqlconfirmsclosedByPullRequestsReferencespoints at merged PR fix(selfhost): add default memory limit to the runner compose service #3913, "add defaultmemory limit to the runner compose service."
#1678is merged PR "wire Codex reviews and secureobservability" —
git showon itsdocker-compose.ymlhunk confirms it is the exact commit thatchanged the hardcoded
30dto${PROMETHEUS_RETENTION_TIME:-180d}. Both check out.