Octopus
1.x
Docs/Octopus/Auto-discover services with FARP
Open

Reading3 min
Updated31 Jul 2026
Sourcev1/guides/farp-auto-discovery.mdx

Auto-discover services with FARP

FARP — the Forge API Gateway Registration Protocol — flips hand-written routing around: a discovery backend reports live service instances, Octopus fetches each one's published OpenAPI document, and turns its paths and methods into routes. As services scale, appear, or disappear, the routes follow. Static upstreams/routes and FARP discovery coexist, so you can adopt it incrementally.

1

Make services advertise themselves01

FARP only registers an instance — and generates routes for it — when its discovery metadata advertises farp.enabled = true. The OpenAPI document is then fetched from farp.openapi.path (default /openapi.json). How you set that metadata depends on the backend:

  • Kubernetes — carried on the Service/Pod metadata; filter with a label_selector.

  • Consul — service Meta.

  • mDNS — TXT records.

Instances without farp.enabled are discovered but skipped. See what a backend reports.

Enable FARP and pick a backend02

Set farp.enabled: true and list one or more backends under farp.discovery.backends. Each entry is tagged by type (mdns | dns | consul | kubernetes), has an enabled flag, and a backend-specific config.

yaml
farp:
  enabled: true
  watch_interval: 5s
  schema_cache_ttl: 5m
  discovery:
    backends:
      - type: kubernetes
        enabled: true
        config:
          namespace: default
          label_selector: "app.kubernetes.io/part-of=myapp"
          watch_interval: 10s
          use_endpoint_slices: true
          include_not_ready: false
Note

Each backend is gated behind a Cargo feature in the gateway build (mdns, dns, consul, kubernetes); the default runtime build enables only mdns. A configured-but-not-compiled backend is logged and skipped, not fatal. There is no type: etcd backend. The DNS backend is experimental (only watch_interval is applied) — prefer mDNS, Consul, or Kubernetes. See Discovery backends.

Validate and run03

octopus validate -c gateway.yaml
octopus serve -c gateway.yaml

A complete, validated configuration (Kubernetes backend):

gateway:
  listen: "0.0.0.0:8080"

farp:
  enabled: true
  watch_interval: 5s
  schema_cache_ttl: 5m
  discovery:
    backends:
      - type: kubernetes
        enabled: true
        config:
          namespace: default
          label_selector: "app.kubernetes.io/part-of=myapp"
          watch_interval: 10s
          use_endpoint_slices: true
          include_not_ready: false

Watch routes appear04

On each tick of watch_interval, Octopus polls every enabled backend, fetches the OpenAPI document of any newly advertised instance, and generates routes from it. Inspect the live route table through the admin dashboard (/admin/routes) or the Admin API. Scale a discovered Deployment up or down and the routes reconcile to match.

Readiness and discovery05

If you also run on Kubernetes with probes, /readyz can wait for the first discovery sync before reporting ready — gateway.probes.require_discovery_sync (default true) keeps a freshly started pod out of the Service EndpointSlice until it knows where its upstreams are. See Probes & drain and the observability guide.

See also06