Configuration reference

July 19, 2026 ยท View on GitHub

This document catalogs the configuration directives that the IRL fork of srt-live-server adds on top of the upstream SLS project, plus the base directives whose behavior changed in this fork. The canonical example with inline comments is src/sls.conf.

For directives inherited unchanged from upstream SLS see the upstream wiki at https://github.com/rstular/srt-live-server/wiki/Directives. Feature deep dives live in BITRATE_LIMITING.md and PLAYER_KEY_IMPLEMENTATION.md. This file links to those rather than restating them.

Conventions

  • Directives live in one of three scopes: srt { } (global), srt { server { } } (per server), or srt { server { app { } } } (per app).
  • Boolean values accept true / false or 1 / 0. Strings may be optionally wrapped in single or double quotes; the quotes are stripped at parse time.
  • Time values are in the unit the directive name implies (_ms suffix for milliseconds, _timeout is usually seconds unless otherwise noted, see the per directive entry).
  • -1 is the conventional "unlimited" sentinel for counted limits.

Global scope (srt { ... })

Server runtime

DirectiveTypeDefaultNotes
worker_threadsint1Worker threads handling SRT connections. Bump for many concurrent streams (more than 5).
worker_connectionsint300Max concurrent SRT connections per worker.
pidfilepath/tmp/sls/sls_server.pidPID file path; created on start, removed on stop.
userstring(unset)Drop privileges to this user after binding. Only applies when started as root, otherwise ignored with a warning.
groupstringuser's primary groupDrop privileges to this group. Pairs with user.

HTTP stats and control API

DirectiveTypeDefaultNotes
http_portint8181Port for the HTTP stats / control API. Exposes /stats, /healthz, and the disconnect endpoints.
cors_headerstring*Value sent in Access-Control-Allow-Origin. Restrict to a specific domain for production.
api_keysstring list(unset)Comma separated API keys. Clients pass one in Authorization: <key> to use the control endpoints without the ?publisher= query. Compared in constant time.
stat_post_urlurl(unset)If set, SLS POSTs the stats JSON to this URL on the interval below.
stat_post_intervalint (seconds)1Interval between auto posted stats payloads.

Logging

The fork ships a redesigned logging system designed to keep log volume sane on IRL setups where players and OBS reconnect frequently. The per category levels and the rate limiter together let an operator silence noisy subsystems without losing real errors.

DirectiveTypeDefaultNotes
log_filepathlogs/srt_server.logLog file path.
log_levelenuminfoGlobal log level (trace, debug, info, warn, error).
log_formatenumtexttext or json. JSON is useful for log aggregators.
log_rate_limit_enabledbool1Enable per event rate limiting.
log_rate_limit_windowint (seconds)60Time window for the rate limit threshold.
log_rate_limit_thresholdint5Log every Nth occurrence of a repeated event.
log_summary_enabledbool1Emit periodic operational summary (active publishers / players, connect counts, errors).
log_summary_intervalint (seconds)60Summary cadence.
log_session_idsbool1Tag log lines with a short connection id like [connection:a3f2] for grep based correlation.
log_level_connectionenuminherits log_levelPublisher / player connect and disconnect events.
log_level_listenerenuminherits log_levelListener lifecycle, accepts.
log_level_streamenuminherits log_levelStream lifecycle (publishers).
log_level_dataenuminherits log_levelData path / packet trace. Very verbose.
log_level_relayenuminherits log_levelPuller and pusher operations.
log_level_httpenuminherits log_levelHTTP API and webhooks.
log_level_authenuminherits log_levelAuthentication, player keys.
log_level_systemenuminherits log_levelStartup, shutdown, config reload.

Per server scope (srt { server { ... } } })

Listener ports

listen_player, listen_publisher, and listen_publisher_srtla each accept either a single port, a comma separated list, an inclusive range (a-b), or any mix. One SRT listener is created per port. SRTLA patches are enabled automatically on listen_publisher_srtla and disabled on listen_publisher.

DirectiveTypeDefaultNotes
listen_playerport list(required)Player facing port(s).
listen_publisherport list(required for direct SRT publishers)Direct SRT publisher port(s) (OBS, FFmpeg without SRTLA).
listen_publisher_srtlaport list(required for SRTLA publishers)SRTLA / bonded cellular publisher port(s) (used together with srtla_rec).

