Skip to content
streamneo.
Setup Guides12 min read

How to Keep FFmpeg Running After an SSH Disconnect on DigitalOcean

Choose tmux, systemd or nohup to keep an FFmpeg job running after SSH disconnects, and learn how to check its state and logs.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

If SSH disconnects, an FFmpeg process started in the foreground may stop or become inaccessible, depending on how it was launched and how the shell handles the session. To make the job deliberate, use tmux when you want to return to its terminal, systemd when you want service management and logs, or nohup for a basic detached command.

These are Linux process-management choices on a DigitalOcean Droplet, not a DigitalOcean-specific persistence guarantee. None ensures that FFmpeg will survive a reboot, host problem, resource failure, or its own error; you still need to check the process and its output after reconnecting.

Why an SSH disconnect can affect FFmpeg

When you connect to a Droplet over SSH, you get a shell associated with that login session. If you start FFmpeg directly in the foreground and then close the terminal, the shell and its child process may receive a hangup signal or otherwise lose the terminal they were using. The exact behaviour depends on the shell and process setup, so an SSH connection closing is not a reliable way to detach a job.

There is a second issue even when you try to run a process in the background: FFmpeg normally checks console input. Its FAQ explains that these checks can suspend a background job, and recommends -nostdin or redirecting standard input from /dev/null on Linux and macOS. See the FFmpeg FAQ on running a background task before adapting the command to your installed build.

The useful distinction is between the process and the terminal. A process manager or detached terminal session can separate FFmpeg from the SSH connection, but it cannot make the media job healthy by itself. A source may disappear, an output path may be unwritable, storage may fill, or FFmpeg may exit because of an encoding or network error. If you are building the stream command as well as keeping it alive, start with the practical 24/7 FFmpeg stream guide and test the command before detaching it.

Choose tmux, systemd, or nohup

Pick the tool according to what you need after you log back in. tmux is useful for a one-off run when seeing the live terminal again matters. systemd is better when you want the operating system to manage a named service, show its state, and collect its output in the journal. nohup is a smaller shell-level option if output is redirected and you do not need an interactive terminal or supervisor.

Method Useful when Return to the same terminal? Built-in lifecycle and restart policy? Main thing to manage
tmux You are running a one-off command and may need to inspect its live output Yes, by reattaching No Session state and useful logs
systemd You want a managed service with status and journal output No Yes, according to the unit configuration Correct unit, paths and restart behaviour
nohup You want a simple detached shell command No No Output redirection, PID and later health checks

A session is not the same as a service. With tmux, you can reconnect to the terminal, but you must decide what to do if FFmpeg exits. With systemd, you can define how the service starts and whether it restarts after certain exits, but it will not preserve an interactive terminal. With nohup, you mainly avoid a hangup affecting the launched process; it does not add an attachable session or supervision.

For a stream built from a playlist, the command's looping and input behaviour matter just as much as persistence. The guide to running a continuous YouTube playlist with FFmpeg on a DigitalOcean VPS is relevant to that separate question. Keep the command itself simple enough to inspect before choosing how to manage it.

Run FFmpeg in a detached tmux session

Use tmux when you want to leave a command running and later return to the same terminal view. Install it with the package manager for the Droplet's Linux distribution if it is not already available. The package name and installation command vary by distribution, so check the distribution's own package instructions rather than pasting a command intended for another system.

Start a session with a name you will recognise:

tmux new -s ffmpeg

At the tmux prompt, run your actual FFmpeg command. This schematic example shows where -nostdin belongs; the input, codecs, output and paths need to match your job:

ffmpeg -nostdin -i /path/to/input -c:v libx264 /path/to/output.mp4

The example is not a universal encoding recommendation. For a live broadcast, your command may instead read from a playlist or input stream and send output to YouTube. Check that it works in the foreground first and that the stream key, if used, is supplied securely. The continuous playlist guide covers the streaming-command context; this page is about keeping a launched process separate from SSH.

When the command is running, detach from tmux rather than closing the session. Press Ctrl-b, release the keys, then press d. This leaves the named tmux session in the background on the Droplet. You can then disconnect SSH. Avoid typing exit inside the session if you intend to leave the command running, because that closes the shell in the session and can end the job.

After reconnecting, list sessions and reattach:

tmux ls
tmux attach -t ffmpeg

If the session is absent, the command may have finished, the session may have been closed, or the Droplet may have restarted. If you can reattach but FFmpeg is no longer running, the terminal may show its final message. For a long run, terminal scrollback alone may not retain everything you need; consider capturing output in a log as well, then inspect the log after reconnecting.

tmux is a good fit when a person may need to watch the run or issue terminal commands. It does not restart FFmpeg after an error, decide whether a finished transcode should run again, or make a transient network input reliable. If those are service-lifecycle requirements, use a service manager rather than treating a persistent terminal as a supervisor.

Create a systemd service for managed jobs

Use systemd when the job should be represented as a service rather than as a shell session. A unit gives the operating system a command to start and a place to report status and output. This takes more setup than tmux, and you need to be comfortable editing a configuration file with administrator permissions.

A minimal unit might look like this:

[Unit]
Description=FFmpeg job

[Service]
Type=simple
WorkingDirectory=/path/to/job
ExecStart=/usr/bin/ffmpeg -nostdin -i /path/to/input -c:v libx264 /path/to/output.mp4
Restart=no

[Install]
WantedBy=multi-user.target

Treat this as a shape to adapt, not a file to copy unchanged. Confirm FFmpeg's actual path with your distribution's tools, use absolute paths for input and output, and set a working directory that exists and is accessible to the service. If you need a non-root account, configure the unit for that account and ensure it can read the source and write the destination. A command that succeeds in your SSH shell can fail as a service if it relies on your shell's environment, current directory, or permissions.

Create the unit using an appropriate administrator account, then ask systemd to reload unit files and start it:

sudo systemctl daemon-reload
sudo systemctl start ffmpeg-job.service

Check the result rather than assuming that a successful start means the media job is healthy:

sudo systemctl status ffmpeg-job.service
sudo journalctl -u ffmpeg-job.service

Restart= is a policy choice. A one-time transcode that exits successfully is normally complete, not a failed service that should be launched again. Setting an indiscriminate restart policy can cause a completed job to run again and potentially overwrite or conflict with output. For a continuing stream, decide which failures should trigger a restart and whether the command is safe to run again. The systemd service documentation describes service behaviour and restart settings; options can differ by installed systemd version.

Do not enable a unit to start at boot just because it is called a service. Enable it only when you have decided that the job should start after a Droplet reboot and have considered what happens to its input, output files, and stream destination. Enabling a unit is not a recovery plan for every failure, and a service manager cannot promise successful completion of a media job.

Use -nostdin when FFmpeg should not read input

A detached job generally should not wait for keyboard input from a terminal that is no longer available. Place -nostdin among FFmpeg's command-line options so it does not check standard input for interactive commands. FFmpeg documents this as the way to prevent its console input checks for a background task. The installed version's help and documentation are worth checking if the option behaves differently in a locally built version.

For example:

ffmpeg -nostdin -i /path/to/input -c:v libx264 /path/to/output.mp4

-nostdin changes console input handling; it does not detach the process, capture output, or add restart behaviour. Pair it with tmux, systemd, or a redirected shell launch according to the job. A service's standard input is not an interactive SSH terminal, but writing the command explicitly this way makes the intended non-interactive behaviour clear.

The FFmpeg FAQ also describes redirecting input from /dev/null on Linux and macOS. That can be useful with a shell-launched job, particularly if you are following an existing command, but do not confuse it with output redirection. Send standard output and standard error somewhere you can inspect as well. If your FFmpeg command is part of an always-on devotional stream, the pre-recorded bhajan setup guide can help with the broader channel workflow; process persistence alone does not settle content, source, or stream configuration.

Use nohup only for a simple detached command

nohup can be enough for a basic task when you only need the shell to launch it without tying it to the terminal's hangup, and you are happy to manage logs and checks yourself. It cannot be reattached to like a tmux session, and it does not create a managed service with a configured restart policy.

A shell pattern with explicit input and output handling is:

nohup ffmpeg -nostdin -i /path/to/input /path/to/output >ffmpeg.log 2>&1 < /dev/null &
printf '%s\n' "$."

