Skip to content
streamneo.
Troubleshooting13 min read

How to Limit CPU Usage on a VPS Running a 24/7 YouTube Stream

Set a real CPU ceiling for a VPS YouTube encoder, then check encoding speed and stream health before keeping the change.

sn.
StreamNeoPublished 4 October 2026
Worth sharing?

CPU usage on a VPS running a 24/7 YouTube stream can be limited with a hard quota, but the quota must be applied to the service or container that owns the encoder. A lower CPU graph is not enough: if FFmpeg or OBS cannot encode in real time, the stream can fall behind even while the VPS appears less busy.

For a systemd service, the main control is CPUQuota=. For Docker, use --cpus or the equivalent Compose setting. These create a ceiling; CPUWeight= and --cpu-shares only alter priority when workloads compete. After every change, check both the encoder’s progress and YouTube’s stream health.

Why a CPU limit can affect a live encoder

A live encoder has to process frames quickly enough to send them on schedule. Depending on the setup, it may decode a video, scale it, apply filters, encode the video, encode audio, package the result and send it to YouTube. A loop of simple footage may be light, while a high-resolution source, animated overlays, several filters or software H.264 encoding can require much more CPU.

A CPU quota interrupts or delays work after the process reaches its permitted CPU time. That can leave the encoder unable to produce packets at the intended rate. You may see encoding speed fall below real time, frames accumulate, audio and video drift, or the process reconnect after a failure. The exact symptom depends on the encoder, workload, VPS kernel and the amount of CPU available.

This is why there is no universally safe percentage to apply. A quota that works for a static devotional loop may not work for a live OBS scene with browser sources. Even the same resolution can produce different CPU demand when the source contains movement, scaling or filters.

A hard limit can still be useful. It prevents one stream from consuming all available CPU and gives other services a chance to run. The trade-off is that the encoder has less headroom when the workload changes. Treat the first setting as a test, not as proof that every future scene will fit within it.

If your stream uses FFmpeg to rotate files, first make sure the deployment itself is understood. The guide on streaming videos in order from a text file to YouTube can help separate playlist and process problems from CPU problems.

Measure the process or container using CPU

Start with a baseline while the stream is operating normally. Record the CPU use, the encoder’s reported speed and any warnings in its log. If the stream changes between quiet and busy scenes, observe both rather than measuring only a calm section.

For a direct process, tools such as top, htop or ps can show the FFmpeg or OBS process. Look for the actual encoder process, not only the shell command that started it. A wrapper may use little CPU while its child process does the work. If several FFmpeg processes exist, identify which one owns the active YouTube connection.

For Docker, use:

docker stats <container-name>

Docker documents docker stats as a live view of container resource usage, including CPU, memory and network activity. See the Docker resource constraints documentation for the current behaviour and available controls. The displayed CPU figure is useful for observing change, but it does not tell you by itself whether the encoder is keeping pace.

FFmpeg’s progress and statistics are more relevant to the stream than a single CPU percentage. Depending on the FFmpeg build and command, inspect the reported frame count, output time, speed, bitrate and warnings. FFmpeg also documents -stats_enc_pre and -stats_enc_post for writing per-frame information before encoding and when encoded packets are received. The FFmpeg documentation explains the available reporting options.

Compare encoded progress with wall-clock time. If ten minutes pass but the output has advanced by less than ten minutes, the encoder is falling behind. A process can show moderate CPU use and still be too slow if a quota, I/O wait, a single busy thread or another bottleneck is limiting it.

Also check memory, disk and network. A CPU change cannot fix a full disk, a damaged input file or insufficient outbound bandwidth. CPU and network are separate constraints, and a stream can fail with one healthy while the other is overloaded.

Choose a systemd unit or Docker container as the target

Apply the limit to the unit or container that owns the encoder process tree. This gives the control the right scope and means restarts normally receive the same setting. Applying a limit to an unrelated login shell or temporary command may leave the actual stream untouched.

For a systemd deployment, inspect the service that launches FFmpeg or OBS. It might be named youtube-stream.service, but use the name from your own system. Check its command and status before editing it:

systemctl status youtube-stream.service
systemctl cat youtube-stream.service

The important question is whether the service starts the encoder directly or starts a script that then launches it. A correctly configured service cgroup covers the processes belonging to that service. If the script hands work to another supervisor or moves it into another scope, verify where the encoder actually runs before relying on the quota.

For Docker, identify the container connected to YouTube:

docker ps