Latency and connection tuning

DirectiveTypeDefaultNotes
latency_minint (ms)(per role default)Minimum SRT latency for both publisher and player listeners. Floor enforced and warned when configured below the SRT default.
latency_maxint (ms)(per role default)Maximum latency for accepted connections.
backlogint100Listen backlog for simultaneous connection attempts.
idle_streams_timeoutint (seconds)30Close streams idle for this long. -1 disables.
player_idle_streams_timeoutint (seconds)0 (inherit idle_streams_timeout)Idle timeout applied to player roles only. Set it higher than idle_streams_timeout so viewers ride out a publisher outage without being disconnected: when the publisher returns, surviving players re anchor at the live write head (with fresh PAT and PMT) instead of forcing every viewer client to reconnect. Publishers keep the shared idle_streams_timeout, so a dead publisher is still reaped promptly. 0 inherits idle_streams_timeout. -1 disables the player idle reap entirely (viewers then only leave when their own socket dies or they disconnect).
peer_idle_timeoutint (ms)0 (libsrt default)SRTO_PEERIDLETIMEO applied to every accepted socket. Bounds how long a peer may go silent (no data, no keepalive) before the link is declared broken. The belabox SRT fork raises the libsrt default so bonded cellular gaps do not kill healthy publishers; set a tighter value (for example 4000) only when publishers reach SLS over a stable hop (a local srtla_rec terminating the bond). Avoid on direct bonded SRTLA listeners.
publisher_first_data_graceint (ms)0 (built in 3000)First data probation for an accepted publisher. A connection that completes the SRT handshake, registers as a publisher, then never delivers a media packet (almost always a player or preview pointed at the ingest port, a valid stream key still authenticates) is reaped by (negotiated latency + this grace) instead of squatting the key for the full idle_streams_timeout. The latency term is required because SRT's TSBPD holds the first packet for the whole receive latency window, so a legitimate high latency encoder (Moblin around 3000, Belabox 2000 to 3000) surfaces its first byte only after that window. The grace covers RTT, encoder warmup, and TSBPD jitter on top of it. 0 applies the built in 3000. -1 disables probation. Works with the publisher takeover guard, which refuses a new connection for a key whose incumbent is actively delivering rather than evicting the live broadcaster.

Listener wide SRT encryption

These run during the SRT crypto handshake on every accepted connection (publishers and players). This is orthogonal to player_key_auth_url, which runs after the handshake on streamid lookup.

DirectiveTypeDefaultNotes
srt_passphrasestring (10 to 79 bytes)(unset, no encryption)libsrt enforces this passphrase during the crypto handshake. Validated at listener start.
srt_pbkeylenint (0, 16, 24, 32)0 (libsrt default, AES-128)Key length in bytes. Validated at listener start.

Streamid routing

DirectiveTypeDefaultNotes
domain_playerstring(required)Domain segment used in the player streamid (<domain_player>/<app>/<stream>).
domain_publisherstring(required)Domain segment used in the publisher streamid.
default_sidstring(unset)Default streamid to use when the encoder omits one.

The pair domain_publisher / app_publisher must not equal domain_player / app_player in the same server block.

Webhooks

DirectiveTypeDefaultNotes
on_event_urlurl(unset)HTTP endpoint called on publisher and player connect / close. Callback shape: ?method=on_connect|on_close&role_name=&srt_url=<stream_url>. The publish auth response may include a pushTargets array that drives per publisher push destinations (see below).
auth_reject_cache_ttlint (seconds)30Negative auth cache TTL. A publisher streamid whose on_event_url lookup returns non 200 is remembered for this many seconds; subsequent attempts with the same canonical streamid are rejected at the SRT handshake (no accept, no webhook). 0 falls back to the 30 second default. Mitigates streamid rotating DoS.

Player key authentication

When player_key_auth_url is set, player connections targeting the configured domain_player / app_player are validated against the API endpoint. The response maps the player key to the real stream id (and optionally to a per stream player limit). See PLAYER_KEY_IMPLEMENTATION.md for the full protocol.

