Code Review scaling and limits
Scale self-hosted Code Review workers and configure concurrency, budgets, metrics, retention, and encrypted artifact storage.
Self-hosted Code Review separates webhook and dashboard traffic from queued review and Code Intelligence work. Dedicated workers share Redis and the main database, so you can tune queue classes independently and add worker replicas without moving the web process.
Budget behavior
Organization owners configure limits under Dashboard → Settings → Code Review. Repository settings may add narrower token and cost budgets, while embedding-token and indexing-time budgets are organization-wide.
Budget enforcement changes the observable review behavior:
- At 80% usage, new reviews switch to
diff_onlycontext. They still run, but omit repository-aware context until the applicable daily or monthly budget resets. - At 100%, automatic reviews are skipped. Interactive reviews use
diff_onlywhen When the budget is exhausted isdegrade, the default. - Set that control to
blockonly when interactive reviews must also fail once the budget is exhausted.
Organization automatic reviews per hour and Organization automatic reviews per day cap automatic reviews across all repositories in the organization.
Both are disabled by default (an empty value means no organization-wide cap).
Admission-time throttle and budget decisions made by the web service are
written to the organization audit log. The worker rechecks budgets before
model work; if a threshold is crossed after admission, its diff_only,
skipped_budget, or budget_exhausted decision is visible in the run state but
does not currently create an organization audit entry.
Budget metering fails open if its aggregate cannot be read: reviews remain available and Skitflow records diagnostic evidence instead of causing an outage.
Worker capacity
Start from these defaults and tune against CPU, memory, provider rate limits, and queue latency:
| Variable | Default | Scope |
|---|---|---|
SKITFLOW_CODE_REVIEW_ORG_CONCURRENCY | 2 | Concurrent reviews per organization. |
SKITFLOW_CODE_REVIEW_REPO_CONCURRENCY | 1 | Concurrent reviews per repository. |
SKITFLOW_CODE_REVIEW_MAX_CHANGED_FILES | 100 | Maximum changed files admitted to a review; the worker checks it again. |
SKITFLOW_CODE_REVIEW_INTERACTIVE_CONCURRENCY | 8 | Interactive jobs per worker replica. |
SKITFLOW_CODE_REVIEW_BACKGROUND_CONCURRENCY | 4 | Automatic jobs per worker replica. |
SKITFLOW_CODE_REVIEW_SHADOW_CONCURRENCY | 2 | Shadow-evaluation jobs per worker replica. |
SKITFLOW_CODE_REVIEW_BACKGROUND_RATE_MAX | 60 | Automatic jobs per rate window. |
SKITFLOW_CODE_REVIEW_SHADOW_RATE_MAX | 30 | Shadow jobs per rate window. |
SKITFLOW_CODE_REVIEW_RATE_DURATION_MS | 60000 | Rate-limit window in milliseconds. |
Interactive reviews have no rate cap unless
SKITFLOW_CODE_REVIEW_INTERACTIVE_RATE_MAX is set. Code Intelligence has
separate trigger, worker, embedding, and cleanup concurrency controls; see the
deployment's docs/PRODUCTION_ENV.md for the complete environment-variable
contract.
On a single-node installation, SKITFLOW_MAX_TOTAL_CONCURRENCY is a safety
ceiling for in-process workers. It defaults to twice the available CPU count.
Skitflow logs a startup warning when the sum of enabled per-class concurrency
exceeds it; lower the class limits or move work to dedicated worker replicas.
In Swarm, keep the web service on a manager because it manages the cluster.
The Code Review worker is a separate service labelled
skitflow.component=code-review and skitflow.class=mixed; use placement
constraints and resource reservations appropriate to your worker nodes. Do not
move the web service to a worker node to gain review capacity.
Redis queue migration
SKITFLOW_QUEUE_PREFIX defaults to skitflow and isolates Skitflow's Redis
keys. Keep it stable after migration.
SKITFLOW_QUEUE_LEGACY_DRAIN is only for upgrading from a build that used
unprefixed queues. Set it to true temporarily on the worker to start a second
consumer for the legacy queues. Return it to false after every legacy queue
has zero waiting, active, delayed, and prioritized jobs in two checks at least
60 seconds apart. Leaving it enabled consumes extra worker concurrency.
Worker metrics
Workers expose Prometheus text at GET /metrics on
SKITFLOW_METRICS_PORT (default 9095). SKITFLOW_METRICS_TOKEN optionally
requires Authorization: Bearer <token> from the infrastructure scraper.
Self-hosted workers bind to 127.0.0.1 by default; use
SKITFLOW_METRICS_HOST only when an internal collector must reach them.
install.sh does not currently pass these three metrics variables into the
worker service. Script-based installations therefore use the worker image
defaults (loopback, port 9095, no token). To use a private-network scraper,
add the required variables directly to skitflow-code-review-worker after
installation, for example with docker service update --env-add.
Never publish the metrics port through Traefik, a public load balancer, or a host port. It is an internal infrastructure endpoint. Keep it on the private worker network even when bearer authentication is enabled.
Encrypted artifact storage
An S3-compatible bucket is optional. If SKITFLOW_ARTIFACT_S3_BUCKET is unset,
artifact writes become no-ops and reviews, indexing, embedding, and cleanup
continue normally. An installation without S3 is fully supported.
| Variable | Purpose |
|---|---|
SKITFLOW_ARTIFACT_S3_BUCKET | Enables artifact storage. |
SKITFLOW_ARTIFACT_S3_REGION | Region; defaults to us-east-1. |
SKITFLOW_ARTIFACT_S3_ENDPOINT | Optional S3-compatible endpoint. |
SKITFLOW_ARTIFACT_S3_FORCE_PATH_STYLE | Set to true when required by MinIO or another provider. |
SKITFLOW_ARTIFACT_KEY | Preferred encryption root; falls back to SKITFLOW_SECRET_KEY, then BETTER_AUTH_SECRET. |
SKITFLOW_CODE_REVIEW_DEBUG_BUNDLES | Retains successful-run debug bundles when true; failed-run capture is automatic. |
The AWS default credential chain is supported. Objects are encrypted in the
application with AES-256-GCM and a per-organization HKDF-SHA256 key before
upload. Changing the effective root key makes existing objects unreadable;
there is no key rotation in this version. Configure the bucket lifecycle to
expire objects tagged retention=30d after 30 days.
Database retention
The scheduled retention job:
- deletes
code_review_webhook_eventsafter 30 days; - clears policy and context diagnostic JSON from
code_review_runsafter 90 days, while preserving the run record; - aggregates detailed
code_review_usageinto monthly rows before deleting detail older than 13 months.
Aggregation and detail deletion happen in one transaction so usage detail is not removed before the monthly totals are durable.
Production reference
The public defaults and contracts on this page match
skitflow-cloud/docs/PRODUCTION_ENV.md, the deployment compose files, and the
production environment example. When upgrading, compare local overrides with
that file before changing worker topology or limits.