Skip to Content
cuelo.

06Ship

Deploy

Size your machine, run workers, and serve in production.

Measure first

cuelo machine check

This streams real speech through your actual turn-taking stack at rising concurrency, and reports how many calls stay real-time. Inside a project it uses the project's controllers. Elsewhere it uses the default stack. It then sizes worker processes from your CPU and memory and checks them running together.

cuelo machine check --single        # one process only
cuelo machine check --seconds 15    # longer per load level

What we measured on an M3 Pro (11 cores, 5 performance):

StackPer processWhole machineMemory / process
Default (turn-1-mini + MaAI barge-in + MaAI backchannels)5 calls8 (4 workers × 2)~1 GB
Light (backchannel-detector + vad backchannels)64 calls72 (2 workers × 36)~160 MB

The Python GIL caps one process at about 4 cores. Beyond that, add workers.

Speech and LLM run at the providers, so their cost doesn't depend on your machine. The turn-taking models run locally.

Serve

cuelo serve                     # serve.host, serve.port, serve.workers from config.cuelo
cuelo serve --port 8080
config.cuelo
serve:
  host: 0.0.0.0
  port: 4141
  workers: 4 # from cuelo machine check
  api_keys: ["${CUELO_KEY}"] # required on a public host
  cors: ["https://app.example.com"]

Each worker is a separate process with its own calls and models. A call stays on the worker its WebSocket landed on. Under cuelo-serve directly, use --workers N or CUELO_WORKERS.

Checklist

  • API keys set (the server refuses a public host without them). See Security.
  • TLS at a reverse proxy or load balancer. Browsers need wss:// for the microphone on non-localhost origins. Enable WebSocket upgrades and raise idle timeouts above your longest call.
  • Store on Postgres or MySQL for more than one machine. store.audio on a persistent volume.
  • Weights pre-downloaded in your image (cuelo models pull --all, or python -m cuelo.controllers.weights), so the first call doesn't wait. CUELO_MODELS sets the cache directory (default ~/.cache/cuelo/models).
  • Health: GET /health returns {"ok": true, "agent": ...} without a key.
  • Region: run close to your STT, LLM and TTS endpoints. Network round trips are a large share of latency.

Container

Dockerfile
FROM python:3.13-slim
RUN pip install uv
WORKDIR /app
COPY . .
RUN uv sync --frozen
ENV CUELO_MODELS=/app/.models CUELO_TORCH_THREADS=1
RUN uv run python -m cuelo.controllers.weights   # bake turn-taking weights into the image
EXPOSE 4141
CMD ["uv", "run", "cuelo-serve", "generated/pipeline.py", "--host", "0.0.0.0", "--port", "4141"]

Pass credentials at runtime (--env-file .env or your platform's secrets). Don't bake them into the image.

On this page