What is the use of the departure timeout under the...
# ask-ai
h
What is the use of the departure timeout under the room config in the livekit config file?
t
Thanks for reaching out, Jasmeet. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — you're asking about the purpose of the departure timeout under the room config. The departure timeout specifies how long LiveKit keeps a room open after the last non-agent participant leaves. During that time the room remains active so participants can reconnect (for example after a brief network drop). If no one rejoins before the timeout expires, the room is automatically closed and any remaining agent connections are disconnected. Default: 20 seconds. After the timeout expires, a cleanup may take an additional ~30–45 seconds to fully finalize room termination. Sources: Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name
h
what if i want to set participant departure timeout?
t
You're asking how to set the participant departure timeout — here's how to do that. You set the timeout using the room
empty_timeout
(in seconds) when creating a room via the Server SDK or Room API. Examples: • Node.js
Copy code
await roomService.createRoom({
  name: 'my-room',
  empty_timeout: 300, // 5 minutes
});
• Python
Copy code
await api_client.room.create_room(
  name="my-room",
  empty_timeout=300  # 5 minutes
)
Notes: • If you don't set it, the default is typically 300 seconds (5 minutes). • Use shorter values for ephemeral rooms and longer values for persistent collaboration rooms. Do you want an example for your language or where to set this in your existing config? Sources: server-sdk-ruby | livekit/livekit_composite | DeepWiki
h
This is the room departure time, but I want to set it for the participant.
t
You're asking about setting a departure timeout for an individual participant (not the room). LiveKit does not provide a built-in per-participant departure timeout. The only built-in timeout is the room-level
empty_timeout
. What you can do instead: • Track participant activity in your app (heartbeat, audio/video activity, messages, or silence detection). • When a participant exceeds your inactivity threshold, call the server API to remove them (use
remove_participant
from the Room API/Server SDK). Would you like a short code example (Node, Python, or Go) for tracking inactivity and calling
remove_participant
? Sources: Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name | server-sdk-ruby | livekit/livekit_composite | DeepWiki
h
This is my config for the livekit server for self-hosted. I am facing an issue of the disconnect ICE issue is something is missing in this port: 7880 log_level: debug rtc: node_ip: 0.0.0.0 _#node_ip: 127.0.0.1_ tcp_port: 7881 _# force_relay: false_ port_range_start: 50000 port_range_end: 60000 _# use_external_ip should be set to true for most cloud environments where_ # the host has a public IP address, but is not exposed to the process. # LiveKit will attempt to use STUN to discover the true IP, and advertise # that IP with its clients use_external_ip: true _# connection_timeout: 30s_ _# node_ip: livesk.obpl.tech_ _# participant_timeout: 5_ redis: # redis is recommended for production deploys address: 127.0.0.1:6379 keys: # key-value pairs test-key: “_a6df8b5265626a23ee4bf4d790923621925c9cb6c8398d0f2cd328788081f0b7_” # When enabled, LiveKit will expose prometheus metrics on :6789/metrics _#prometheus_port: 6789_ turn: enabled: true # domain must match tls certificate # domain: <turns.13.127.100.28:5349> domain: livesk.ol.tch # defaults to 3478. If not using a load balancer, must be set to 443. tls_port: 5349 udp_port: 3478 cert_file: /etc/letsencrypt/live/livesk.obpl.tech/fullchain.pem key_file: /etc/letsencrypt/live/livesk.obpl.tech/privkey.pem room: departure_timeout: 3 webhook: urls: - “https://live.ol.tch/api/webhook/live-kit” api_key: “test-key” _# api_secret: “a6df8b5265626a23ee4bf4d790923621925c9cb6c8398d0f2cd328788081f0b7"_
t
Thanks — I’m looking at your self-hosted config and the ICE disconnect issue. A few clear problems likely causing ICE failures and what to change: 1) You set
use_external_ip: true
but have no STUN servers • Add STUN servers so LiveKit can discover your public IP (otherwise it may advertise 0.0.0.0 and ICE will fail). 2) TURN domain / TLS must match exactly • Your TURN
domain
and the certificate host must be identical. Fix any typos (e.g.,
livesk.ol.tch
vs
livesk.obpl.tech
) and ensure DNS points to your server and certs are for that hostname. 3) Ensure TURN ports and media ports are open (UDP + TCP) • Open UDP 3478, UDP/TCP media range (50000–60000), and TURN TLS/UDP ports (5349 / 3478). If UDP is blocked, clients must be able to reach TURN over TCP/TLS. 4) Add ICE resilience settings • Enable
ice_tcp
and consider
ice_lite
or
force_relay
depending on infra. Example: set
ice_tcp: true
and include
force_relay: false
in
rtc
. 5) Room vs participant timeout •
departure_timeout
(or
empty_timeout
) is room-level. There is no built-in per-participant departure timeout. To evict inactive participants, track activity in your app and call
remove_participant
via the Server API. Suggested minimal fixes (rtc + turn + stun):
Copy code
rtc:
  node_ip: 0.0.0.0
  tcp_port: 7881
  port_range_start: 50000
  port_range_end: 60000
  use_external_ip: true
  stun_servers:
    - "stun:<http://stun.l.google.com:19302|stun.l.google.com:19302>"
  ice_tcp: true
  force_relay: false

turn:
  enabled: true
  domain: <your-exact-hostname>
  tls_port: 5349
  udp_port: 3478
  cert_file: /etc/letsencrypt/live/<your-exact-hostname>/fullchain.pem
  key_file: /etc/letsencrypt/live/<your-exact-hostname>/privkey.pem
Next diagnostics I need if the issue continues: • Results from the LiveKit Connection Tester (or paste its output) • Browser console WebRTC errors from a failed session • LiveKit server log lines during a failed connect attempt Tell me which of those you can share and whether you want a concrete patched config using your actual hostnames — I’ll produce it. Sources: Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name
h
I got this error while set this config livekit-server --config ./config open ./config: no such file or directory root@ip-172-31-41-64:/webroot/live-kit# livekit-server --config ./config.yaml could not parse config: yaml: unmarshal errors: line 18: field ice_tcp not found in type config.RTCConfig line 19: field force_relay not found in type config.RTCConfig
t
Thanks — you hit two separate problems: the missing file error and the YAML parsing errors. I’ll address both and give the minimal fixes. 1) "open ./config: no such file or directory" • Ensure you pass the correct filename. If your file is named
config.yaml
run:
Copy code
livekit-server --config ./config.yaml
• Confirm the file exists in the current directory:
Copy code
ls -l ./config.yaml
2) "field ice_tcp not found" / "field force_relay not found" • Those fields are not top-level keys under
rtc
. Use the correct nesting and field names under
rtc.ice
. Example valid snippet:
Copy code
rtc:
  node_ip: 0.0.0.0
  tcp_port: 7881
  port_range_start: 50000
  port_range_end: 60000

  ice:
    # force relay mode (true/false)
    force_relay: false

    # TCP remotes (if needed)
    tcp_remotes:
      - "1.2.3.4:7883"

# STUN servers for external IP discovery
stun_servers:
  - "stun:<http://stun.l.google.com:19302|stun.l.google.com:19302>"

turn:
  enabled: true
  domain: your-exact-hostname
  tls_port: 5349
  udp_port: 3478
  cert_file: /etc/letsencrypt/live/your-exact-hostname/fullchain.pem
  key_file: /etc/letsencrypt/live/your-exact-hostname/privkey.pem
Notes: • Replace
your-exact-hostname
with the exact hostname on your TLS cert and DNS. •
stun_servers
is required if
use_external_ip: true
so LiveKit can discover and advertise the correct public IP. •
tcp_remotes
and
tcp_port
handle ICE-TCP. Do not use
ice_tcp
. 3) Quick validation steps • Validate YAML syntax:
yamllint config.yaml
(or
python -c 'import yaml,sys; yaml.safe_load(sys.stdin.read())' < config.yaml
) • Dry-run config (if supported):
livekit-server --config ./config.yaml --dry-run
• Check server version:
livekit-server --version
(some keys differ by version) If you'd like, paste your current full
config.yaml
(sanitized of secrets) and I’ll correct it for your LiveKit version and hostnames. Sources: Firewall Tips | Running LiveKit on AWS | Avoiding Room ID Reuse When Re-Creating Rooms With the Same Name
h
livekit-server version 1.9.3
t
Thanks — since you’re on LiveKit v1.9.3, the parsing errors mean those keys are invalid or mis-nested for that version. Quick actionable steps to get your server starting and fix ICE behavior: 1) Confirm file path • Run:
ls -l ./config.yaml
and then start with:
Copy code
livekit-server --config ./config.yaml
2) Use correct RTC keys for v1.9.3 • Don’t use
ice_tcp
or
force_relay
at the top level. Put relay/ICE settings under
rtc.ice
and use
tcp_port
for enabling ICE-TCP. Example minimal working snippet:
Copy code
port: 7880
log_level: debug

rtc:
  node_ip: 0.0.0.0
  tcp_port: 7881
  port_range_start: 50000
  port_range_end: 60000
  use_external_ip: true

  ice:
    force_relay: false
    tcp_remotes:
      - "127.0.0.1:7883"

stun_servers:
  - "stun:<http://stun.l.google.com:19302|stun.l.google.com:19302>"

turn:
  enabled: true
  domain: your-exact-hostname
  tls_port: 5349
  udp_port: 3478
  cert_file: /etc/letsencrypt/live/your-exact-hostname/fullchain.pem
  key_file: /etc/letsencrypt/live/your-exact-hostname/privkey.pem

room:
  departure_timeout: 3

keys:
  test-key: "REDACTED"
3) Important checks for ICE connectivity • Ensure TURN domain matches TLS cert and DNS. • Open required ports (UDP/TCP): ◦ TCP: 7880, 7881, 3478, 5349 ◦ UDP: 3478, 50000–60000 • Keep
stun_servers
when
use_external_ip: true
so LiveKit discovers your public IP. 4) Validate before start • Lint YAML:
yamllint config.yaml
or a simple parse check. • Start with debug logging and tail server logs:
Copy code
livekit-server --config ./config.yaml
  journalctl -u livekit-server -f
If you want, paste your current full
config.yaml
(remove secrets) and I’ll correct it for v1.9.3 and your hostnames. Which hostname should replace
your-exact-hostname
?
h
port: 7880 log_level: debug rtc: node_ip: 0.0.0.0 _#node_ip: 127.0.0.1_ tcp_port: 7881 _# force_relay: false_ port_range_start: 50000 port_range_end: 60000 _# use_external_ip should be set to true for most cloud environments where_ # the host has a public IP address, but is not exposed to the process. # LiveKit will attempt to use STUN to discover the true IP, and advertise # that IP with its clients use_external_ip: true ice: force_relay: false _# connection_timeout: 30s_ _# node_ip: livesk.obpl.tech_ _# participant_timeout: 5_ stun_servers: - “stun.obpl.tech:3478” redis: # redis is recommended for production deploys address: 127.0.0.1:6379 #address: 13.203.66.45:6379 keys:
t
Thanks — I reviewed your latest snippet. A few quick fixes so your config parses and ICE works on v1.9.3: 1) YAML syntax • Replace smart quotes with straight quotes. Example: stun_servers: • "stun.obpl.tech:3478" 2) Correct nesting for ICE/relay • Keep relay settings under
rtc.ice
(not top-level). Example:
Copy code
rtc:
  node_ip: 0.0.0.0
  tcp_port: 7881
  port_range_start: 50000
  port_range_end: 60000
  use_external_ip: true

  ice:
    force_relay: false
    tcp_remotes:
      - "127.0.0.1:7883"
3) STUN format • Include the
stun:
prefix for public STUN servers when possible, or use a known public STUN for testing: stun_servers: • "stun:stun.l.google.com:19302" 4) TURN / certs / DNS • If behind NAT/firewall, run/configure TURN and ensure: ◦ TURN domain exactly matches TLS cert and DNS. ◦ TURN ports and media UDP range are open (UDP 3478, UDP 50000–60000; TCP 3478/5349/your tcp ports). 5) participant timeout • There is no per-participant departure timeout field. Use server-side logic +
remove_participant
if you need per-participant eviction. Next steps I can do for you • Paste your full sanitized config.yaml and I’ll correct it for v1.9.3 (I can replace hostnames/secrets). • Or, if you prefer, share the exact error after fixing quotes and nesting and I’ll iterate. Which would you like? Sources: client-sdk-android | livekit/livekit_composite | DeepWiki | Client SDKs | livekit/livekit_composite | DeepWiki | Firewall Tips