DirectiveTypeDefaultNotes
player_key_auth_urlurl(unset, disabled)API endpoint for validating player keys. GET <url>?player_key=<key>. Expected JSON response: {"stream_id": "publish/live/actualstream", "max_players_per_stream": 10} (the limit is optional).
player_key_auth_timeoutint (ms)2000HTTP timeout for the validation call.
player_key_cache_durationint (ms)60000Duration to cache successful validations (and briefly cache rejections to prevent API abuse).
player_key_rate_limit_requestsint-1 (unlimited)Max validation requests per peer IP per window.
player_key_rate_limit_windowint (ms)60000Rate limit window.
player_key_min_lengthint8Minimum accepted player key length.
player_key_max_lengthint64Maximum accepted player key length. Valid characters are printable ASCII (hex 0x20 to 0x7E).

Per app scope (srt { server { app { ... } } })

Routing

DirectiveTypeDefaultNotes
app_playerstring(required)App segment used in the player streamid.
app_publisherstring(required)App segment used in the publisher streamid.

IP access control (allow / deny)

allow and deny directives gate connections per role.

DirectiveTypeNotes
allow publish <ip|all>ruleWhitelist for publishers.
deny publish <ip>ruleBlacklist for publishers.
allow play <ip|all>ruleWhitelist for players.
deny play <ip>ruleBlacklist for players.

Known IPv6 limitation. The ACL storage type (sls_ip_access_t) holds only an IPv4 address. As a result, specific IPv6 allow or deny rules are not enforced today. IPv6 peers match only the wildcard entry (all) and otherwise hit the documented default (currently "accept by default", matching the IPv4 no match path); a one shot warning per call is logged so operators know that explicit IPv6 ACL entries are being ignored. Tracking item: add IPv6 ACL matching to conf.cpp and SLSListenerHandler.cpp. Until then, an explicit deny play <ipv6> rule will not take effect.

Per stream limits

DirectiveTypeDefaultNotes
max_players_per_streamint-1 (unlimited)Cap on simultaneous players per stream. May be overridden per session by max_players_per_stream in a player key validation response.

Bitrate limiting

See BITRATE_LIMITING.md for the algorithm.

DirectiveTypeDefaultNotes
max_input_bitrate_kbpsint(unset, disabled)Sustained publisher bitrate ceiling in kbps.
max_input_bitrate_violation_timeoutint (seconds)30Disconnect after this many seconds of sustained violation.
max_input_bitrate_spike_toleranceint (percent)120Spike multiplier in percent (120 means trigger at 1.2x of max_input_bitrate_kbps).

Push destinations

Push destinations let the publish auth webhook drive per publisher SRT pushers. When push_destination_max > 0 and the publish auth response includes a JSON body { "pushTargets": [{ "url": "srt://..." }, ...] }, SLS spawns one CSLSPusher caller per accepted entry. Each URL is validated again at use time. Aggregate egress per stream is bounded by push_destination_max * max_input_bitrate_kbps.

DirectiveTypeDefaultNotes
push_destination_maxint0 (feature disabled)Maximum number of push targets accepted per publisher. 0 disables the feature regardless of webhook output.
push_destination_allow_internalboolfalseWhen false, RFC1918, loopback, and link local destinations are rejected.
push_destination_allow_selfboolfalseWhen false, the server's own bind addresses are rejected as destinations.
push_destination_allow_schemesstring listsrtAllowed URL schemes for destinations.
push_destination_max_url_lenint (bytes)1024Maximum accepted destination URL length.

Relay (relay { } block)

The per app relay { } block configures static pull or push relays. The static relay code path remains in the codebase but is largely superseded for push by the dynamic pushTargets mechanism described above. The pull direction is still in active use.

Block fieldTypeNotes
typeenumpull or push.
modeenumpull: loop or hash. push: all or hash.
reconnect_intervalint (seconds)Reconnect delay on failure.
idle_streams_timeoutint (seconds)Idle teardown timeout. -1 disables.
upstreamsurl listSpace separated list of upstream SRT URLs. Templates like {stream_name} are substituted.

TODO: confirm whether the static relay { type push; } direction is still preferred over dynamic pushTargets for any operator workflow; cross reference the resolution from plan 007 once it lands.

See also