Embedded Temporal

Deep dive into the embedded Temporal server that powers standalone mode.

Component Topology

Loading diagram...
ComponentRoleDefault Port
FrontendgRPC entrypoint used by Compozy workers and the CLI7233
HistoryPersists workflow execution history and timers7234
MatchingDistributes tasks to the correct worker queues7235
WorkerRuns system workflows (namespace replication, visibility)7236
UI ServerOptional Temporal Web UI for debugging workflows8233

Port Allocation Strategy

  • frontend_port anchors the service block; History, Matching, and Worker consume the next three sequential ports.
  • Ports bind to standalone.bind_ip (defaults to 127.0.0.1). Override the IP when running inside containers that expose additional interfaces.
  • Adjust frontend_port to avoid conflicts, for example when other Temporal stacks are already listening on 7233.
Custom port block
temporal:
  mode: standalone
  standalone:
    frontend_port: 9733   # Services listen on 9733-9736
    bind_ip: 0.0.0.0      # Use cautiously; exposes gRPC outside loopback
    enable_ui: true
    ui_port: 9820

SQLite Persistence Modes

  • Ephemeral

    database_file: :memory: keeps Temporal state in RAM. This is fastest for unit tests because every Compozy restart resets state.

  • File-backed

    Point database_file to a writable path to persist workflow history between restarts. The server enables WAL + NORMAL sync for durability without sacrificing dev speed.

The builder automatically selects SQLite connection attributes:

engine/worker/embedded/sqlite.go
if dbFile == ":memory:" {
  return map[string]string{"mode": "memory", "cache": "shared"}
}
return map[string]string{"_journal_mode": "WAL", "_synchronous": "NORMAL"}

Lifecycle Management

1

Startup

maybeStartStandaloneTemporal evaluates temporal.mode. When set to standalone, it constructs Temporal configuration, assigns deterministic host settings, and launches the server using server.NewServer().

2

Health checks

Startup waits for the frontend service to accept gRPC connections. The wait is bounded by standalone.start_timeout (default 30s).

3

Registration

On first boot, the embedded server creates the configured namespace (standalone.namespace) and cluster name (standalone.cluster_name).

4

Shutdown

Compozy stops the worker pool and gracefully closes the Temporal server, flushing SQLite WAL files to disk when applicable.

Logging & Observability

  • standalone.log_level controls Temporal server logging (debug, info, warn, error). Logs flow through logger.FromContext(ctx).
  • The embedded UI exposes workflow executions, task queues, and history events via http://localhost:8233.
  • Prometheus metrics are emitted on the same process; scrape the Compozy metrics endpoint to monitor Temporal internals during development.

Security Considerations

  • Keep bind_ip on loopback unless you understand the risk profile.
  • Use non-default namespaces and task queues when multiple developers share a Temporal cluster.
  • Reset the SQLite file after workshops to avoid leaking PII in workflow payloads.