Skip to main content
HyphaeDB is a standalone Rust service. You run one hyphae-server process that owns the in-memory HNSW mesh, talking to an external PostgreSQL instance that is the system of record. This page covers how to run that process — its two run modes, the volumes it needs, the Kubernetes wiring, and the production hardening posture. For a local stack, start with /operations/docker-compose. For the reasoning behind this shape, see /operations/deployment-operations.

Run modes

The same binary runs in two modes: Daemon mode is the deployable service. MCP stdio mode is for launching the server as a tool process (for example, from Claude Code) and binds no network ports.

Boot sequence

On start, the daemon connects to PostgreSQL, runs migrations and verifies the dimension/model contract, builds the embedder, ensures a bootstrap admin exists, rehydrates the mesh from storage, and begins serving with graceful signal handling:

Persistent volumes

A production deployment needs three durable volumes:

Embedding packaging

The embedding model is large and changes less often than the binary, so it does not belong in the app image. Choose one of three delivery modes through configuration:
1

Init-container warm (recommended)

A small init container pre-downloads the weights into the shared model-cache volume mounted at the embedding cache path. The app image stays small and the server starts with a warm cache.
2

Baked Candle

Weights are copied into a custom image and the provider is candle (the engine itself is compiled into the default image — only the weights need baking). Use this for air-gapped or immutable single-artifact deploys where the larger pull is acceptable.
3

TEI sidecar

Set HYPHAEDB_EMBEDDING_PROVIDER=tei and run a co-located TEI container. The weights live in the sidecar, keeping both the app image and the volume free of model files.

Kubernetes probes

Wire liveness and readiness so Kubernetes cooperates with mesh rehydration rather than fighting it:
  • livenessProbeGET /healthz. Gates on nothing external and stays 200 throughout rehydration, so Kubernetes never kills a pod that is correctly rebuilding its mesh.
  • readinessProbeGET /readyz. Returns ready only once every probe (storage, embedding, audit, graph) is Up, so the load balancer never routes to an instance still loading its mesh. The gRPC alternative (readinessProbe.grpc on port 50051) probes the same evaluator via the standard grpc.health.v1 service, which starts fail-closed NOT_SERVING; prefer the HTTP form — its response body names the failing probe.
These are the exact timings the shipped deploy/k8s/ and Helm manifests use.
Do not point livenessProbe at /readyz. Because readiness gates on rehydration, that would make Kubernetes kill a pod that is correctly warming its mesh — a restart loop that never finishes.
For high availability, run two replicas with HYPHAEDB_HA_ENABLED=1 (the Helm chart wires the env automatically at replicaCount > 1, where the PodDisruptionBudget also activates): the lease-race loser runs as a zero-write standby (/readyz 503, so no traffic routes to it) and promotes automatically when the primary dies or drains. Never run two instances without the flag — they would both act as primary against the same PostgreSQL. See /operations/high-availability.

Production posture

The service introduces a deployment profile that gates security:
  • Dev permits plaintext binds on loopback for friction-free local work.
  • Production mandates TLS/mTLS on every listener (a listener refuses to start without a TLS identity), secrets resolved through a manager rather than raw env, and encryption at rest on sensitive columns.
Authorization is always enforced — every read is scoped to the authenticated principal. See /operations/authorization.

Operational artifacts

The repository ships these under deploy/:

Source

This guide follows the deployment-operations spec and the staged rollout in the build-sequence spec.