Skip to content
streamneo.
Tools12 min read

How to Rotate FFmpeg Stream Logs on a VPS Running a 24/7 YouTube Channel

Choose between journald and logrotate for a live FFmpeg stream, then size retention around observed log growth and available VPS disk space.

sn.
StreamNeoPublished 5 October 2026
Worth sharing?

If FFmpeg is managed by systemd and its stderr is captured there, use journald’s storage limits rather than rotating journal files with logrotate. If FFmpeg appends to an ordinary file that it cannot reopen, logrotate’s copytruncate can rotate it without changing the path, but a small amount of data may be lost during the copy-and-truncate interval.

The right choice depends on the actual destination of FFmpeg’s messages and whether the running process can reopen a renamed log. First identify that path, then choose a retention policy using observed log growth and the free space you can afford to use.

Start by finding FFmpeg’s log destination

FFmpeg writes diagnostic messages to stderr by default. What happens next depends on how you start it: systemd may collect stderr in the journal, a shell command may redirect it to a file, or FFmpeg’s report option may create a report file. Confirm the launch method before adding a rotation rule. The FFmpeg documentation describes its logging options, including the default stderr destination.

For a systemd service, inspect the unit and any drop-in configuration for its standard output and error settings. Then query the unit’s records with journalctl -u your-service-name. Use the actual unit name in place of the example. If the service is launched by a supervisor, container, or interactive shell, trace the output settings in that system instead; do not assume that a process running on a VPS is automatically writing to journald.

For a file-based setup, inspect the FFmpeg command and its wrapper script for redirection such as >> /var/log/ffmpeg/stream.log 2>&1. Check the configured path and the file that is actually growing. A timestamped report produced by FFmpeg is a separate case: it may be written somewhere other than the path you expected to rotate.

This is worth checking during an ordinary running period, not just after a failure. A quiet log can make a wrong assumption look plausible. Compare the service’s recent output, the configured destination and any files whose size changes as the stream runs. The issue is local to the VPS, not the YouTube stream key; for a separate streaming failure, see why an FFmpeg reconnect may not resume after an RTMP timeout.

When systemd captures stderr, use journald

If the service’s stderr goes to the systemd journal, journald already handles collection and its own storage management. Keep it in that path. A logrotate rule aimed at journal files is the wrong layer: journald owns their format and lifecycle, while logrotate is intended for ordinary files.

Use journalctl to inspect output for the unit and understand what the service is reporting. On a long-running channel, filter by unit and time range when investigating a reconnect, encoding error or restart, rather than treating every line as something that must be retained forever. Journal queries can also help you distinguish an FFmpeg issue from messages emitted by the service manager.

Check whether journal storage is persistent or volatile on the VPS. Persistent journal files are commonly stored under /var/log/journal; volatile data may be held under /run/log/journal and can disappear on reboot. The location and behaviour depend on host configuration. Do not plan on a week of incident history surviving a restart until you have checked both persistence and retention settings.

A journal and a plain text log serve different operational needs. The journal associates output with a unit and can be queried by time and service; an ordinary file can be simpler to hand off or process with tools that expect text. If you choose the journal, keep the service output there and control its footprint using journald’s supported settings and tools. The systemd journal documentation explains the configuration controls; confirm details against the systemd version installed on your VPS.

Set a journal budget that fits the VPS

Inspect the current journal configuration before changing it. Relevant settings can include overall storage limits and limits for individual journal files. The effective result may also depend on whether storage is persistent, how much disk is available, and other services sharing the VPS. Avoid copying a value from another server without first looking at those conditions.

Choose a budget from the disk space you can spare for all journal data, not just FFmpeg. If the VPS has a small disk and also stores the video being streamed, an expansive journal allowance can compete with that media and other system files. If you need service history after a reboot, persistent storage matters; if the journal is volatile, a size limit does not make it persistent.

journalctl provides supported vacuum controls for archived journal files, including size-, time- and file-count-based options. These controls do not necessarily remove active journal files, so do not interpret a vacuum command as a way to immediately shrink every byte of currently open journal data. The journalctl manual describes the distinction and the available options.

Make one change at a time and recheck actual use. A configured limit is a ceiling or retention control, not a promise that a particular number of days will always remain available: the rate at which services produce messages varies. If you need a useful incident window, observe the VPS over representative stream conditions and review what remains after the policy has had time to operate. Keep in mind that reducing old history is a trade-off against the ability to diagnose a problem that was not noticed immediately.

For an append-only file, consider copytruncate

If FFmpeg writes to a regular file and keeps that file open, a conventional rename can create a problem. Renaming the path does not necessarily make the process close its existing file descriptor. FFmpeg may continue writing to the renamed file while a new file appears at the original path, leaving the expected current log empty and the older file still growing.

When you cannot reliably tell the running process to reopen its log, logrotate’s copytruncate is designed for this situation. It copies the current contents to a rotated file and then truncates the original in place. The process continues writing through the existing descriptor, and the original pathname remains available for new output. The logrotate manual documents the option and its caveat: some logging data might be lost in the small interval between copying and truncation.

A basic rule might look like this, but treat it as a shape to adapt, not a universal policy:

/var/log/ffmpeg/stream.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}

The example assumes that this is the actual file FFmpeg appends to and that the installed logrotate version supports the options as used. The user and group, permissions, path, scheduler and service layout all need to match the VPS. missingok avoids an error if the file is absent; notifempty avoids rotating an empty file; compress compresses older generations. rotate 7 retains a count of generations, not a guaranteed seven-day history if rotations occur more or less often.

The cost of copytruncate is the brief copy/truncate loss window, plus the work of copying a file that may be large. It is a practical compromise for a process that cannot reopen its file, not a zero-loss design. If every diagnostic line matters, consider whether the process has a documented, reliable reopen mechanism and test it before using a rename-and-create pattern. A postrotate command that runs successfully is not proof that FFmpeg has switched to the new file.

