Skip to content

Make zoekt-webserver probes tunable - #983

Merged
devdinu merged 2 commits into
mainfrom
fix/zoekt-readiness-probe-tunable
Oct 27, 2026
Merged

devdinu merged 2 commits into
mainfrom
fix/zoekt-readiness-probe-tunable

Conversation

@devdinu

@devdinu devdinu commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

The zoekt-webserver probes are hardcoded. Readiness allows 15s of grace (failureThreshold: 3, periodSeconds: 5) and liveness allows 12 minutes (failureThreshold: 10, periodSeconds: 60), both with timeoutSeconds: 5. On instances where /healthz stalls past that timeout, readiness drops a healthy pod out of the indexed-search service and liveness restarts a container that is still serving. Neither window can be adjusted per instance.

Two causes seen in production. Loading the shards for a many-shard repo stalls /healthz during startup. Separately, where the on-disk index greatly exceeds the container memory limit, page cache fills to the cgroup ceiling and reclaim stalls every process in the cgroup for a sustained fraction of wall-clock time.

Changes

  • Add indexedSearch.readinessProbe with failureThreshold, periodSeconds, and timeoutSeconds
  • Add indexedSearch.livenessProbe with failureThreshold, initialDelaySeconds, periodSeconds, and timeoutSeconds
  • Defaults match the previously hardcoded values (3/5/5 and 10/120/60/5), so rendered output is unchanged unless a value is set
  • The two probes are independent, so overriding one leaves the other at its default

Liveness remains a backup to zoekt's in-process watchdog, as set up in #850. Any override should keep the probe window wider than ZOEKT_WATCHDOG_ERRORS x ZOEKT_WATCHDOG_TICK so the watchdog detects a wedged process first.

Raising a threshold is a mitigation, not a fix. It keeps a stalling pod in service rather than cycling it, but where the index outsizes the memory limit the real remedy is more replicas or more memory per pod.

ref EPD2-432

Test Plan

  • Rendered the StatefulSet from main and from this branch with default values. Output is byte-identical, so existing deployments are unaffected on upgrade
  • Rendered with a partial override of each probe and confirmed the other probe stays at its defaults
  • helm lint and the full helm unittest suite pass (206 tests, 35 suites)

Alert - Slack Investigation with restart trend: https://sourcegraph.slack.com/archives/C0A4S5X3L8P/p1793039912710159?thread_ts=1793033284.231829&cid=C0A4S5X3L8P

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

@devdinu devdinu changed the title Make zoekt-webserver readiness probe tunable Make zoekt-webserver probes tunable Oct 26, 2026
@devdinu
devdinu marked this pull request as ready for review October 26, 2026 18:35
@devdinu
devdinu requested a review from a team October 26, 2026 18:45

@filiphaftek filiphaftek left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIce catch!

The zoekt-webserver readiness probe is hardcoded to failureThreshold 3
and periodSeconds 5, so a pod has 15s of grace. On instances with large
monorepos that is not enough. Loading the shards for a many-shard repo
stalls /healthz past the 5s timeout, and the pod is dropped from the
indexed-search service while it is still healthy. Observed on a
138-shard repo, where /healthz went from 3-5ms to 245ms under shard
load with no container restarts.

The liveness probe already allows for this with failureThreshold 10 and
periodSeconds 60, which is why only readiness flaps. Readiness never
got the same treatment.

Makes the three timing fields overridable per instance. Defaults match
the previously hardcoded values, so rendered output is unchanged unless
a value is set.

- [x] Update [changelog](https://github.com/sourcegraph/deploy-sourcegraph-helm/blob/main/charts/sourcegraph/CHANGELOG.md)

- Rendered the StatefulSet from main and from this branch with default
  values. Output is identical
- Rendered with an override and confirmed only the readiness probe
  changes, liveness untouched
- helm lint and helm unittest pass
The zoekt-webserver liveness probe is hardcoded to failureThreshold 10,
periodSeconds 60, and timeoutSeconds 5, giving a container 12 minutes of
grace. Where the index greatly exceeds the container memory limit, page
cache fills to the cgroup ceiling and reclaim stalls /healthz past the 5s
timeout for minutes at a time. Consecutive failures then restart a
container that is still serving.

Makes the four timing fields overridable per instance. Defaults match the
previously hardcoded values, so rendered output is unchanged unless a
value is set. Keep any override wider than zoekt's in-process watchdog so
the watchdog stays the first line of defence.

### Test plan

- Rendered the StatefulSet from main and from this branch with default
  values. Output is identical
- Rendered with partial overrides of each probe and confirmed the other
  probe is unaffected
- helm lint and helm unittest pass
@devdinu
devdinu force-pushed the fix/zoekt-readiness-probe-tunable branch from ae6e89d to 965a7c5 Compare October 27, 2026 22:59
@devdinu
devdinu merged commit 64bae33 into main Oct 27, 2026
6 checks passed
@devdinu
devdinu deleted the fix/zoekt-readiness-probe-tunable branch October 27, 2026 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants