How to stream OBS to your own RTMP server on a VPS

Set up your own RTMP server on a Linux VPS with Nginx and send your OBS live stream without depending on Twitch or YouTube. Practical technical walkthrough.

Streaming through Twitch or YouTube works until you need control: lower latency, video retention on your own terms, simultaneous rebroadcast to multiple destinations, or simply independence from a platform that could ban your channel. Running your own RTMP server on a VPS solves all of that for a fraction of what a dedicated commercial streaming plan costs.

This tutorial covers the full path: deploying Nginx with the RTMP module on an Ubuntu VPS, configuring OBS Studio to publish to it, validating the broadcast in an external player and hardening the server for production. The persona here is the technical streamer who already knows OBS but has never administered a media server.

Estimated execution time: 40 to 60 minutes, including package downloads and the first transmission test.

Prerequisites

Before starting, confirm the environment. RTMP is a protocol sensitive to network latency — a VPS with low upload or a congested link will degrade the quality of the live stream regardless of server configuration.

Prerequisites

Ubuntu 24.04 LTS (or 22.04) with root access over SSH, ~500 MB free for the Nginx build and auxiliary packages, public IP reachable from your local machine. Minimum 100 Mbps bandwidth on the server for 1080p60 without bottlenecks. OBS Studio 30.x or higher installed on the source machine.

Default RTMP port 1935/tcp
HLS port (optional) 8080/tcp
Suggested 1080p60 bitrate 6000 kbps
Video codec h.264

Installing Nginx with the RTMP module

The nginx-rtmp-module is not shipped in the official Ubuntu repositories as a loadable dynamic module. The cleanest way on current distributions is to install the libnginx-mod-rtmp package, which already delivers the module compiled against the apt version of Nginx — no need to build from scratch.

01

Update the package index and install Nginx along with the RTMP module:

sudo apt update
sudo apt install -y nginx libnginx-mod-rtmp

The libnginx-mod-rtmp package adds the file /etc/nginx/modules-enabled/50-mod-rtmp.conf, which loads the module automatically. Confirm that it loaded:

nginx -V 2>&1 | grep -o rtmp

If the output is rtmp, the module is available.

02

Create the RTMP configuration. The rtmp block sits outside the http block — edit /etc/nginx/nginx.conf and add at the end of the file:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        allow publish 127.0.0.1;
        allow publish YOUR_HOME_IP;
        deny publish all;
        allow play all;

        application live {
            live on;
            record off;
        }
    }
}

Replace YOUR_HOME_IP with the public IP from which OBS will publish. Without this restriction, anyone on the internet can publish streams to your server, consuming bandwidth and CPU.

03

Test the configuration and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

If nginx -t complains about unknown directive "rtmp", the module did not load — review step 01 and confirm that /etc/nginx/modules-enabled/50-mod-rtmp.conf exists.

Opening the firewall

By default the VPS comes with the firewall active or blocking non-standard ports. RTMP uses TCP 1935 — without an explicit rule, OBS will hit a silent timeout.

04

Open port 1935 in UFW:

sudo ufw allow 1935/tcp
sudo ufw reload

If you use iptables directly without UFW, the equivalent rule is:

sudo iptables -A INPUT -p tcp --dport 1935 -j ACCEPT

Persist it with iptables-save or your provider’s method.

Watch the provider's firewall

Some VPS providers add an extra firewall layer on the control panel (security groups, network policies) that runs before the iptables on the machine itself. If telnet YOUR_IP 1935 from home times out but inside the VPS it works on localhost, the block is external — open the port on the panel as well.

Configuring OBS Studio

With the server ready, OBS now has to point to it. The endpoint follows the pattern rtmp://SERVER_IP/application and the stream key is the name of the stream the player will consume.

05

Open OBS Studio and go to File → Settings → Stream. Set:

  • Service: Custom
  • Server: rtmp://YOUR_SERVER_IP/live
  • Stream key: pick a name — it can be mychannel, test01, any string without spaces or special characters.

Click OK to save.

06

Tune the encoder in Settings → Output → Advanced Mode → Streaming:

  • Encoder: x264 (CPU) or NVENC H.264 (if you have an NVIDIA GPU)
  • Bitrate: 4500 kbps for 1080p30, 6000 kbps for 1080p60
  • Keyframe interval: 2 seconds
  • Profile: main
  • Preset: veryfast (CPU) or Quality (NVENC)

A keyframe every 2s is important for future HLS use — segments without a keyframe do not work well in HTML5 players.

07

Click Start Streaming on the main OBS panel. The indicator in the bottom-right corner should turn green with an active bitrate. If it turns red or shows “Failed to connect”, see the troubleshooting section below.

Verifying the broadcast

Now confirm the stream is actually reaching the server and can be consumed. VLC is the fastest way — it speaks RTMP natively without any plugin.

08

On the server, check that Nginx is accepting the connection:

sudo tail -f /var/log/nginx/error.log

When OBS connects, you see lines like client connected '...' and publish started.

09

On your local machine, open VLC and go to Media → Open Network Stream. Paste:

rtmp://YOUR_SERVER_IP/live/mychannel

Where mychannel is the key you defined in OBS. Click Play — the live stream should appear with 2 to 5 seconds of latency. If you see “could not open”, check that OBS is actually transmitting (green indicator) and that the key matches the URL exactly.

Add HLS for in-browser distribution

If you want to embed the live stream on a website, add this inside the application live block in nginx.conf:

hls on;
hls_path /var/www/hls;
hls_fragment 2s;
hls_playlist_length 10s;

Create /var/www/hls with permissions for www-data, serve it through a normal HTTP block, and point an hls.js player to http://IP/hls/mychannel.m3u8.

Troubleshooting

OBS connects but disconnects after a few seconds

Almost always a lack of upload bandwidth at home or on the server. Reduce the OBS bitrate to 2500 kbps and try again. If it stabilizes, bandwidth was the bottleneck — measure your real sustained upload with speedtest-cli on your machine and size the bitrate to stay below 70% of the available upload.

Error “RTMP_ReadPacket, failed to read RTMP packet header”

Typical symptom of a timeout between the RTMP client (VLC, player) and the server. Increase the timeouts in the Nginx rtmp block:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        timeout 30s;
        ping 30s;
        ping_timeout 10s;
        # ... rest
    }
}

Reload with sudo systemctl reload nginx.

Very high latency in VLC (more than 10 seconds)

VLC has an aggressive network buffer by default. In Tools → Preferences → Input/Codecs, reduce “Network caching” to 500 ms. Raw RTMP delivers sub-3s latency — if it is still higher than that, the problem is the player, not the server.

Next steps

With the RTMP server working, it is worth considering:

  • Add HLS for browsers: the hls on block in nginx-rtmp exposes the stream as .ts segments consumable by hls.js — required for an HTML5 player on your site.
  • Set up automatic recording: the record all directive saves each live stream as FLV in /var/recordings, useful for retention and on-demand replay.
  • Rebroadcast to Twitch/YouTube in parallel: the push rtmp://... directive inside the application forwards the stream to other destinations at no extra OBS upload cost.
  • Harden with RTMPS through stunnel: to expose publishing publicly without plain text, stunnel in front of nginx-rtmp terminates TLS on port 1936.
  • Move to a streaming-dedicated VPS: if you go past 50 concurrent viewers or want to deliver 4K, the CPU becomes a bottleneck on transcoding. A Hostini VPS with dedicated vCPU and a 1 Gbps symmetric link holds a lot more load than a shared server.

Frequently asked questions

What is the difference between RTMP and RTMPS for OBS?

RTMP runs in plain text on port 1935; RTMPS adds TLS on top, usually on 443 or 1936. OBS Studio supports both — RTMPS requires a valid certificate on the server (Let's Encrypt does the job) and stunnel or a TLS proxy in front, since the nginx-rtmp module does not speak TLS natively. For production exposed on the public internet, prefer RTMPS.

How much bandwidth do I need to stream 1080p60 from OBS?

With h.264 at a 6,000 kbps bitrate (Twitch's standard for 1080p60), you consume roughly 750 KB/s of sustained upload. Multiply by the number of viewers if the server has to redistribute — 10 concurrent 1080p60 viewers already mean 7.5 MB/s of outbound traffic. Size the VPS thinking about upload, not download.

Can I use the same RTMP server to record and rebroadcast at the same time?

Yes. The nginx-rtmp module lets you combine the `record` and `push` directives inside the same `application` — you record the stream to disk as FLV and simultaneously forward it to Twitch, YouTube or any other endpoint. This is useful for keeping a local backup of the broadcast at no extra OBS upload cost.

Why does my OBS live show 'failed to connect to server'?

Three common causes: port 1935 blocked by the VPS firewall (ufw or iptables), nginx-rtmp not listening on the public interface (check `ss -tlnp | grep 1935`), or the stream key has special characters that OBS escapes. First test with `telnet IP 1935` from your machine — if it connects, the problem is the OBS configuration.

Can I deliver the live stream over HTML5 without Flash?

Yes, but raw RTMP does not run in modern browsers. The standard solution is to convert to HLS inside nginx itself — add `hls on; hls_path /tmp/hls;` to the RTMP application and serve the directory through an HTTP block. The player on your site uses hls.js or video.js pointing to the `.m3u8`. Latency rises from ~2s (RTMP) to ~10-20s (HLS), which is normal.

Does the stream key still need to be secret on a private server?

Yes. Anyone who has the stream key can publish content to your server if you do not restrict publishing by IP or token. Use the `allow publish` directive with specific IPs, or implement authentication via the `on_publish` callback to an HTTP endpoint that validates the token before accepting the stream.

Topics:
Next steps Infrastructure optimized for live streaming, recording and VOD.Set up your streaming server on Hostini →
Was this tutorial helpful?
Chat on WhatsApp