Temporal in WSL: Local Workflow Development and Replay Tests
Use Temporal's local development server in WSL to test workflow orchestration, task retries, and replay while keeping in-memory state and uptime limits clear.
Temporal’s local development server gives an application engineer a fast way to test workflow and activity code without first operating a shared Temporal cluster. In WSL, it is especially useful for exercising a Linux SDK, worker process, workflow registration, retry policy, and local UI from one development environment. It is not a small production cluster: the local server is designed for development, its default persistence is in-memory, and the WSL VM can stop independently of the Windows host.
The key distinction is between application logic and service guarantees. A local run can help demonstrate that a workflow schedules activities and that a worker can poll and execute them. It cannot prove that an event history survives VM loss, that a production namespace is configured correctly, or that production visibility, metrics, authentication, and capacity are ready. Treat histories and test results as disposable unless you explicitly configure another supported persistence mode and test recovery.
Install the CLI and start one isolated dev server
Install the Temporal CLI inside the WSL distribution using the current official instructions for the Linux architecture. Keep the CLI and SDK development environment on the Linux side. The CLI and SDK are distinct dependencies: recording both versions makes it easier to reproduce a test after an update. Do not install the Windows CLI and assume its filesystem paths, environment variables, or worker processes behave like Linux tools invoked by a WSL shell.
Start the development server in a foreground terminal:
temporal --version
temporal server start-dev
The CLI documentation describes this command as starting a local development server and web UI; the learning guide notes that it creates a default namespace and uses an in-memory database. The UI is available at the documented local endpoint, commonly http://localhost:8233. Check the actual startup output for the URL and port instead of relying on a stale bookmark. Keep the terminal open so server shutdown is an intentional Ctrl-C rather than an unexplained process termination.
Run the server and worker in separate WSL terminals. Make the target address explicit in the SDK configuration so a developer does not accidentally connect a test worker to Temporal Cloud or a shared self-hosted cluster. Use a disposable task queue name for the lab, and avoid reusing a production namespace or task queue simply because its name is familiar.
Exercise one workflow through a complete lifecycle
Choose a deterministic workflow with a small activity that records a test result. Give it an input identifying the test run, and set a finite timeout appropriate to the development exercise. Start the worker, trigger one workflow, observe the workflow and activity in the UI, and verify the returned result in the client. Then stop the worker while a second activity is pending and confirm the local behavior matches the application’s expectations when no worker is polling.
Workflow code needs deterministic replay semantics. A workflow implementation is reconstructed from its recorded event history, so nondeterministic operations belong in activities or in SDK-supported workflow APIs, not arbitrary wall-clock, random, filesystem, or network calls executed directly by workflow code. Local testing is a good place to run a workflow through its history and make a code change that tests replay compatibility. It is not equivalent to a production upgrade test with long-lived histories, multiple SDK versions, and real operational traffic.
Retries need a deliberate test. Trigger a controlled activity failure and inspect the configured retry policy, attempt count, and final workflow result. Do not create an activity that repeatedly mutates a real external service just to demonstrate a retry. Activities can execute again after failures or timeouts, so an external side effect should be idempotent or use an application-level idempotency key. Test that behavior against a disposable target.
Separate server, worker, client, and UI
The Temporal server accepts workflow requests and records event history. A worker is application code that polls a task queue and runs workflow or activity implementations. The client starts or signals workflows through the service. The UI is an operator and developer view into that server state. These are separate processes and separate failure points even if all run inside one WSL distribution.
If a workflow appears in the UI but its activity never completes, verify that the worker is running, uses the same namespace and task queue, registered the activity type, and can reach any dependency it calls. If the workflow client cannot connect, inspect the server’s actual bind address and port, then test from Linux before testing Windows localhost forwarding. WSL NAT and mirrored networking have distinct behavior; neither should be treated as a substitute for configuring the application endpoint correctly.
Use a Linux filesystem location for SDK source, build outputs, and temporary files. Microsoft notes the Linux filesystem is the preferred location for Linux command-line workloads. A cross-boundary path can introduce permission, file notification, and performance differences that have nothing to do with Temporal. If your real deployment consumes Windows-hosted files, add that as a separate explicit integration test.
Understand local persistence and observability limits
The default local development server’s in-memory database is convenient because it avoids provisioning another dependency. It also means the local server process lifetime is a hard boundary for the test’s state. Do not interpret a completed workflow visible in the UI as a backup, and do not use the local server to validate long-retention behavior. If a CLI version supports a persistent local database option, verify its syntax in that version’s command reference and test its recovery separately.
Temporal’s learning guide states that the local development server does not emit metrics. Therefore, local success is not evidence for production metrics, alerting, tracing, or capacity. For those checks, use a supported self-hosted cluster or Temporal Cloud environment with the intended telemetry configuration. Similarly, a local UI does not demonstrate production access control or reverse-proxy behavior.
Keep workflow inputs synthetic and avoid sending secrets or customer data into local histories. A history can contain workflow arguments, activity results, and error details. Do not put credentials in workflow arguments, source control, or a command line that may be retained in shell history. Clean up disposable histories by stopping the local server and using the documented local state lifecycle, not by deleting an uncertain directory while a process is active.
WSL process lifetime and troubleshooting
WSL can be shut down by Windows lifecycle events, and an enabled systemd unit cannot guarantee that a distro remains awake. For a development server, foreground operation is usually preferable because it makes logs and shutdown visible. If you later put the server in a systemd unit, use an explicit Linux user, working directory, and environment, and test how it behaves after wsl --shutdown, Windows restart, and user logoff.
If the server starts but the worker does not see tasks, compare endpoint, namespace, task queue, and worker logs. If workflows remain open, inspect the workflow’s waits, activity timeouts, retry policy, and worker poller state. If a run disappears after a restart, check whether the server was using only its default in-memory state before debugging application code. If Windows cannot open the UI, distinguish server listener problems from forwarding mode and browser routing.
Acceptance criteria
The WSL Temporal lab is ready when CLI and SDK versions are recorded, a local development server starts, a Linux worker connects to the intended namespace and task queue, a deterministic workflow completes an activity, controlled retry behavior is observed without external side effects, and the team can explain what state disappears at shutdown. Stop both worker and server cleanly.
This environment is a workflow-development and replay-learning tool. It is not a production availability test, event-history recovery plan, metrics validation environment, or substitute for a correctly operated Temporal cluster.
Related:
- Systemd in WSL: Service Lifetime, Idle Shutdown, and the Limits of a Workstation VM
- WSL Localhost Forwarding: How Windows Reaches Linux Services and Where It Breaks
Sources: