---
title: "Octopus"
tagline: "API gateway"
language: "Rust"
license: "MIT OR Apache-2.0"
since: "2025"
canonical: "https://xraph.com/work/octopus"
---

# Octopus

A gateway in Rust that builds its own routing table. Services publish a FARP manifest carrying their OpenAPI, gRPC and GraphQL schemas; Octopus finds them over mDNS, Consul, Kubernetes or DNS and derives routes as instances appear and disappear. Static config works too, and the two modes run side by side.

## Install

```bash
cargo install octopus-gateway
```

## What it is

Octopus is an API gateway in Rust that can build its own routing table. Most gateways expect every route declared by hand, in a repository owned by a different team than the service it points at. Services that speak FARP publish their own schemas across OpenAPI, AsyncAPI, gRPC and GraphQL, and Octopus turns those into routes as instances come and go.

It also runs purely statically from a config file, and the two modes work together: static routes for the things that will never be discoverable, derived routes for everything else.

## What it does

- HTTP/1.1 and HTTP/2 reverse proxying with connection pooling, configurable timeouts and WebSocket upgrades.
- A trie-based router with wildcard matching, method filtering, prefix stripping and per-route priorities.
- Upstream load balancing (round-robin, weighted) with active health checks and circuit breaking.
- Service discovery over mDNS, Consul, Kubernetes or DNS.
- A middleware chain: request ids, CORS, JWT authentication, rate limiting, brotli/zstd/gzip compression, and inline Rhai scripting for the cases that need one-off logic.
- TLS termination including mutual TLS, with hot certificate reload.
- Prometheus metrics, OpenTelemetry and Jaeger tracing, structured JSON logs.
- Layered YAML, JSON or TOML configuration with environment-variable substitution, supplied as several -c flags or a directory and merged in order.

## Why Rust here

A gateway is a single well-defined program with a hot path, no user-authored handlers in its type signatures, and a need for predictable memory use under load. That is the shape of problem Rust is best at, and it avoids the thing that killed my two Rust frameworks, since nobody has to read a generic signature to use it.

## Octopus or Bastion

Octopus when the gateway is genuinely a separate network element with its own scaling and blast radius, which usually means cluster ingress. Bastion when the gateway is a logical concern inside a Go process, such as an aggregation layer, a backend for frontend, or a service fronting three others. Same protocol, same derived routes.

---

*Unpublished draft. Not peer reviewed and not submitted to a venue.*


## Anatomy

- **Controller**: Watches FARP manifests as Kubernetes resources.
- **Router**: Routes derived from manifests, never from gateway-side config.
- **Policy**: Rate limits, auth and transforms applied at the edge.
- **Telemetry**: Per-route metrics and traces out of the box.

## Constraints and trade-offs

- (decision) Rust here because the gateway is on every request path and the tail latency is the product.
- (constraint) The gateway holds no routing state of its own. If the manifest is wrong, the route is wrong.