The redirections send standard output and errors to ffmpeg.log and give the process no interactive input. The final command prints the launched process ID in common shells; save it if it will help you inspect the job. Shell details vary, so validate the syntax in the Droplet's shell. Check that the log path is writable and that it has enough space for the output you expect.

A saved PID is only a clue, not a health check. The process can exit after the PID is printed, and process IDs can later be reused. After reconnecting, inspect the process and its log rather than concluding that a job is healthy because a number was saved. Choose nohup when the task is straightforward and manual checks are acceptable; if you need to see the existing terminal or manage restarts, tmux or systemd is a better fit for those specific needs.

Check status and logs after reconnecting

Start with the mechanism you chose. For tmux, run tmux ls and attach to the named session. For a systemd unit, run systemctl status for that unit and inspect its journal with journalctl -u. For nohup, check whether the expected process is running and read the redirected log. These checks answer different questions: a session can exist without a healthy FFmpeg process, and a service can be active while the stream itself is not reaching its intended destination.

For a service, recent journal output is often a useful first diagnostic:

sudo journalctl -u ffmpeg-job.service

Look for FFmpeg's own error messages, permission failures, missing files, and whether the process exited or is still producing output. systemctl status gives a service state and recent context, but neither command confirms that a remote viewer can see the correct programme. Check the receiving platform and the stream itself separately. The systemd journal documentation covers journal queries and their options.

For a shell-launched command, capture both standard output and standard error. Without redirection, useful messages may have been printed only to the terminal that is now gone. For tmux, reattaching gives you the terminal session while it exists, but durable logs help if the session has ended or its scrollback is insufficient.

Also check the mundane causes before changing process-management settings. Verify the input and output paths, permissions, available disk space, and whether a remote source or destination is still reachable. If FFmpeg fails because an input has disappeared, detaching it more effectively only leaves the failure unattended. A useful operating routine is to run a test, confirm the output or live destination, detach or start the managed unit, then reconnect later and inspect state and logs.

What process persistence does not guarantee

A detached session or service addresses the relationship between FFmpeg and your SSH terminal. It does not guarantee that the process will survive Droplet reboot, a host failure, memory pressure, storage exhaustion, network interruption, or an FFmpeg error. systemd can apply a restart policy you configure, but restarting a command is not the same as restoring a valid stream or completing a transcode correctly.

DigitalOcean's SSH documentation explains how to connect to and troubleshoot SSH access to a Droplet; it does not establish that a particular foreground FFmpeg process is preserved after a disconnect. See the DigitalOcean SSH troubleshooting guide for SSH issues, and treat process lifecycle as a separate Linux configuration question. None of the methods here is a DigitalOcean guarantee of persistence or uninterrupted streaming.

If you need a 24/7 broadcast, separate the operational questions: can the process continue without your laptop, can failures be noticed, can it restart safely, and can someone verify that the destination is receiving the right output? A cloud-run workflow can remove the need to leave your own computer on; StreamNeo is relevant when the pain is managing a prerecorded YouTube broadcast from a local machine rather than maintaining that local machine and SSH session. It does not change the need to check that your channel and content are ready.

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 FFmpeg always stop when I close SSH?

Not necessarily, but a foreground process tied to a shell is not a dependable way to keep a job running after the session ends. Use a deliberate detachment or service approach and verify it after reconnecting. SSH disconnection by itself is not a persistence guarantee.

Should I use tmux or systemd for a single encode?

Use tmux if you want to return to the live terminal and inspect the run interactively. Use systemd if you want named service status and journal logs, or service lifecycle behaviour you have configured. A one-off encode does not automatically need a service or a boot-time restart policy.

Does -nostdin keep FFmpeg alive?

No. It prevents FFmpeg from checking console input, which can otherwise suspend a background task, but it does not detach the process or restart it after failure. Pair it with the process-management method that fits your job.

Does nohup let me reconnect to FFmpeg's terminal?

No. nohup is a simple way to launch a detached command, usually with explicit log redirection, but it does not provide an attachable terminal or service supervision. Use tmux when returning to the terminal matters.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