Set up a streaming server: one upload for any number of viewers

Published on 10 min read

You send a single stream to the server, and the server supplies all viewers from it. Your own line therefore only ever carries one upload, whether ten or a thousand people are watching. This guide covers the setup, the protocols and the bandwidth math behind it.

Anyone who streams without a server of their own sends the picture to every single viewer separately. Ten viewers mean the same data ten times, a hundred viewers a hundred times. The upload at home or in the office is saturated after a handful of viewers, and the picture starts to stutter even though the computer is bored.

A streaming server turns that around: you send exactly one stream to the server, and the server supplies all viewers from it. Your own line therefore only ever carries a single upload, no matter whether ten or ten thousand people are watching. This article shows why that works so well, how you set up such a server, which protocol costs how much delay, and how much traffic really adds up.

The problem: your upload is the bottleneck

Video is a continuous stream. A 1080p stream at 60 frames per second needs 4.5 to 8 Mbit/s depending on the content, 720p sits at 3 to 5 Mbit/s. That bitrate flows per viewer, the whole time, without a break.

An average home connection in Germany manages between 10 and 50 Mbit/s upstream, and even many fiber connections sit at 50 to 100 Mbit/s upstream. The math is therefore over quickly:

Viewersat 3 Mbit/sat 6 Mbit/sHome line enough?
515 Mbit/s30 Mbit/sbarely
2060 Mbit/s120 Mbit/sno
100300 Mbit/s600 Mbit/sno
10003 Gbit/s6 Gbit/sno

On top of that comes a second problem that often gets overlooked: your connection shares that line with everything else in the household or the office. As soon as somebody uploads a large file or a backup starts running, the stream breaks down. A server in the datacenter does not have this problem, because there the uplink is available to you alone.

The principle: upload once, deliver many times

The setup consists of three parts:

  • The sender, meaning OBS, ffmpeg or a hardware encoder, sends one stream to the server. That part is called ingest.
  • The server accepts this single stream, converts it into the delivery format you want and keeps it ready.
  • The viewers pull the stream from the server. That part is called egress, and it is the part that grows with the number of viewers.

The asymmetry is what matters: the path from you to the server is walked once, the path from the server to the viewers a thousand times. That is why your own connection needs only as much upstream as a single stream, while the server needs an uplink that keeps up with the audience.

How much traffic really adds up

Bandwidth is only half the math. The volume is more interesting, because that is what many providers bill for. The formula is simple:

Volume in GB = bitrate in Mbit/s × seconds × viewers ÷ 8000

A few realistic examples:

ScenarioBitrateDurationViewersVolume
Weekly talk3 Mbit/s2 h50135 GB
Daily show6 Mbit/s3 h2001.6 TB per day
Round-the-clock channel4 Mbit/s24 h301.3 TB per day
One-off major event6 Mbit/s4 h200021.6 TB

The numbers in the last column are the reason streaming and volume-based billing go together badly. A single well-attended broadcast can use up the included volume of a whole month, and every further terabyte is then billed separately. On a plan with unlimited traffic that calculation disappears entirely: the monthly price is fixed, whether 200 GB or 50 TB go through the line.

Which software fits you

SoftwareStrengthA good fit for
nginx with the RTMP modulelean, stable, does RTMP and HLS at the same timethe classic starting point, forwarding to platforms
MediaMTXa single binary, SRT and WebRTC out of the boxlow delay without much tinkering
SRSa great many features, cluster-capablelarger setups with several nodes
Owncastcomplete solution with a web interface and chatyour own small streaming site

For a first setup, nginx with the RTMP module is the obvious choice: it is available everywhere, well documented, and you can later use the same server as the web server for the viewer page without rebuilding anything.

Setting up a streaming server with nginx and RTMP

Install

On Debian and Ubuntu the package libnginx-mod-rtmp brings the module with it, so you do not have to compile anything yourself:

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

On AlmaLinux and Rocky Linux the module comes from the EPEL repository:

dnf install -y epel-release
dnf install -y nginx nginx-mod-rtmp ffmpeg

Configure

The RTMP section goes into nginx.conf outside the http block, which is the most common beginner mistake. A lean, working version looks like this:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
            record off;

            # HLS for regular viewers
            hls on;
            hls_path /var/www/stream/hls;
            hls_fragment 2s;
            hls_playlist_length 12s;

            # only your own address is allowed to publish
            allow publish 203.0.113.10;
            deny publish all;

            # anyone may watch
            allow play all;
        }
    }
}