Then inspect its command, image and recent logs. If a Compose file creates the container, make the resource setting part of that file rather than applying a one-off change that disappears during recreation. Do not confuse a video file container, a monitoring container and the container that performs the encoding.

The same principle applies to OBS running through a graphical session. If OBS is not managed by the systemd unit you are editing, that unit may not control it. Confirm the process hierarchy and deployment method first.

A stream key problem is different from a CPU problem. If YouTube does not show the expected control or key, the troubleshooting steps in YouTube Stream Key Not Appearing in Live Control Room in India are more relevant than changing CPU settings.

Set a hard CPU quota with CPUQuota= or --cpus

For a systemd service, add CPUQuota= under the [Service] section. For example:

[Service]
CPUQuota=150%

This number is an illustration of the syntax, not a recommendation for your stream. systemd expresses the quota as a percentage of one CPU. CPUQuota=20% permits up to one-fifth of one CPU, while a value above 100% permits more than one CPU-equivalent. The suitable value depends on measured encoding speed, the chosen codec, frame rate, filters and other work on the VPS.

After changing a unit file, reload systemd and restart the service:

sudo systemctl daemon-reload
sudo systemctl restart youtube-stream.service
sudo systemctl status youtube-stream.service

The systemd resource-control documentation describes CPUQuota= and related controls. Watch the service after the restart. Confirm that the expected encoder process is running, that the output is advancing in real time and that YouTube reports a healthy incoming stream.

For Docker, create or recreate the container with a CPU ceiling such as:

docker run --cpus="0.5" <image-name>

Docker uses --cpus to limit the CPU capacity available to a container. The documented example of 0.5 represents at most half of one CPU. It is a syntax example, not a safe setting for every encoder. If your container already exists, changing the deployment definition and recreating it is usually clearer than assuming a temporary command has altered the persistent configuration.

With Compose, the equivalent setting is expressed as the number of usable CPUs in the service definition, for example:

services:
  stream:
    image: your-image
    cpus: "0.5"

Use the syntax supported by the Compose version and deployment mode you run. Check the resulting container with docker inspect and observe it with docker stats after starting the stream.

Docker notes that resource controls can have requirements in rootless mode, including cgroup v2, systemd and controller delegation. If the setting appears to be ignored, check the Docker documentation and the host’s cgroup configuration rather than assuming the encoder is exempt. A VPS provider can also restrict which resource controls are available to you.

Do not set an arbitrarily low quota and leave it overnight without a test. YouTube’s guidance says to test before starting a live stream and to monitor stream health. A quota change is complete only after the stream has been observed under representative content.

Understand quota ceilings versus CPU priority

A hard quota and a priority weight solve different problems. A quota says how much CPU time the workload may consume. A weight says how strongly it should compete with other workloads when they are competing for CPU.

Control What it changes Hard ceiling Suitable use
systemd CPUQuota= Maximum CPU time for a service cgroup Yes Capping an FFmpeg or OBS service
Docker --cpus or Compose cpus CPU capacity available to a container Yes Capping a containerised encoder
systemd CPUWeight= Relative scheduling access between units No Giving other units preference during contention
Docker --cpu-shares Relative scheduling weight between containers No Sharing CPU without a fixed ceiling
systemd AllowedCPUs= CPUs on which a service may run No, placement only Restricting CPU placement for a specific reason
Docker --cpuset-cpus CPUs on which a container may run No, placement only Pinning a container to selected CPUs

CPUWeight= does not cap a service when the machine is otherwise idle. The service can still use available CPU. Similarly, reducing Docker --cpu-shares does not mean the container can never exceed a particular CPU percentage. It changes the outcome when other workloads need CPU.

Affinity controls are different again. AllowedCPUs= and --cpuset-cpus restrict where work runs, not how much CPU time it can consume over time. Pinning an encoder to one CPU can make its available capacity smaller, but it is not the same statement as a CPU-time quota and may create a bottleneck.

Use a quota when the requirement is “this encoder must not exceed this ceiling”. Use a weight when the requirement is “other work should win during contention”. Use affinity only when you have a clear placement or isolation reason. Mixing these controls can make diagnosis harder, so change one relevant control at a time.

Watch encoder performance and YouTube stream health

After applying a quota, observe three layers: the process, the encoded output and YouTube. The first tells you what the VPS is doing. The second tells you whether the encoder is keeping pace. The third tells you whether the received stream meets YouTube’s expectations.

At the process layer, watch CPU, memory, disk activity and the service or container logs. At the encoding layer, look for falling speed, increasing delay, repeated buffer warnings, dropped frames or a growing difference between output time and wall-clock time. At the platform layer, open YouTube Studio’s live control room and inspect the stream-health indicators and preview.

