Slowing down video processing
@PavelS was discussing the big server hit for video processing in a previous post. This issue warrants a separate thread, imo.
Perhaps someone could turn this idea into a mod or even build it into future versions of UNA. The UNA developers host their own servers but still they have made a path for remote video processing, which is certainly going beyond the call of duty.
Here's a short overview of how linux and/or ffmpeg can be adjusted, courtesy of Google. Obviously, in a shared environment, server modifications are limited. Please let us know if your own experimentation produces good results.
1. Using OS-level Commands (Recommended on Linux)
These tools help manage how much of the server's resources the FFmpeg process can consume, which is the best approach for a shared environment.
nice: This command adjusts the CPU priority of a process. A higher "niceness" value means lower priority, so the process will run in the background when other tasks need CPU time.- bash
nice -n 19 ffmpeg -i input.mp4 [other ffmpeg options] output.mp4
- (A niceness of 19 is the lowest priority).
cpulimit: This utility can explicitly limit the percentage of CPU usage for a process. You will likely need to install this tool if it's not available.- bash
cpulimit -l 50 -- ffmpeg -i input.mp4 [other ffmpeg options] output.mp4
- (The
-l 50option attempts to limit the process to 50% of one CPU core's capacity. The value depends on the number of cores available; consult thecpulimitdocumentation for the correct value for your server). - Combining
niceandcpulimit: - bash
nice -n 19 cpulimit -l 50 -- ffmpeg -i input.mp4 [other ffmpeg options] output.mp4
- (Make sure to add the
--before the FFmpeg command if usingcpulimit). taskset: This command can confine a process to specific CPU cores.- bash
taskset -c 0 ffmpeg -i input.mp4 [other ffmpeg options] output.mp4
- (This runs FFmpeg only on the first core (core 0)).
2. Using FFmpeg's Built-in Options
You can also use options within the FFmpeg command itself to reduce its resource demands.
-threads: This option (when placed after the input file) can limit the number of threads FFmpeg uses for encoding. Setting it to1can significantly reduce CPU load, though it might not always strictly limit to a single core for all codecs.- bash
ffmpeg -i input.mp4 -threads 1 [other ffmpeg options] output.mp4
- Encoding Presets: Using a faster encoding preset reduces the computational complexity of the encoding process, thus using less CPU per frame, though this may impact quality. Presets range from "ultrafast" to "veryslow".
- bash
ffmpeg -i input.mp4 -c:v libx264 -preset fast [other ffmpeg options] output.mp4
3. General Considerations
Run Processes in the Background: Use job management systems (like message queues or simple shell job operators like &, wait) to manage multiple concurrent FFmpeg tasks. This prevents new encoding jobs from launching until previous ones are complete or resources are available.
Avoid Concurrent Runs: The core problem with shared hosting is often multiple FFmpeg instances running simultaneously. Implement logic to ensure only one (or a limited number) of FFmpeg processes runs at any given time.
Check Server Limits: Be aware of the specific CPU and memory limits imposed by your shared hosting provider. Maxing these out can lead to your processes being terminated or your account suspended.
-
- · PavelS
- ·
Hi @banister
I would like to thank you for your research and work. It's great that someone is also looking into this. I've been thinking about this a lot lately and trying different settings and versions of ffmpeg, but unfortunately the results, such as speed and server load, weren't particularly impressive.
I currently have the CPU limit for conversion set to 80% to keep some reserve for other tasks, but I did not limit the queue or the number of processes. Another issue is, as you mentioned, the limited configuration options on a VPS. Many administrators won’t even discuss custom setups that go beyond the standard service.
I came to the conclusion that running a live website with videos and multiple users is simply not feasible on a VPS — or at least not financially worthwhile. VPS is great for small projects, testing, and development, but not sufficient for large-scale production. There should be at least two servers — one for the main website and another for backups.
If you have the knowledge, you can even use a third server dedicated to remote video processing. It’s a lot of work and money, but in the long run it saves costs, since owning your own storage is always better.
Yes, it can be expanded using AWS or similar services, but then you’re handing over your data to someone else — which, in my case, I refuse to do.
We all know times are tough, and user data is the most important thing you must protect. I'm not encouraging anyone to do anything and I don't mean it badly, I just came to this realization through time and suffering with VPS.
-
- · banister
- ·
You summed it up well, Pavel S. Good to hear from you, wherever you are today.
Under the best conditions, the shared server might be limited to videos no longer than a minute or so. Still, that would be better than nothing at all.
One other detail regarding video for the new UNA Admin to consider is the massive size which the backup files will eventually reach. Thus to move backup copies off to other safe locations will become increasingly time-consuming. A fast connection will be required.
For those interested in remote storage, Wasabi is a good platform and much cheaper than AWS. As for the remote processing on a separate instance of UNA, a detailed guide would be nice. I attempted it but could not get my remote server to connect.
-
- · PavelS
-
·
In reply to banister
- ·
These are things that guys have been dealing with long before us. There are plenty of posts here on this topic.
I learned from them myself and they helped me a lot to understand how to do what and where. Unfortunately, no one has made a specific procedure and instructions yet. I think that's how they keep their "know how" :)
https://unacms.com/d/remote-storage-1708
https://unacms.com/d/remote-storage-on-dedicated-server
https://unacms.com/d/serious-problem-with-urls-and-files-in-the
-
-
·
Alex T⚜️
- ·
in UNA it's already possible to set threads limit (-threads param), all you need is put something like this into your inc/header.inc.php
define('BX_SYSTEM_FFMPEG_THREAD', 2); // 2 threads limit -
·
Alex T⚜️
-
-
·
LeonidS
-
·
In reply to banister
- ·
Hello @banister !
As @Alex T⚜️ mentioned about the threads solution, but as I remember you already saw it here https://unacms.com/d/video-transcoding-solution-on-shared . Could you please share what is not good with this way for you?
-
·
LeonidS
-
- · OneEagle
-
·
In reply to Alex T⚜️
- ·
Hi @Alex T⚜️ , Great to know that. How many threads are used by default without the threads limit setting above? Also what would be the Pros and Cons of setting it to '1', from a video conversion and server load perspective?
-
- · Romulus
- ·
If you’re using Docker, it’s much easier to handle.
Just create a dedicated container for video processing and limit its CPU and RAM. For example:
# ----------------------------------------------------------------------------------# # # # Copyright (C) 2009 - 2025 Coozila! Licensed under the MIT License. # # Coozila! Team lab@coozila.com # # # # ----------------------------------------------------------------------------------# # ----------------------------------------------------------------------------------# # STACK NETWORK ---------------------------------------------------------------# networks: # Private network for application services --------------------------------# una_private_network: # # SSH command to create the Docker network: # docker network create --driver bridge una_private_network --subnet=172.16.0.0/16 # external: true # ------------------------------------------------------------------------------# # Private network for application services --------------------------------# una_private_proxy_network: # # SSH command to create the Docker network: # docker network create --driver bridge una_private_proxy_network --subnet=172.16.0.0/16 # external: true # UNA APPS --------------------------------------------------------------------# caddy-reverse-proxy: # ----------------------------------------------------------------------------------# nginx-una-proxy: # ----------------------------------------------------------------------------------# nginx-video-proxy: # ----------------------------------------------------------------------------------# una: # ----------------------------------------------------------------------------------# una-db: # ----------------------------------------------------------------------------------# una-cron: # ----------------------------------------------------------------------------------# una-meet # ----------------------------------------------------------------------------------# una-messenger: # ----------------------------------------------------------------------------------# memcached-cluster: # ----------------------------------------------------------------------------------# elasticsearch-cluster # ----------------------------------------------------------------------------------# una-video: image: una/una-video:${UNA_VERSION}-${PHP_VERSION} container_name: una.video.${UNA_VERSION}-${PHP_VERSION} restart: always hostname: localhost env_file: - ../../.env build: context: ../../apps/${UNA_VERSION} dockerfile: ../../compose/una-video/${PHP_VERSION}/Dockerfile deploy: resources: # # Add limit for resource usage (CPU / RAM) # limits: cpus: '2' memory: 8G volumes: - ../../compose/una-video/${PHP_VERSION}/php.ini:/usr/local/etc/php/php.ini - ../../compose/una-video/${PHP_VERSION}/docker.conf:/usr/local/etc/php-fpm.d/docker.conf - ../../compose/una-video/${PHP_VERSION}/www.conf.default:/usr/local/etc/php-fpm.d/www.conf.default - ../../compose/una-video/${PHP_VERSION}/zz-docker.conf:/usr/local/etc/php-fpm.d/zz-docker.conf - ../../compose/una-video/${PHP_VERSION}/www.conf:/usr/local/etc/php-fpm.d/www.conf - ../../apps/${APP_VERSION}:/opt/una:Z - /etc/localtime:/etc/localtime:ro # # Add custom header.inc.php to your container # This will overwrite the main una/inc/header.inc.php inside the video container # - ../../compose/una-video/inc/header.inc.php:/opt/una/inc/header.inc.php:Z # # You can also overwrite other files here as needed, depending on your requirements # #- ../../compose/una-video/custom_file.php:/opt/una/custom_file.php:Z networks: - una_private_network - una_private_proxy_network extra_hosts: # # Add extra host entries for internal resolution # - "host.docker.internal:host-gateway" - "${LOCAL_LISTEN_ADDR:-127.0.0.1}:host-gateway" # # Add extra service entries for internal resolution # - "${LOCAL_LISTEN_ADDR:-127.0.0.1}:${UNA_VIDEO_HOSTNAME:-www.video.com}" - "${NETWORK_LISTEN_ADDR:-172.16.0.1}:${UNA_VIDEO_HOSTNAME:-www.video.com}" # ----------------------------------------------------------------------------------#This way, all heavy video processing tasks run in an isolated UNA Video Container, without affecting the main UNA instance. It also ensures that your primary container remains fast and responsive, without being slowed down by video processing workloads.
Note:
This is just an example.
To make it fully functional, you need to configure all required files separately, set up a proper
.envfile, and update yourinc/header.inc.phpto route all video processing tasks exclusively to this container.In practice, you will have a clone of your main site container with a few files modified specifically for video processing, running on the same main
unafolder on disk./main-una/ <-- Project root, where docker-compose.yml is located ├── docker-compose.yml <-- Docker Compose file ├── .env <-- ENV file ├── apps/ │ └── una/ <-- Main UNA application code │ ├── inc/ │ │ └── header.inc.php <-- Original header (untouched) │ └── ... <-- Other UNA files ├── compose/ │ └── una-video/ │ └── php8.3/ │ ├── php.ini <-- Custom PHP config for video container │ ├── docker.conf <-- PHP-FPM config for video container │ ├── www.conf.default <-- Default config for video container │ ├── zz-docker.conf <-- Additional config for video container │ └── www.conf <-- Overwrite default www.conf │ └── inc/ │ └── header.inc.php <-- Modified header for video container └── ...This instance should not be accessible from the internet; set up a proxy only within your private network.
By running
docker compose up -d --build, a customized image for this container will be created, and the container will then run in the background together with your other containers.⚠️ IMPORTANT NOTICE
🚨 These commands and configuration changes are for informational or development purposes only.
💾 They DO NOT represent an official production setup guide.
⚙️ Run them ONLY if you fully understand what they do.
❗ Use at your own risk – adjust values and configuration to your environment.
👉 This example is intended for advanced users only.
💬 Need Help?
For inquiries or assistance, contact us via private message to order the Professional UNA CMS Installation & Server Setup for self-hosted sites. 🔗 https://unacms.com/view-product/coozila-small-business-una-cms
-
-
·
Alex T⚜️
-
·
In reply to OneEagle
- ·
It varies depending on number of CPU cores/threads and the codec used. Setting it to 1 may cause longer encoding time, but less CPU load in some situations.
-
·
Alex T⚜️
-
- · OneEagle
-
·
In reply to Alex T⚜️
- ·
Got it! Thanks