The HLS files are then served by the normal web server. A small block in the http section is enough for that:

server {
    listen 80;
    server_name stream.example.com;

    location /hls {
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        root /var/www/stream;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
    }
}

Create the directory, check the configuration, reload:

mkdir -p /var/www/stream/hls
chown -R www-data:www-data /var/www/stream
nginx -t && systemctl reload nginx

Open the ports

RTMP runs on port 1935, delivery over 80 and 443. With nftables or ufw:

ufw allow from 203.0.113.10 to any port 1935 proto tcp
ufw allow 80/tcp
ufw allow 443/tcp

Note the first line: the publishing port is open only for your own address. An RTMP port that is open to the world gets found within a few days, because whole address ranges are scanned automatically, and then somebody else is streaming over your line.

Publishing from OBS

In OBS under Settings, Stream, set the service to "Custom":

FieldValue
Serverrtmp://stream.example.com/live
Stream keya name you pick yourself, for example kanal1

Under Output you set the bitrate. As a guide: 1080p60 at 6000 kbit/s, 1080p30 at 4500 kbit/s, 720p30 at 3000 kbit/s. Set the keyframe interval to 2 seconds, otherwise HLS ends up with uneven segments and the player stutters when it switches.

Watching

The stream is then available at https://stream.example.com/hls/kanal1.m3u8 and opens in any HLS-capable player, in the browser with hls.js or Video.js for example. For a quick check, VLC via "Open Network Stream" is enough.

Publishing to several platforms at once

This is the second big advantage of your own server. Instead of blowing up your line with three parallel uploads, you send once to the server and it forwards from there. For that you add one line per destination in the application block:

application live {
    live on;
    record off;

    push rtmp://live.plattform-a.example/app/STREAM_KEY;
    push rtmp://live.plattform-b.example/app/STREAM_KEY;
}

Your upload stays at a single stream while that happens. The server does the multiplying, and bandwidth there is exactly what it is for.

Delay: which protocol for what

The delay comes almost entirely from delivery, not from publishing. That is important to understand, because many people look in the wrong place:

Delivery pathDelayFits
HLS, default settings20 to 30 stalks, church services, sports without betting
HLS with short segments6 to 10 sthe usual compromise
Low-Latency HLS2 to 5 sstreams with chat
SRTunder 1 scontribution feeds between locations
WebRTCunder 0.5 sconversations, auctions, remote control

The lower the delay, the more expensive the individual viewer becomes. HLS is the cheapest, because it consists of plain files that any web server and any cache can deliver. WebRTC, by contrast, keeps a separate connection open for every viewer and therefore costs considerably more compute. Only take the low delay where you genuinely need it.

Transcoding: when it pays off

As long as the server only passes the stream through, it needs almost no compute. A single modern core serves several hundred viewers that way, and the uplink is the only bottleneck.

That changes as soon as you want to offer several quality levels so that viewers on a weak connection can watch too. Every additional level has to be computed:

ffmpeg -i rtmp://127.0.0.1/live/kanal1 \
  -c:v libx264 -preset veryfast -b:v 3000k -s 1280x720 -c:a copy -f flv rtmp://127.0.0.1/live/kanal1_720 \
  -c:v libx264 -preset veryfast -b:v 1200k -s 854x480  -c:a copy -f flv rtmp://127.0.0.1/live/kanal1_480

Count on two to four cores per level. Three levels therefore tie up eight to twelve cores permanently. So think carefully about whether you need them: for an audience that mostly sits at a computer or on Wi-Fi, a single well-chosen level is often enough.

Locking it down: who may publish

A streaming server is visible from the outside and it will be found. Three measures are enough for everyday operation:

  • Firewall on the publishing port. Only your own address may reach 1935. If your address changes, use a VPN connection into the server instead.
  • Check the stream key. With on_publish, nginx calls a small script on every publish attempt that checks the key against a list and rejects anything that does not match.
  • Basic protection against overload. A streaming server is a worthwhile target, because an outage is visible immediately. At KernelHost, flood protection with 3.2 Tbps of capacity sits in front of every server without you having to set anything up. There is more about it on the page about DDoS protection.

Choosing the location, and running several servers

The server does not belong near you, it belongs near your viewers. Your own connection to the server is established once and then runs stably, even across half a continent. The connection to the viewers, by contrast, decides load time and drop-off rate.

