Architecture

Three Rust binaries. One Postgres database. No cloud required.

Overview

Flux is three independent binaries that work together:

BinaryRole
flux-runtimeRuns your TypeScript app via Deno V8. Records every request: inputs, outputs, console logs, IO checkpoints.
flux-serverStores execution records in Postgres. Serves the gRPC API that the CLI and runtime use.
flux (CLI)Developer tools — tail, why, trace, replay, resume.

All state lives in a single Postgres database. No microservices, no cloud account, no data leaving your infrastructure.

Request lifecycle

When a request arrives:

  1. The runtime executes your TypeScript handler (via Deno V8)
  2. Every Postgres query or Redis call goes through a recorded checkpoint
  3. Console output is captured
  4. On completion (success or error), the full execution record is sent to the server and stored in Postgres
  5. flux tail streams this event in real-time

The replay / resume model

This is the core of what makes Flux different:

CommandModeWhat it does
flux replay Safe Re-runs the request using recorded checkpoints for all IO. The real database is never touched. Stops cleanly at IO boundaries where no checkpoint was recorded (e.g., when original request failed before reaching the DB).
flux resume Live Re-runs the request with real IO — actually writes to Postgres, calls external services. Use this after replay confirms your fix works.
replay = investigation. resume = action.

This separation is intentional. replay is always safe to run — it cannot accidentally mutate your database. resume has a confirmation prompt because it performs real side effects.

What gets recorded

For every request, Flux records:

  • HTTP method, path, status code, duration
  • Request body and headers
  • Console output (console.log, errors, stack traces)
  • IO checkpoints: every Postgres query, Redis command, etc. — request + response
  • Final output or error

Deployment

Minimal production setup:

# start the server
$ DATABASE_URL=postgres://... flux-server

# serve your app
$ DATABASE_URL=postgres://... flux serve index.ts

Or with Docker — two containers (your app + Postgres) is the complete stack.