CLI Reference

Complete reference for the flux command-line tool.

Installation

$ curl -fsSL https://fluxbase.co/install | bash
$ flux --version

Command index

CommandDescription
SETUP
flux loginAuthenticate with Flux
flux createScaffold a new project from a template
flux initLink current directory to an existing project
flux devRun functions locally with hot reload
flux doctorCheck CLI config and connectivity
DEPLOY
flux deployDeploy functions to production
flux invokeInvoke a deployed function
MONITORING
flux tailStream live requests in real time
flux logsQuery historical function logs
DEBUGGING
flux whyRoot-cause why a request failed
flux traceShow the full span tree for a request
flux trace debugStep through a request span-by-span
flux trace diffCompare two requests span-by-span
DATA
flux state historyShow every mutation to a database row
flux state blameShow the last writer for each column
INCIDENT TOOLS
flux incident replayReplay a traffic window against current code
flux bug bisectBinary-search commits to find a regression
QUERY TOOLS
flux explainPreview the query plan for a ctx.db call
PROJECT MANAGEMENT
flux secretsManage project secrets
flux projectCreate, list, update, and delete projects
flux api-keyCreate, list, revoke, and rotate API keys
flux db pushApply pending schema migrations
flux queueInspect dead-letter queue and replay jobs

flux login

Authenticate with your Flux instance. Saves a token to ~/.config/flux/config.toml.

flux login [--host <url>]
$ flux login --host http://localhost:4000
  ✔ Authenticated with localhost:4000

flux create

Scaffold a new project from a built-in template.

flux create <name> [--template <slug>]
FlagDescription
--template, -tTemplate slug. If omitted, shows interactive picker.

Available templates:

SlugDescription
todo-apiFull CRUD REST API with Postgres
webhook-workerWebhook receiver and event processor
ai-backendAI/LLM proxy with logging and caching
# Interactive picker
$ flux create my-app

# With template
$ flux create my-app --template todo-api

flux init

Link the current directory to an existing Flux project. Creates a .flux config file.

flux init --project <project-id>
$ flux init --project proj_abc123
  ✔ Linked to project "my-app"  (.flux)

flux dev

Run all functions in functions/ locally with hot reload. Shares the same ctx API as production.

flux dev [--port <n>]
FlagDefaultDescription
--port, -p7700Local port to listen on
--no-dbfalseDisable database; useful for pure logic testing
$ flux dev
  ✔ Watching functions/   (5 functions)
  ✔ Listening on          http://localhost:7700

flux doctor

Check CLI configuration and connectivity.

flux doctor
$ flux doctor

  ✔ CLI version:        0.1.0
  ✔ Config file:        ~/.config/flux/config.toml
  ✔ Authenticated:      you@example.com
  ✔ API reachable:      http://localhost:4000  (42ms)
  ✔ Gateway reachable:  https://localhost:4000   (38ms)

flux deploy

Bundle and deploy functions to production.

flux deploy [--name <fn-name>] [--runtime <runtime>] [--dry-run]
  • Run from the project root to deploy all functions in functions/.
  • Run from inside a function directory (contains flux.json) to deploy just that function.
FlagDescription
--nameOverride function name (single-function mode)
--runtimeOverride runtime: deno (default) | node
--dry-runBundle and validate without uploading
--envTarget environment: production (default) | staging
# Deploy all functions
$ flux deploy

# Deploy a single function
$ flux deploy --name create_user

# Validate bundle without deploying
$ flux deploy --dry-run

flux invoke

Invoke a deployed function directly, bypassing the gateway.

flux invoke <name> [--payload <json>] [--gateway] [--env <env>]
FlagDescription
--payloadJSON body to pass as input
--gatewayRoute through the API gateway (auth + rate-limiting apply)
--envTarget environment: production (default) | staging
$ flux invoke create_user --payload '{"email":"a@b.com"}'

  201  81ms  req:4f9a3b2c
  { "id": 42, "email": "a@b.com" }

flux tail

Stream live requests and their outcomes in real time. This is the starting point for most debugging workflows.

flux tail [--filter <expr>] [--since <duration>] [--last <n>]
FlagDescription
--filterFilter expression (repeatable). Keys: status=<code>, path=<path>, function=<name>, type=job, req=<id>
--sinceShow requests from this far back. Examples: 1h, 30m, 24h
--lastNumber of recent requests to show before streaming
--no-streamPrint batch and exit without streaming
# Stream all live requests
$ flux tail

  POST /signup        201  81ms   req:4f9a3b2c
  GET  /users         200  12ms   req:a3c91ef0
  POST /checkout      500  44ms   req:550e8400
     └─ Error: Stripe API timeout

