Deploy a worker.
A worker on HostingGuru is a long-running background process — no public URL, no health endpoint required. The right service type for queue consumers (BullMQ, Sidekiq, Celery, RQ), scheduled job runners, data pipelines, websocket fan-out servers, and anything else that needs to keep running but doesn't speak HTTP to the public internet.
Workers run on dedicated infrastructure. Available on Pro ($35/mo, 1 vCPU / 1 GB RAM per service, up to 10 services) and Custom plans. Not available on Starter or Hobby — those run on shared infrastructure where background workloads can't be guaranteed. See pricing.
From repo to a running worker
1. Pick "Worker"
From the dashboard, click New service → Worker. Pick the repo, branch, and root directory. We auto-detect Node, Python, Go, Ruby, Rust, Java, and PHP. The build phase is identical to the API service type — only the start phase and networking differ.
2. Set the start command
Common shapes: node dist/worker.js, python -m app.worker, celery -A app worker --loglevel=info, bundle exec sidekiq, ./bin/processor. The process runs as PID 1 of its container — when it exits, the container is considered stopped.
3. Add env vars + connect resources
Workers usually need a queue (Redis), a database (Postgres), and credentials for whatever they're processing. Paste connection strings from the Redis and Databases tabs as environment variables, plus any external API tokens. Both Postgres and Redis use SSL/TLS for the connection.
4. Deploy
The worker starts and runs with restartPolicy: always. We don't run an HTTP health check — we monitor the process. If it exits, we restart it. If it crashes 5 times in 5 minutes, we mark the service failed and stop restarting until you intervene.
Workers built around how queue consumers actually run
Auto-restart with backoff
Container restart policy is always. Crashes are restarted with exponential backoff up to 30s. After 5 crashes in 5 minutes the service is marked failed — so a poison-pill message doesn't burn your CPU in a tight loop.
Graceful shutdown
On deploy or restart we send SIGTERM and wait up to 30 seconds (configurable up to 5 min) for the process to drain in-flight jobs. After the grace period, SIGKILL. This gives Sidekiq, BullMQ, and Celery enough time to finish whatever they were processing.
Real-time logs
Every line on stdout/stderr is streamed to the dashboard within ~200ms. Log lines are tagged with workspaceId, deploymentId, and requestId if your code emits one. Filter by level, search by substring, follow live.
Private networking
Workers, APIs, Postgres databases, and Redis caches all live under your workspace. Connection strings from the Databases and Redis tabs work from any service — paste once, use anywhere.
Resource limits per worker
Set memory and CPU caps per service from the dashboard, so a leaky worker doesn't take down your API on the same machine. Hit the cap and the process is OOM-killed and restarted — visible in logs as a clear OOM event, not a mystery 137 exit code.
Service slots, not replicas
Each worker is a single container by design. To run several workers in parallel, deploy the same repository as multiple worker services from the dashboard — they each count toward your plan's service limit (10 on Pro). Each pulls from your queue concurrently; the queue (Redis, RabbitMQ, SQS) handles distribution.
What people typically run as a worker
Queue consumer
BullMQ, BeeQueue, Sidekiq, Celery, RQ, Laravel queue. The worker pulls jobs off a Redis or RabbitMQ queue, processes them, acks them. A managed Redis cache (from the Redis tab) plus a worker is the canonical setup.
Scheduled job runner
Long-running scheduler (node-cron, APScheduler, whenever, sidekiq-cron) that fires tasks on a schedule from inside the same process. If you only have a single occasional task, prefer on-demand scripts with a cron trigger — cheaper and no idle process.
Data pipeline
ETL processes that pull from sources (S3, Kafka, an API), transform, and write to your database. Check-pointing should live in your store, not in the worker memory — workers can be redeployed at any time.
Websocket fan-out
Pub/sub server that holds many open websocket connections and pushes events from a Redis channel. Run as a worker (no inbound public port needed if your API proxies the upgrade) or as an API service if it accepts public upgrades directly.
External integration listener
Long-poll or stream consumer for a third-party API (Slack RTM, Twitter streaming, Stripe webhook replay, IMAP IDLE). Reconnects and rate-limits live in your code; we only ensure the process stays running.
Common questions
Worker vs on-demand script — which one do I want?
Worker = process that keeps running and waits for work to arrive (queue consumer, schedule loop). On-demand script = container that runs once and exits (migration, backup, monthly billing reconciliation). If your task takes <15 minutes and runs on a schedule or trigger, use a script. If it runs continuously, use a worker.
How do I run the same worker multiple times in parallel?
Deploy the same repository as multiple worker services (e.g. queue-worker-1, queue-worker-2) — each counts toward your plan's service limit. They all pull from your queue concurrently; the queue (Redis, RabbitMQ, SQS) handles the work distribution.
Does the worker get a public URL?
No. By design — workers don't speak HTTP to the public internet. If you need an HTTP-accessible worker (e.g., a status endpoint), use the API service type instead.
How do I see what my worker is doing right now?
The dashboard shows live logs streamed in real time. For application-level metrics (jobs processed, queue depth), instrument them in code and emit structured log lines — the dashboard search makes them easy to filter.
What if my worker writes to disk?
The container's filesystem is ephemeral — anything you write is lost on restart or redeploy. For persistent state, use a managed Postgres database or Redis cache, or attach an external object store (S3, R2, B2).
Run your queue consumer where your API lives.
Same workspace, same logs, same dashboard. From $35/mo on Pro.
Key takeaways
A worker on HostingGuru is a long-running background service with no public HTTP endpoint — the right shape for queue consumers, schedulers, websocket fan-out servers, and chat bots.
- Workers restart automatically on a non-zero exit, with exponential back-off (1s, 2s, 4s … 60s).
- Each worker counts as one service against your plan limit (Hobby: 3, Pro: 10).
- Workers share env vars and the same git repo as your web service.
- Restart loops are capped and surfaced in the dashboard so crash storms do not consume resources silently.
How is a worker different from an on-demand script?
An on-demand script runs once and exits — ideal for migrations or backfills. A worker is meant to stay running indefinitely, consuming messages or watching schedules. Pick a worker when the natural answer to "when does this stop?" is "never."
Which queue libraries work on HostingGuru workers?
BullMQ, Bee-Queue, Celery, RQ, Sidekiq, Oban, and any custom Redis or Postgres-based queue. Connect to the managed Redis URL injected as REDIS_URL, or to managed Postgres via DATABASE_URL.