URL: /docs

---
title: Rill
description: Self-hosted 1:1 WebRTC SFU. Two people per call.
icon: sparkles
---

Self-hosted **1:1 video** for your product. Two browsers join a call; Rill copies audio, video, and opaque labeled data between them. Your app owns login, chat schema, and hang-up.

Use it when the call is **inside your product** (support, consult, interview) and you want to run the SFU yourself. Not a meeting app: two people, then `call_full`.

```sh
docker compose up
```

Open [http://127.0.0.1:3000](http://127.0.0.1:3000). Create a call, share the link, enable microphone and camera in two browsers. Chrome and desktop Safari. The SFU on port **7880** is API and signaling, not a homepage (`/` is 404).

## What you get

- **Packet copy.** Live media is RTP forwarded (SSRC/PT cache). No transcode on the hot path.
- **Two people.** Opaque `sub` + JWT `publish: { microphone, camera, screen, data }`. No host/guest roles.
- **Labeled data.** `call.send(label, data)` / `on("data")`. Max **128 KiB** per message; the app chunks larger payloads. Rill does not parse chat or rrweb.
- **Headless SFU.** `/health`, `/ready`, `/v1/*`, `/v1/signal`. No dashboard, no `/admin`.
- **Optional recording.** `rill-record` sidecar writes per-participant MP4 + JSONL. If it is down, the call continues.

```
Browser A  ←RTP + data→  Rill SFU  ←RTP + data→  Browser B
                              ⋮ lossy fork
                         rill-record → S3
```

In-memory calls: a restart forgets every call. Create again and mint new tokens.

[Run](/run) · [Your app](/your-app) · [Recording](/recording) · [HTTP](/http/create-call)
