Skip to content

fix(embed): make daemon health-check timeout configurable (default 30s, was 2s) - #3402

Open
handnewb wants to merge 2 commits into
vectorize-io:mainfrom
handnewb:fix/daemon-health-timeout-configurable
Open

fix(embed): make daemon health-check timeout configurable (default 30s, was 2s)#3402
handnewb wants to merge 2 commits into
vectorize-io:mainfrom
handnewb:fix/daemon-health-timeout-configurable

Conversation

@handnewb

Copy link
Copy Markdown
Contributor

Summary

Fixes #3099: The embed daemon liveness check used a hardcoded 2-second HTTP timeout on /health. When the daemon's asyncio event loop was blocked by a slow LLM call (measured 17.4s for consolidation against custom providers), /health could not respond within 2s. The embed manager then misclassified the daemon as dead and force-killed + restarted it — even though it was merely busy.

Root Cause

Three hardcoded timeout=2 (and one timeout=1) values in the health-check path:

Location Old timeout Impact
is_running() line 198 timeout=2 Kill/restart decision
_port_health_ok() line 382 timeout=2 Port clearing on startup
profile_manager._check_daemon_running() line 578 timeout=1 Port scanning

Any LLM call that blocked the event loop for > 2s triggered a false kill.

Changes

  1. New env var HINDSIGHT_EMBED_DAEMON_HEALTH_TIMEOUT (default 30.0s) — configurable, above typical LLM latency.
  2. is_running() and _port_health_ok() use DAEMON_HEALTH_TIMEOUT instead of hardcoded 2s.
  3. profile_manager._check_daemon_running() bumped from 1s to 2s for consistency (less critical path).

Impact

  • Daemons running slow LLM calls (consolidation, large retains) are no longer falsely killed.
  • Operators using fast providers can set HINDSIGHT_EMBED_DAEMON_HEALTH_TIMEOUT=5 to detect dead daemons sooner.
  • No change to startup behavior — the grace-period timeout _wait_for_port_health is separate.

The embed daemon liveness check used a hardcoded 2-second HTTP timeout on
/health.  When the daemon's asyncio event loop was blocked by a slow LLM
call (measured 17.4s for consolidation against custom providers), /health
could not respond within 2s.  The embed manager then misclassified the
daemon as dead and force-killed + restarted it.

Changes:
- New HINDSIGHT_EMBED_DAEMON_HEALTH_TIMEOUT env var (default 30.0s).
- is_running() and _port_health_ok() both use the configurable timeout
  instead of the hardcoded 2s.

The default of 30s is set above typical LLM latency (15-20s) to avoid
false positives while still detecting truly dead daemons.  Operators
whose provider is known to be faster can lower this to detect outages
sooner.

Closes vectorize-io#3099.
@handnewb
handnewb force-pushed the fix/daemon-health-timeout-configurable branch from 3f8d089 to 43c9ca8 Compare August 11, 2026 21:28
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.

Bug: hindsight-embed daemon is falsely killed by the 2s /health timeout when the event loop is blocked by a slow LLM call

1 participant