Choose trigger, compression and retention from evidence

A daily rule offers a regular opportunity to rotate, but it does not necessarily protect a disk during a burst of verbose output. A size trigger can rotate after a file crosses a threshold when logrotate runs; maxsize can be used alongside a time interval to impose an additional size condition. These triggers are not instantaneous alarms. Their practical effect depends on how often logrotate is scheduled and how quickly the file grows between runs.

Measure growth on the actual channel. Record the current file size, wait through representative operating conditions, then compare the change and note whether reconnects or other noisy events caused bursts. Do not use a single quiet hour as the basis for a policy if the stream has periods of repeated errors. If you cannot observe growth yet, begin conservatively, watch free disk space, and revise the trigger once you have real measurements.

Retention is a capacity decision. Estimate how much space the current log and rotated generations may use, then leave room for the video, system updates, temporary files and other services. Compression can reduce the space used by older text logs, but the active file remains uncompressed, and compression does not rescue a disk that fills before the next rotation. A generation count controls how many rotations remain, not their age; at a size-based rate, the same count can cover a different time span than under a daily schedule.

Approach Fits when Retention control Main trade-off
systemd journal Unit stderr is captured by systemd journald limits and journalctl vacuuming of archived files Persistence and retained history depend on host configuration and log volume
File with copytruncate FFmpeg appends to a file it cannot reliably reopen logrotate schedule or size, generation count and compression Simple live-process path, with a documented small data-loss window
File with reopen action You have verified that the process can reopen after rotation logrotate policy plus a working postrotate action Avoids copying the whole active file, but reopen behaviour is deployment-specific

If FFmpeg runs under systemd but you deliberately redirect stderr to a file, classify it by the actual destination, not by the fact that systemd starts it. Conversely, a file appearing under /var/log does not make it a journal file. For another view of how a long-running prerecorded stream is operated, the guide to streaming pre-recorded MP4 files with OBS without audio crackling covers a different production path; the same principle applies here: make decisions from the real process behaviour.

Keep diagnostic reports deliberate

FFmpeg’s -report option is useful for troubleshooting, but it is not a retention policy. It writes the command line and log output to a timestamped report file and implies debug-level logging. Left enabled indefinitely on an always-on process, it can generate diagnostic material at a rate that is not reflected in the ordinary log path you thought you were monitoring.

Check the actual command line and environment for -report and FFREPORT. The latter can set a report filename and numerical log level. If a report is needed to diagnose a specific problem, decide where it will be written, how it will be retained, and when you will disable it. Review the configured log level as well: verbose debugging can obscure the operational messages you need and consume more disk than normal logging.

This does not mean that reports should never be used. They can be valuable when reproducing an encoder, input or reconnect issue. The point is to enable them with a purpose and include their files in the disk review, rather than assuming the service’s main log rotation rule will cover a separate timestamped output.

A channel that loops a video overnight may behave differently from one with a changing playlist or unstable input. If your FFmpeg command is part of a broader playback workflow, see how to schedule a YouTube live playlist with OBS Advanced Scene Switcher for an alternative playlist setup. That does not change FFmpeg’s logging defaults, but it may help you identify which process and output path you actually need to manage.

Verify the policy on the VPS

Before relying on a new rule, inspect the installed logrotate version and its local documentation. Review how the host schedules logrotate and where the rule is included. A syntactically plausible file that is not loaded by the scheduler will not rotate anything. Test configuration parsing using the installed tool’s supported check or debug mode, and avoid treating a dry run as proof that the live file will behave as expected.

For a regular file, plan a controlled test when you can observe the result. Confirm that the intended path is rotated, that FFmpeg continues writing to the current path after truncation, and that older generations are compressed or removed according to the policy. Check the actual file descriptor or watch new messages reach the active pathname; the existence of a rotated file alone does not establish that logging continued correctly.

For a journal, check the unit’s recent records, persistence mode and disk use before and after applying limits. Confirm that the policy affects archived data as intended and that the history you need remains available. Do not vacuum old records during an incident unless you have decided those records are no longer needed for diagnosis.

Finally, check free disk space as well as log files. A log policy can look correct while another file is filling the VPS, and compressed generations can still accumulate if a count or schedule is not operating as expected. Revisit the policy after changing the FFmpeg command, service manager, logging destination or stream workload. If the repetitive task of keeping a local FFmpeg process running is itself the problem, StreamNeo can remove the need to keep your own computer on for a file-based YouTube broadcast; it does not change how you manage logs on a VPS.

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

Can I rotate an FFmpeg log without stopping the stream?

Often, yes. With an ordinary append-only file that FFmpeg cannot reopen, copytruncate lets it continue writing to the same pathname, but the logrotate manual warns that some data may be lost between the copy and truncation. If stderr is captured by systemd, use journald’s retention controls instead.

Is copytruncate lossless?

No. It has a small documented interval in which data can be lost. If that matters for your operational or audit needs, look for a verified way for the running process to reopen a renamed log, or choose a logging path that meets your retention requirements.

How often should logrotate run, and how many logs should I keep?

There is no universal schedule or generation count that suits every VPS. Observe how quickly your logs grow, how much disk is available after accounting for other files, and how long you need the history; then choose and verify a schedule or size trigger and retention count.

Will logrotate manage FFmpeg reports or the systemd journal automatically?

Not unless you configure it for the actual output, and journal files should be managed by journald rather than a file-oriented logrotate rule. FFmpeg reports may use a separate timestamped path, so check for -report or FFREPORT and decide explicitly how those files are retained.

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 Tools guides ↗ · All topics ↗