# A Laravel queue worker that actually stays alive on a R 100/month VPS

- Published by: Sitect (Pty) Ltd (https://sitect.co.za), written by Sitect Editorial Team
- Published: 2026-05-10
- Web page: https://sitect.co.za/insights/laravel-queue-worker-r100-vps

> Supervisor, sane retry config, OOM guards and a Pushover heartbeat. The exact set-up we put on every R 100/month VPS we deploy a Laravel job runner to.

Most "how to run Laravel queues in production" tutorials assume you're on a beefy box. Here's the minimal-resources version: a single Hetzner CX21 or similar SA-hosted VPS, ~2GB RAM, running web + queue together.

## Supervisor config

We use Supervisor (not systemd directly, because of the per-process restart guarantees). One worker group per critical queue: `default`, `ai`, `mail`. AI jobs sit on their own queue so a slow OpenAI call doesn't block a contact-form email.

```
[program:sitect-queue-ai]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/sitect/artisan queue:work --queue=ai --tries=3 --backoff=30 --max-time=3600 --memory=192
autostart=true
autorestart=true
user=www-data
numprocs=1
stopwaitsecs=60
```

`--max-time=3600` kicks the worker after an hour so memory leaks (yours or upstream's) don't accumulate. `--memory=192` is a hard ceiling.

## A heartbeat to Pushover

A scheduled task every 5 minutes that fires a small ping to a heartbeat endpoint. If two consecutive pings don't arrive, Pushover wakes us up. Free tier of healthchecks.io works fine too.

## Why this matters for AI workloads

AI jobs are unusual: they're long-running (10–30s), expensive (R0.02–R1 each) and they fail in interesting ways (rate limits, timeouts, JSON parse errors). Without a healthy worker, leads silently sit in `ai_qualifying` status forever. Get this right early.

---
Sitect (Pty) Ltd is an AI-first digital agency in Midrand, South Africa. Contact: 084 227 4264 (calls and WhatsApp), info@sitect.co.za.
