Why self-host Temporal on a VPS
Temporal Cloud exists, but self-hosting remains relevant for several reasons. Cost: starting from 99 DH/month, a ServOrbit VPS is sufficient for moderate workloads, without per-action or active workflow fees. Data sovereignty: your workflows may process sensitive information that must not pass through a third-party service. Flexibility: you control the deployed version, retention policies and internal network integrations.
Temporal use cases
Temporal shines where cron jobs and simple queues show their limits. Here are the most common production use cases.
Architecture of self-hosted Temporal
Understanding the internal components helps you size your VPS and diagnose issues. Temporal consists of four main services that can run in the same process (temporalio/auto-setup) or be deployed separately at scale.
Temporal vs BullMQ vs Celery
Scroll the table
| Criterion | Temporal | BullMQ | Celery |
|---|---|---|---|
| State durability | Full history persisted in database — an interrupted workflow resumes exactly where it left off | State in Redis — a Redis loss means job loss | Optional results backend — no native execution history |
| Replay and determinism | Automatic replay from history — workflow code must be deterministic, Temporal handles the rest | No native replay — simple retry on failure | Per-task configurable retry, no multi-step workflow replay |
| Observation UI | Rich built-in UI: workflow list, step detail, search, manual actions | Bull Board as third-party plugin — functional but limited | Flower as separate tool — basic metrics, no step history |
| Supported languages | Go, TypeScript/JavaScript, Python, Java, .NET, PHP (official SDKs) | Node.js only | Primarily Python |
| Performance and latency | Higher overhead per task — optimized for durability over low latency | Very low latency — designed for high-frequency job queues | Variable latency depending on broker |
| Ideal use case | Long critical business workflows, saga pattern, multi-step processes over days | High-frequency task queues, image processing, real-time notifications | Python background tasks, data pipelines, existing Python ecosystem |
Technical prerequisites
Before starting, verify your environment is ready.
Deploy Temporal with Docker Compose
Create the working directory
Create a dedicated directory and navigate into it.
Download the official Docker Compose file
Temporal provides a reference Compose file in its GitHub repository.
Create the environment variables file
Create a
.envfile to customize PostgreSQL credentials. Never leave default passwords in production.Restrict .env file permissions
The
.envfile contains credentials — restrict access.Start the Temporal stack
Launch all services in the background. First startup takes a few minutes as
auto-setupinitializes the PostgreSQL schema.Verify all services are healthy
Wait 60-90 seconds, then check that containers are in
healthyorrunningstate.Verify connection to the Frontend Service
Confirm the server responds on the gRPC port.
Create a production namespace
Create a dedicated namespace for your application with a 30-day retention.
Access the Temporal UI
The web interface is available on port 8080.
Configure automatic startup
Enable automatic restart of the stack after a VPS reboot.
Configure a simple Go or TypeScript Worker
A Worker is the process that actually executes your business code. It connects to the Frontend Service, polls a task queue and executes the Workflows and Activities that Temporal dispatches to it.
Temporal UI — monitor and debug workflows
The Temporal UI (available on port 8080) is the central tool for observing your workflows in production.
PostgreSQL backups and persistence
Temporal's durability relies entirely on PostgreSQL. An unbackedup instance means total history loss on VPS failure.
Troubleshooting — common errors
Here are the four most common errors when installing Temporal on a VPS and their resolution.
Security: do not expose Frontend Service without authentication
Port 7233 (gRPC Frontend) and port 8080 (UI) must never be exposed directly to the Internet. Recommended measures: (1) block port 7233 in ufw and allow only your Workers' IPs; (2) place the UI behind an nginx reverse proxy with HTTP basic auth or SSO; (3) use a VPN or private network between your Temporal VPS and Worker VPS. In production, consider mTLS (available in Temporal v1.x) to encrypt and authenticate gRPC connections.