# Deploy *background workers.*

Long-running processes that just keep running.

Push your worker. We keep it alive.

## Perfect for.

- **Queue consumers.** Pull jobs off SQS, Redis, or RabbitMQ and process them as they arrive.
- **Pollers and sync loops.** Watch an external API, sync data between systems, or reconcile state on a tight loop.
- **Notification dispatchers.** Subscribe to events and fan out emails, push notifications, or webhooks downstream.
- **Realtime processors.** Consume Kafka or Kinesis streams, process events, and write results to your database.

## How it works.

1. **Write your worker.** A normal Node.js, Python, or Go process. Loop forever, await your queue, do the work.
2. **Push to Tokay.** `git push tokay`. We detect it as a background worker.
3. **It just runs.** No URL, no schedule. Your process stays alive in the background, with logs and a way to stop and start it.
4. **It stays up.** If your process crashes, we restart it. If you push a new version, we swap it in cleanly.

## When to pick a background worker.

The four service types each fit a different shape of work. Here's the quick test.

- **No URL, no schedule, just keeps running.** That's a background worker. Queue consumers, pollers, daemons.
- **Has a public URL people visit in a browser.** Use a web service.
- **Runs on a clock.** Use a scheduled job. The runtime starts your process on the schedule and exits when it's done.
- **Receives HTTP requests from another system.** Use a function. You get a webhook URL and request history.

## Just write your worker.

No framework to learn. Loop, do work, log. We keep the process alive.

**Node.js worker loop**

```javascript
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function run() {
  while (true) {
    console.log('checking queue');
    // Pull a job from SQS, Redis, RabbitMQ, etc.
    await sleep(30000);
  }
}

run().catch((err) => {
  console.error(err);
  process.exit(1);
});
```

**Python poller**

```python
import time

def sync_once():
    print('syncing upstream data')
    # Call an API, write to your database, repeat.


while True:
    sync_once()
    time.sleep(30)
```

**Go worker loop**

```go
package main

import (
    "log"
    "time"
)

func main() {
    for {
        log.Println("processing next event")
        // Read from Kafka, Kinesis, or a queue.
        time.Sleep(30 * time.Second)
    }
}
```

Push it. We detect it as a background worker, keep it running, and stream you the logs.

## What we handle for you.

- **Stays alive.** If your worker crashes, we restart it and email you when it goes down and when it recovers. No supervisor or systemd unit to write.
- **Live logs.** Stdout and stderr stream straight to the dashboard. Watch your worker in real time.
- **Clean deploys.** Push a new version and we swap the running process. The old worker gets a shutdown signal first, so graceful shutdown code has time to finish. No URL flips, no requests to drain.

- [Read the background workers doc for restarts, logs, and clean swaps](/docs/background-workers)
- [Build a full queue pipeline with the queue worker guide](deploy-queue-worker.md)