# Only failures from the last hour
$ flux tail --filter status=500 --since 1h

# Only async job runs
$ flux tail --filter type=job

# Only requests to a specific path
$ flux tail --filter path=/stripe_webhook

# Combine filters
$ flux tail --filter path=/checkout --filter status=500 --since 1h

flux logs

Query historical function logs (stdout / stderr output from function code).

flux logs [--function <name>] [--tail] [--limit <n>] [--since <duration>]
FlagDescription
--functionFilter to a specific function name
--tailKeep streaming new log entries
--limitMax number of entries to return
--sinceHow far back to query. Examples: 1h, 30m
$ flux logs --function create_user --limit 50 --since 1h

flux why

Read the execution record for a request and return the root cause of failure, the exact file and line, any database mutations made (including rollbacks), and a suggested fix. The fastest way to go from request ID to root cause.

flux why <request-id>
ArgumentDescription
<request-id>The req: ID from flux tail output or the x-request-id response header
$ flux why 550e8400

  ROOT CAUSE   Stripe API timeout after 10s
  LOCATION     payments/create.ts:42
  DATA CHANGES users.id=42  plan: free → null  (rolled back)
  SUGGESTION   → Add 5s timeout + idempotency key retry

flux trace

Show the full span tree for a request — every function call, database query, outbound API call, and async hand-off with durations and outcomes.

flux trace <request-id>
$ flux trace 550e8400

  gateway                   2ms
  └─ create_order           8ms
     ├─ db.insert(orders)   4ms
     ├─ stripe.charge     180ms  ✗ timeout
     └─ send_slack          —    skipped (upstream error)

flux trace debug

Step through a request execution span-by-span in an interactive terminal UI. Shows the input and output at each step.

flux trace debug <request-id>
$ flux trace debug 550e8400

  Step 2/4  create_order
  ──────────────────────────────────────────────
  Input:   { userId: 42, items: [...] }
  Output:  { orderId: "o_881" }
  Time:    8ms

  ↓ next  ↑ prev  e expand input/output  q quit

flux trace diff

Compare two execution records span-by-span. Highlights spans that changed in duration, result, or presence. Useful for comparing a passing and failing version of the same request.

flux trace diff <request-id-a> <request-id-b>
flux trace diff <commit-a>:<request-id> <commit-b>:<request-id>
$ flux trace diff 4f9a3b2c 550e8400

  SPAN              REQUEST A       REQUEST B
  ──────────────────────────────────────────────────────
  gateway           2ms             2ms               —
  create_order      81ms            44ms              faster
  ├─ db.insert      4ms             4ms               —
  ├─ stripe.charge  68ms ✔          → timeout (10s)   ✗ changed
  └─ send_slack     7ms ✔           — skipped         ✗ missing

flux state history

Show the full mutation history for a database row — every INSERT, UPDATE, and DELETE, each linked to the request that caused it.

flux state history <table> --id <row-id> [--since <duration>] [--request <id>] [--format <fmt>]
flux state history --request <id>
FlagDescription
--idRow identifier (primary key value)
--sinceHow far back to search
--betweenISO timestamp range: 2026-03-10T14:00 2026-03-10T15:00
--request, --filter req=<id>Filter to mutations caused by a specific request
--filter job=<id>Filter to mutations caused by a specific job run
--formattable (default) | json | csv
$ flux state history users --id 42

  users id=42  (4 mutations)

  2026-03-10 12:00  INSERT  email=a@b.com, plan=free        req:1a2b3c4d
  2026-03-10 14:21  UPDATE  name: null → Alice Smith        req:a3c91ef0
  2026-03-10 14:22  UPDATE  plan: free → pro                req:4f9a3b2c
  2026-03-10 14:22  UPDATE  plan: pro → null  (rolled back) req:550e8400

# All tables mutated by one request
$ flux state history --request 550e8400

flux state blame

Show the last successful writer for each column of a database row — analogous to git blame but for database state.

flux state blame <table> --id <row-id>
$ flux state blame users --id 42

  email   a@b.com   req:1a2b3c4d  2026-03-10 12:00
  name    Alice     req:a3c91ef0  2026-03-10 14:21
  plan    free      req:550e8400  2026-03-10 14:22  ✗ rolled back

A ✗ rolled back marker means the most recent write attempt was reverted — the displayed value is from the previous successful write.

flux incident replay

Re-run a window of production traffic against your current code. Outbound HTTP calls are stubbed with recorded responses so external services are not contacted. Database writes are enabled by default.