YouTube’s current live encoder guidance covers RTMP or RTMPS, H.264, H.265 and AV1 video codecs, frame rates up to 60 fps, constant bitrate and a recommended two-second keyframe interval that should not exceed four seconds. Check the current YouTube encoder settings guide for the codec, resolution and frame rate you actually use, because platform guidance can change.

A CPU limit does not change these delivery requirements. If a quota causes the encoder to miss its target frame rate, a valid keyframe interval will not make the stream healthy. Conversely, a healthy encoder can still have a poor stream if the VPS cannot send data reliably.

YouTube also recommends representative testing and monitoring before and during a broadcast. Test content that resembles the real channel: a moving devotional background, an ambience loop with gradients, a news playlist or a shop-promo rotation. A static test image may hide the CPU demand of the actual stream.

For an Indian music or devotional channel, keep an eye on long file transitions as well as steady playback. The advice in how to keep an Indian music YouTube stream live after a Windows update concerns a different failure source, but it illustrates why process restarts and continuity checks matter in an always-on channel.

Network capacity deserves a separate check. YouTube’s streaming tips recommend leaving 20% upload headroom. That figure is YouTube guidance, not a CPU setting. If outbound capacity is short, lowering CPU usage will not repair the network path. Run an upload test and compare it with the configured stream output before treating a CPU adjustment as the answer.

Adjust or roll back a limit that causes lag

If encoding speed falls below real time after the change, do not wait for the stream to recover by itself. Restore the previous quota or remove the limit, restart the service or container, and confirm that the encoder catches up. Keep a note of the previous value and the evidence that led to the change.

For systemd, edit the unit again, remove or increase CPUQuota=, then run:

sudo systemctl daemon-reload
sudo systemctl restart youtube-stream.service

For Docker, change the --cpus or Compose value, recreate the container and check the logs and live metrics. If the cap is being set by a higher-level deployment tool, change it there rather than applying a temporary value that will be lost at the next deployment.

Adjust in measured steps. After each change, allow enough time to observe the busiest part of the content and check YouTube’s health. Do not interpret a lower CPU reading as success if output time is no longer advancing at the expected rate.

If the desired stream quality does not fit within the available CPU, you have several trade-offs. You can give the encoder more CPU, reduce resolution, reduce frame rate, simplify filters, select a less demanding encoding workload or use hardware encoding where the setup supports it. Lowering resolution or frame rate can reduce work, but it changes the delivered stream and must be checked for visual quality and compatibility.

A larger VPS allocation may help when CPU capacity is the bottleneck, but it is not a guarantee of stream continuity. The result still depends on the CPU generation, encoder settings, input material, concurrent processes and network. Likewise, moving from a local VPS process to a managed workflow may remove the need to keep your own machine running, but it does not remove the need to verify the YouTube output.

For a file-based channel, removing unnecessary processing is often the least disruptive first step. Avoid scaling a source that already matches the output, remove filters that are not visible in the final picture and prevent unrelated jobs from running at the same time as the encoder. For an ambience channel, also inspect colour gradients and compression rather than solving every visual issue with more CPU. The guide to colour banding and compression artefacts on ambience loops covers that separate quality problem.

StreamNeo removes the need to keep a VPS encoder process running and monitored when your requirement is simply to upload a finished video, connect its YouTube stream key and let the 24/7 broadcast run with your computer switched off.

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

Is CPUWeight= a hard CPU limit?

No. CPUWeight= changes relative access between systemd units when they compete for CPU. It does not stop the encoder using available CPU when there is no competing work. Use CPUQuota= when you need a CPU-time ceiling.

Should I limit the VPS or only the encoder?

Limit the systemd unit or Docker container that owns the encoder process and its children. Limiting the whole VPS is not usually a precise control and can also constrain monitoring, networking or other services. Confirm the process hierarchy before applying the setting.

What CPU percentage is safe for a 24/7 YouTube stream?

There is no universal safe percentage. Measure the actual encoder workload, apply a test quota, and check encoding speed and YouTube stream health under representative content. If the output falls behind, increase or remove the quota or reduce the workload.

Can reducing CPU fix a stream that keeps reconnecting?

Not necessarily. Reconnection can come from CPU lag, insufficient upload capacity, process failure, a stream-key issue or another fault. Check encoder progress, logs, network headroom and YouTube’s stream-health information separately before choosing a remedy.

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