If you run FFmpeg on a Vultr VPS, you can have systemd start it again after a qualifying process failure. Run FFmpeg as the service’s main process, choose a restart policy deliberately, and add a delay so repeated failures do not become a tight loop.
That only covers failures systemd can see as process exits or other qualifying failures. An FFmpeg process can remain alive while YouTube receives a frozen or unhealthy stream, so pair process supervision with checks of the received broadcast.
First identify what failed
A stream that has stopped moving on YouTube can have several different causes. Before adding restart settings, identify whether FFmpeg exited, its output connection failed while the process stayed up, or the process is still running but the received stream is stalled. Those cases need different recovery layers.
Start with the VPS. Check whether the service is active and whether its recent journal entries show an exit, a connection error, repeated reconnects, or resource pressure. For a manually launched process, look for the FFmpeg process and its output in the terminal or logs. Record the time of the problem and compare it with what YouTube Studio shows for the event.
A systemd restart is useful when the process has stopped in a way covered by its policy. It cannot infer from process status alone that the video is advancing correctly on YouTube. If the process remains active, blindly restarting it may interrupt a stream that is still recovering; if the viewer sees a freeze, blindly trusting the active status leaves the fault unresolved.
For a separate way to check what viewers receive, see this guide to monitoring a YouTube stream from another device. A second device or browser gives you an end-to-end view that a VPS process list cannot provide.
Put FFmpeg under systemd supervision
A service manager can observe a process it starts and apply a policy when that process exits. On a typical Linux VPS, create a systemd unit for the stream and put the FFmpeg command in ExecStart=. The important design choice is to have FFmpeg itself be the main long-running process, rather than starting it through a shell wrapper that exits separately.
A wrapper can make process ownership and exit status harder to reason about. If you do need a wrapper for preparation, make sure it replaces itself with FFmpeg or otherwise has well-defined signal and exit handling. For a straightforward stream, a direct ExecStart= avoids that extra layer.
A representative unit might look like this:
[Unit]
Description=YouTube FFmpeg stream
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=stream
WorkingDirectory=/home/stream
ExecStart=/usr/bin/ffmpeg -re -stream_loop -1 -i /home/stream/loop.mp4 -c:v libx264 -c:a aac -f flv rtmp://example.invalid/live/REPLACE_WITH_KEY
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
This is a shape to adapt, not a ready-to-paste stream configuration. Replace the input, output URL and encoding options with the command you have tested. Do not put a real stream key in a public example, shared support post, or source repository. The key is a credential for sending the feed; YouTube explains how to manage live-stream settings and recover if a key is compromised in its live stream settings guidance.
Systemd unit-file paths and user names vary by distribution and local practice. Once you have saved the unit in the appropriate location, ask systemd to reload its definitions, enable the service if it should start after reboot, and start it. Then inspect the unit with systemctl status your-stream.service and read its recent messages with journalctl -u your-stream.service. Keep the service name consistent in those commands and in your monitoring notes.
Choose on-failure and a restart delay
For a stream that should run until you deliberately stop it, Restart=on-failure is usually the sensible starting policy. According to the systemd service manual, it covers non-zero exits and other qualifying failures, including certain signals, timeouts and watchdog expiry. An explicit systemctl stop is not treated as a failure that should immediately bring the service back.
Pair the policy with RestartSec=. The sample uses five seconds only as an example: it gives a short pause before another attempt, but it is not a universal value. If the cause is a momentary interruption, a brief delay may be enough. If the input is missing, the stream key is wrong, or YouTube rejects the output, repeatedly starting again after a very short pause only produces more failed attempts and logs.
Use the journal to decide whether the delay is appropriate. If FFmpeg repeatedly exits with the same configuration error, fix that error rather than making restarts faster. If the log points to a temporary connection problem and a fresh run connects successfully, the delay is part of recovery. A service that is flapping can also make diagnosis harder, so look at the restart count and the timestamps, not just the word “active”.
The phrase “on failure” refers to the service manager’s view of the process, not the health of the YouTube event. systemd can restart an FFmpeg run after an exit that meets its rules; it does not inspect the picture or sound being received. Keep that distinction in mind when choosing a health check.
Use always only for a clean exit loop
Restart=always also restarts a service after FFmpeg exits successfully. That can be useful if the command is intentionally designed to finish one segment or task cleanly and then begin another, or if an unexpected clean exit should still lead to another run. It is not automatically a stronger choice for every continuous stream.
A clean exit may be meaningful. You might have stopped the encoder for maintenance, or a deliberate command change may make it exit normally. With always, a normal exit can trigger another start unless you explicitly stop the service through systemd. The systemd manual distinguishes this from on-failure, and an explicit stop remains an intentional stop rather than a reason to launch again.
For a typical FFmpeg command intended to run continuously, begin with on-failure, then test what happens when FFmpeg exits normally and abnormally. Choose always only if you have a reason to treat a clean exit as needing another run. The policy does not make a broken input valid: if every run exits cleanly because the file has ended, an always policy may simply repeat the same outcome.
Add FIFO recovery for output errors
Systemd and FFmpeg’s FIFO muxer address different parts of a failure. Systemd can start a new process after a qualifying process failure. FFmpeg’s FIFO muxer can attempt to recover from some output errors while the encoder process remains running, avoiding a full process restart for certain transient connection problems.
The FFmpeg manual’s FIFO muxer section documents RTMP recovery options and includes an example. The relevant options include -f fifo, -fifo_format flv, -attempt_recovery 1, and -recovery_wait_time 1. These are output-path options; where they belong in your command depends on your existing output and the FFmpeg build you are using. The manual also notes that max_recovery_attempts defaults to zero, meaning unlimited attempts, so decide whether unbounded retrying suits your operational needs rather than assuming it is a universal best setting.
A schematic form of an output might be:
-f fifo -fifo_format flv -attempt_recovery 1 -recovery_wait_time 1 rtmp://.../live/KEY
Do not treat that fragment as a complete encoder command. Confirm the syntax against the installed FFmpeg version, preserve the input and codec settings that already work, and test the output before relying on it overnight. FIFO recovery may help when the output encounters a recoverable error; it does not repair a terminated process, a bad key, or every possible receiver-side failure.
| Recovery layer | Failure it can address | What it tells you | What it does not establish |
|---|---|---|---|
systemd with on-failure |
FFmpeg exits in a qualifying failure state | Service and process events in the journal | That YouTube is receiving a healthy picture and sound |
| FFmpeg FIFO recovery | Some transient errors on the output path | FFmpeg output and recovery messages | That the event is playing normally for viewers |
| YouTube Studio and a viewer check | Problems visible in received-stream health or playback | What the platform reports and what a viewer sees | The precise cause on the VPS without logs |
If the actual symptom is buffering rather than an exited process, compare your settings and connection as well as restart policy. This guide on YouTube Live buffering and encoder settings covers another part of that diagnosis. The right fix may be bitrate or network headroom, not more frequent process starts.
Check the received stream for a stall
An exit-triggered policy cannot tell that FFmpeg is alive but sending no useful media. A process can remain present while blocked, disconnected in a way it has not exited from, or producing output that is not healthy at the receiver. A monitor for this class of failure needs an end-to-end signal: for example, a check of YouTube’s stream health and playback, or a purpose-built watchdog that verifies progress rather than merely checking that a PID exists.
YouTube recommends monitoring stream health and checking the actual event. In its encoder settings guidance, it documents supported encoder settings, including H.264 among video options, AAC or MP3 audio for RTMP/RTMPS, constant bitrate, and a recommended two-second keyframe interval that should not exceed four seconds. It recommends RTMPS. These settings do not ensure recovery, but compatible, tested output makes it easier to distinguish a configuration problem from a process crash.
Before a scheduled broadcast, check the current ingest URL and key in YouTube Studio, and test with similar audio and video to what you will use live. Confirm that the event is accessible and that the received picture and sound advance. The YouTube streaming tips also advise leaving upload-bandwidth headroom above the total stream bitrate and note that connection interruptions can break a stream.
The VPS matters too. CPU pressure can contribute to dropped frames and buffering; Vultr’s 2025 Ubuntu streaming guide discusses this in an OBS scenario, not as a universal FFmpeg threshold. Treat it as a reason to inspect resource use, not as a blanket rule for your FFmpeg workload. If encoding is straining the host, reducing resolution or choosing more CPU capacity may be more useful than changing restart policy.
A process check and a stream check answer different questions. Use systemctl and the journal to learn whether FFmpeg is running and why it restarted. Use YouTube Studio and a viewer device to learn whether the feed is actually arriving and playing. If your channel is a continuous music loop, the article on running a 24/7 YouTube chillhop radio stream may also help you think through the source material and continuity, but it does not substitute for checking the live event.
Test recovery before relying on it
Do not wait for an overnight failure to discover whether the unit behaves as expected. First test the command manually with a private or otherwise appropriate test event. Confirm the audio and video, stream health, and output protocol. Check that a wrong path, missing file, or invalid key gives a useful error rather than assuming the service will resolve it.
Next test the supervisor in a controlled way. Start the service, inspect its status, and deliberately stop the FFmpeg process in a manner that produces a failure exit. Verify that systemd records the exit and starts a new run after the configured delay. Then use systemctl stop and confirm that your intentional stop stays stopped. If you chose always, separately observe what a clean process exit does and make sure that is the behaviour you intended.
Test FIFO recovery independently if you add it. Simulate a brief output interruption only in a controlled test, and observe whether FFmpeg reports a recovery attempt and resumes output. Do not assume an error message means viewers received a healthy stream again; check the YouTube-side health view and playback. Also test what happens after a longer failure, when recovery limits or an operator decision may matter.
Record the expected signals: the systemd unit state, the relevant journal lines, FFmpeg’s output errors, and what YouTube Studio reports. Keep a short recovery note with the unit name, the command to inspect it, where the media file lives, and how to rotate a compromised stream key. That is more useful at 03:00 than relying on memory or publishing credentials in the note.
Finally, test after changing the input, codecs, key, or service definition. Use systemctl daemon-reload after editing a unit, then restart it deliberately and verify both process and received-stream health. A successful service start is a necessary check, not proof that YouTube has resumed receiving a healthy broadcast.
For a small channel where the operational burden is specifically keeping a file-based broadcast running while your own computer is off, StreamNeo removes the need to maintain this FFmpeg-and-systemd process on your Vultr machine; it is YouTube-only, so this VPS guide remains relevant if you need direct control of an FFmpeg pipeline.
Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.
FAQ
Will systemd restart FFmpeg if YouTube stops showing the stream?
Only if the condition results in a failure systemd can observe, such as a qualifying FFmpeg exit. If FFmpeg remains alive while the received stream is stalled or unhealthy, an exit-based restart policy may do nothing. Check stream health separately.
Should I use Restart=always for a 24/7 broadcast?
Not by default. on-failure is a good starting point when a failed FFmpeg run should be relaunched but an intentional clean exit should remain meaningful. Use always when you deliberately want clean exits to trigger another run, and test that behaviour.
Does FIFO recovery replace systemd?
No. FIFO recovery may retry some output errors within FFmpeg, while systemd can restart FFmpeg after a qualifying process failure. They cover different failure conditions, and neither alone proves that viewers are receiving healthy video and audio.
What should I check after a restart?
Confirm the unit is active and read the journal for the reason it restarted. Then check YouTube Studio’s stream health and view the event from a separate device to verify that the received picture and sound are advancing.