Appearance
Capacity and limits
Quikcast refuses to start with limits that its memory budget cannot honour, so a server that boots is a server that has reserved what it promised. This page explains how the limits relate and how to size them. The individual settings are listed in the [limits] reference.
The short version
For most stations, change only max_listeners and listeners_per_mount to match your bandwidth, and leave the rest alone.
toml
[limits]
max_listeners = 2000
listeners_per_mount = 2000That is enough for roughly 200 MB of reserved memory and keeps startup checks happy.
What the limits protect
| Limit | Protects against |
|---|---|
max_connections, max_handshakes | Too many sockets, and slow clients that connect but never finish asking. |
max_listeners, listeners_per_mount | Too much outbound bandwidth and memory for audio listeners. |
retained_audio_budget | The total memory promised to audio buffers and listeners. |
ring_bytes, ring_entries, join_bytes | How much recent audio each stream remembers. |
*_timeout_ms | Stalled clients, encoders and shutdowns. |
None of them cap how long a healthy stream may run.
How the memory budget is checked
At startup Quikcast adds up what it must be able to hold, in the worst case, and compares it with retained_audio_budget (1 GiB by default).
text
required = 2 × mounts × generation + max_listeners × listener2 × mounts × generation: each mount can hold two source generations at once (the current one and one that listeners are still draining). A generation reserves its ring (ring_bytesplus bookkeeping forring_entries) and fixed parser buffers. With default settings it is about 5.4 MB.max_listeners × listener: every possible listener reserves pending-write space, a metadata block and a share of header storage. That is about 105 KB each.
Rules of thumb
| You have | Reserved memory is about |
|---|---|
| 1 mount, 1,000 listeners | 115 MB |
| 4 mounts, 2,000 listeners | 255 MB |
| 10 mounts, 10,000 listeners | 1.16 GB (needs a bigger budget) |
If the sum is too big you will see:
text
limits.retained_audio_budget: retained audio budget cannot cover admission reservations:
2 mount(s) and max_listeners = 10000 need about 1032 MiB but retained_audio_budget is 1024 MiB;
lower limits.max_listeners or raise limits.retained_audio_budgetFix it by lowering max_listeners, or by raising retained_audio_budget. Both are restart settings.
The default budget is tight for many mounts
With defaults (max_listeners = 10000, 1 GiB budget), one mount fits but several do not. If you add mounts and get the error above, lower max_listeners to what your bandwidth can actually serve.
The reservation counts what Quikcast promises, not process memory: the operating system, your proxy and the HLS store (below) are on top.
Other budgets
These are separate and do not borrow from retained_audio_budget:
| Budget | Setting | Notes |
|---|---|---|
| Relay workers | relay_allocation_budget | At least 2 MiB per relay (up to 16 relays), counted even when a relay is disabled. |
| HLS | [hls] allocation_budget, rendition_budget | In-memory segments for all HLS streams. The per-rendition minimum is 8 × (max_segment_bytes + 128) + 4 × 262,144. |
Choosing a listener limit
Listeners cost outbound bandwidth:
text
bandwidth ≈ listeners × bitrateFor example 1,000 listeners at 128 kbit/s is about 128 Mbit/s. Check your host's real network capacity (and your provider's fair-use limits) before setting max_listeners. It is far better to refuse listeners cleanly than to let everyone's audio stutter.
Also remember file descriptors: allow more than max_connections open files (LimitNOFILE in systemd or ulimit -n).
Fixed limits
Some limits are built in and have no setting:
| What | Limit |
|---|---|
| Request headers | 16 KiB and 64 fields |
| Configuration file | 128 KiB |
| Mounts | 64 configured, plus dynamic mounts within the memory budget |
| Relays | 16, each with up to 8 upstreams |
| IP rule lists | 10,000 distinct entries each |
| User-Agent rule lists | 256 rules of 1–256 bytes |
| Country lists | 249 codes |
| Signed-link HLS entries | 64 |
| Console sessions | 128, one hour each |
| Management request bodies | none allowed |
| Country database file | 128 MiB, 2 million records |