Concepts

Workers

A worker is a process you run that holds an outbound connection to Mobius and executes work. The agent loop and the runtime live in Mobius Cloud; the worker runs your code, your network calls, and (optionally) your local LLM generations.

The connection is outbound-only. Mobius never connects to you.

When do I need one?

You need a worker when a step has to:

  • call something behind your firewall,
  • use a secret that shouldn't live in Mobius,
  • run a custom model (Ollama, an internal serving stack),
  • scale separately from the Mobius backend,
  • run inside a managed environment (a Sprite) pinned to a worker instance.

If a step only calls a provider Mobius already integrates with (Slack, GitHub, Linear, email, ...), use a server action instead. No worker required.

The stock worker

The CLI ships a "stock" worker that registers a small set of built-in actions (print, fail, json, time, random). It's the fastest way to see a worker on the wire:

mobius worker --queues default

That's enough to run the quickstart's sample automation. For real work you'll register your own actions and run a worker with a custom handler (see the SDK examples in the mobius repo).

Concurrency: one process or many?

The CLI gives you two knobs. Pick one.

--concurrency N runs a single worker process that holds up to N jobs in flight. This is the default and what you want for raw throughput. The workers page in the app shows a single saturation bar.

mobius worker --queues default --concurrency 5

--workers N spawns N independent worker instances inside one CLI process. Use this when each child needs to drain or be observed independently (separate presence rows). It's the advanced mode.

mobius worker --queues default --workers 5

If you can't decide, use --concurrency. It's simpler and saturates the same way under most workloads.

Queues and selectivity

--queues selects which queues this worker claims from. By default, workers claim from default. You'll want to split queues when:

  • Some actions are slow and shouldn't starve fast ones.
  • A subset of actions needs special hardware (a GPU worker, an on-premise box).
  • You want a separate worker pool per environment (prod vs. staging).

You can also restrict workers to specific actions or models. Useful when one worker process is your image.resize pool and another is your summarize-document pool. The SDK exposes those filters; the stock worker accepts them as flags.

Instance identity

Every worker advertises a stable worker_instance_id. The CLI auto-detects one from the runtime platform (Cloud Run revision, Kubernetes pod, Fly machine, Railway replica, Render instance) and falls back to a per-boot UUID. Override only when you genuinely need a fixed identifier across restarts:

mobius worker --queues default --instance-id "deploy-worker-prod-01"

The instance ID is used for display and for queries; the per-boot session token (handled by the SDK) is what fences zombie processes.

Managed environments

Mobius can launch a worker for you inside a managed environment (a Sprite, typically). That worker's session reports an environment_id and gets jobs that were pinned to that environment. This is how you give an agent a real filesystem, a git clone, and an isolated network without running the infrastructure yourself.

You don't need to do anything special on the worker side to use this: the automation declares an environment for the agent or run, Mobius spins up an environment with a worker inside, and the runtime routes jobs to that worker by environment_id.

Operating workers

# Who's online right now?
mobius worker-sessions list
 
# What's pending and which worker has each job?
mobius automations list-runs --status suspended

If a worker dies mid-job, Mobius reclaims the job after the heartbeat-miss window and another compatible worker picks it up. The lease mechanism stops a zombie from completing a job a fresh worker already took.

SDKs and the wire protocol

The wire protocol is a WebSocket plus typed JSON frames. The SDKs (Go, TypeScript, Python) speak it for you, including reconnects, backpressure, lease management, and streaming. You should use an SDK in production. The raw protocol is documented in the interactive API reference for cases where you need to implement a worker in a language without an SDK.

  • Jobs for the persistence side of the work workers claim.
  • Actions for the catalog: how an action_name gets registered.
  • API keys for how the worker authenticates.