flux incident replay <start>..<end> [--request <id>] [--env <env>] [--no-db-writes]
FlagDescription
--requestReplay a single request instead of a time window
--envTarget environment for replay (production | staging)
--no-db-writesDry-run: record mutations in the log but don't commit to DB
--fail-ifCustom failure condition, e.g. "status != 200"
# Replay an incident window
$ flux incident replay 14:00..14:30

  Replaying 47 requests from 14:00–14:30…
  Side-effects: stubbed · DB writes: on

  ✔  req:550e8400  POST /signup  200  88ms  ← was 500
  ✔  req:7a8b9c0d  POST /signup  200  91ms  ← was 500

  47 replayed · 47 passing · 0 still failing  ✔ incident resolved

# Replay a single request
$ flux incident replay --request 550e8400

flux bug bisect

Binary-search your git commit history to find the first commit where a given request started failing. Like git bisect, but it re-executes the request at each commit rather than asking you to test manually.

flux bug bisect --request <id> [--since <date>] [--until <date>] [--fail-if <expr>]
FlagDescription
--requestRequest ID whose failure to bisect
--sinceEarliest commit date to search from
--untilLatest commit date (defaults to now)
--fail-ifCustom expression: "span.stripe.charge.duration > 5000"
$ flux bug bisect --request 550e8400

  Bisecting 42 commits (2026-03-01..2026-03-10)…

  Testing abc123…  ✔ passes
  Testing fde789…  ✔ passes
  Testing def456…  ✗ fails

  FIRST BAD COMMIT
  def456  "feat: add retry logic to stripe.charge"
  2026-03-08  alice@example.com

flux explain

Preview the SQL query plan that a ctx.db call will produce, without executing it. Identifies missing indexes and estimates row counts.

flux explain <function-name> [--payload <json>]
$ flux explain list_users --payload '{"limit":50}'

  Query #1   SELECT * FROM users WHERE tenant_id = $1 LIMIT 50
  Cost:      Seq Scan on users  (cost=0.00..1240.00)
  Warning:   Missing index on users.tenant_id
  Suggestion → CREATE INDEX ON users(tenant_id);

flux api-key

Create and revoke API keys for your project. API keys are used as Authorization: Bearer <key> headers on requests to the gateway. See API Gateway for details.

flux api-key create --name <name> [--scopes <scopes>]
flux api-key list
flux api-key revoke <id>
flux api-key rotate <id>
FlagDescription
--nameHuman-readable label for the key (required for create)
--scopesComma-separated permission scopes, e.g. function:deploy,logs:read
$ flux api-key create --name "production-server"
  ✔ Created  flx_live_abc123…  (production-server)

$ flux api-key list
  production-server   flx_live_abc…  created 2026-03-10
  ci-runner           flx_live_def…  created 2026-03-08

$ flux api-key revoke <id>
  ✔ Revoked

flux db push

Apply SQL migrations from the schemas/ directory to the connected Flux database. Migrations are tracked and applied idempotently.

flux db push [--context <name>] [--dir <dir>]
FlagDescription
--contextNamed context to connect to (default: active context)
--dirMigrations directory (default: schemas/)
$ flux db push

  Applying schemas/users.sql…    ✔
  Applying schemas/orders.sql…   ✔

  ✔ 2 migrations applied

flux secrets

Manage encrypted project secrets. Secrets are available in functions via ctx.env.KEY.

flux secrets set <KEY> <value>
flux secrets list
flux secrets delete <KEY>
$ flux secrets set STRIPE_SECRET_KEY sk_live_…
  ✔ Set STRIPE_SECRET_KEY

$ flux secrets list
  STRIPE_SECRET_KEY   sk_live_…***  set 2026-03-10
  SENDGRID_API_KEY    SG.***        set 2026-03-08

flux project

Create, list, update, and delete Flux projects.

flux project create --name <name>
flux project list
flux project update [--cors-origin <url>] [--name <name>]
flux project delete --id <id>
Subcommand / FlagDescription
create --nameCreate a new project with the given name
listList all projects in your account
update --cors-originAdd a CORS allowed origin (repeatable)
update --nameRename the current project
delete --idPermanently delete a project and all its data
$ flux project list

  proj_abc123   my-app       production  3 functions
  proj_def456   my-app-dev   staging     3 functions

$ flux project update --cors-origin https://your-app.com
  ✔ Added CORS origin: https://your-app.com

flux queue

Inspect and manage the async job queue. See Queue & Async Jobs for full docs.

flux queue dead-letter list
flux queue dead-letter replay <request-id>
$ flux queue dead-letter list

  d5e6f7a8  send_welcome_email  failed 3×  last: user not found
  e6f7a8b9  send_invoice        failed 3×  last: Stripe 429

← Observability