If your audience sits mostly in Europe, a location in Germany is the right one. If it spreads across several continents, a second server plus distribution over DNS pays off, so that every viewer lands on the nearest one. KernelHost offers locations in Germany, on the US West Coast, on the US East Coast, and in Singapore and South Korea for that, and you will find an overview under server locations.

If you distribute files instead of live pictures, meaning updates, images or video archives, a streaming server is not the right tool: a cache in front of the origin is. How that works is in the article Build your own CDN server.

Which server fits

For a streaming server the order of priorities is different than for a web server:

  1. Uplink and traffic. This is the bottleneck, and it always is. A real gigabit uplink without throttling carries around 160 viewers at 6 Mbit/s.
  2. Unlimited traffic. Volume-based plans are hard to budget for streaming, because a single successful evening uses up the monthly volume.
  3. CPU. Secondary, as long as you do not transcode. With transcoding it becomes the second bottleneck.
  4. RAM and disk. Least critical. Disk space only becomes a topic once you keep recordings.

Our Unlimited Traffic root servers are cut for exactly this case: a real 2 × 1 Gbit/s uplink per server, unlimited volume without throttling, a fixed monthly price regardless of how much you transfer, and 3.2 Tbps of flood protection out of the box. The server is provisioned in under 30 seconds, with full root access, IPv4 and a /64 IPv6 subnet. Billing is prepaid and you can cancel monthly, so you can start with a small plan and grow when your audience grows.

Frequently asked questions

Why do I need a streaming server at all?
Without a server, your computer sends the stream to every viewer separately. With ten viewers at 6 Mbit/s that is 60 Mbit/s of upstream, with a hundred it is already 600 Mbit/s. A typical home connection manages 10 to 50 Mbit/s upstream. With a streaming server you send exactly once, and the server takes over the distribution.
How much bandwidth does the server need?
Multiply the bitrate by the number of concurrent viewers. 500 viewers at 6 Mbit/s come to 3 Gbit/s. More important than the peak, though, is the monthly volume: those same 500 viewers generate around 2.7 TB in two hours. That is why unlimited traffic is the decisive property for streaming, not the CPU.
Which software is the best choice?
To start with, nginx with the RTMP module, because it is lean and can do RTMP as well as HLS at the same time. MediaMTX is the more modern alternative with SRT and WebRTC out of the box. SRS offers the most features but takes more learning. Owncast is a complete solution with a web interface and chat.
How big is the delay?
RTMP to the server costs less than a second. The delay comes almost entirely from delivery: HLS with default settings sits at 20 to 30 seconds, with short segments at 6 to 10, Low-Latency HLS at 2 to 5. SRT and WebRTC get below one second, but cost more compute per viewer.
Do I need transcoding, and what does it cost?
Only if you want to offer several quality levels. Plain pass-through without re-encoding needs hardly any CPU, one core serves hundreds of viewers. As soon as you also output a 1080p stream in 720p and 480p, you need roughly two to four modern cores per level. Only plan for transcoding once you really need it.
Can I publish to Twitch and YouTube at the same time?
Yes, that is exactly what the server is good for. You send once to your server, and it forwards the same stream to any number of platforms. With nginx-RTMP one push line per destination is enough. Your own line still carries only a single upload.
How do I stop strangers from publishing on my server?
Restrict the ingest port in the firewall to your own address, and check the stream key via on_publish on top of that. Without both, every open RTMP server picks up foreign streams within days, because whole address ranges get scanned.
Where should the server be located?
Not near you, but near your viewers. The path from you to the server is walked once, the path from the server to the viewers a thousand times. If your audience sits in Europe, the server belongs in Europe. If the audience spreads across continents, a second server and distribution over DNS pay off.
Is a VPS enough, or do I need a dedicated server?
For pass-through without transcoding, a VPS with a few cores is perfectly fine, because the bottleneck is the uplink and not the compute. Dedicated hardware only pays off once you transcode several quality levels or run many parallel channels.
How do I test whether the server can take the load?
Start the stream and open it with several tools at once, for example ffmpeg in idle mode. Watch the network throughput and the utilization while you do. If you reach the limit of the uplink before the CPU gets warm, the math worked out and you need more bandwidth, not more cores.

Streaming RTMP HLS SRT nginx OBS Restream Unlimited Traffic