Skip to content

Revision · Part 4: Production Infra

Part 4 is about making quill run somewhere that isn’t your laptop — and survive there. It adds each piece in the order a real service adopts them: a cache and rate limiter first (Redis), then reproducible packaging (Docker), then an orchestrator that keeps it alive and scales it (Kubernetes).

  • Redis, three ways — cache rendered post pages, rate-limit the AI endpoints per user, and back the Part 3 job queue with a real shared store instead of an in-process channel; the win is fast, atomic ops that other pods can see.
  • Docker done small and safe — a multi-stage build that compiles the Rust workspace and ships a tiny, non-root image (distroless or scratch-ish), plus a docker-compose.yml bringing up quill + Postgres + Redis for local development.
  • Kubernetes as the orchestrator — Deployments for the web and worker binaries, a Service and Ingress, ConfigMaps and Secrets for config, liveness/readiness probes wired to /health, rolling deploys, graceful shutdown, and resource requests/limits.
  • Scale and resilience — a HorizontalPodAutoscaler that adds pods under load and backs off when quiet, plus backpressure and zero-downtime deploys.
  • Rust’s unfair advantage here — a Rust binary has no interpreter or VM, so its container image can be just the binary (often under 30 MB), meaning faster pulls, faster pod starts, a smaller attack surface, and honest resource limits.

Part 4’s answer to the thread is to make failure and scale someone else’s problem — declaratively. You stop running the process and start describing the state you want; Kubernetes reconciles reality to match. Your job becomes writing honest health checks and resource limits so the orchestrator can do its job. Next, Part 5 makes the now-opaque running system explain itself.