Hardware encoding moves the work from the processor to a dedicated chip. The speed difference is large enough that it changes what is possible, and it is not free.
What you give up
A hardware encoder produces a larger file at the same visible quality than libx264 does. The gap varies by generation and content, and it is not subtle.
It also exposes far fewer controls. The tuning that software encoders offer, presets, psychovisual options, rate control detail, mostly does not exist.
So the trade is: much less time now, somewhat more bandwidth forever. Which side wins depends entirely on how often the file is served.
Find out what you have first
Do not copy a command from anywhere until you know what this machine supports.
ffmpeg -hide_banner -encoders | grep -Ei 'nvenc|qsv|vaapi|videotoolbox' ffmpeg -hide_banner -hwaccels
An empty result means your FFmpeg build has no hardware encoders compiled in, which is common on distribution packages and is a separate problem from whether the hardware exists.
On shared hosting there is no graphics hardware to reach, and there will not be. This is a virtual or dedicated server topic. There is more on the boundary in what you can and cannot do with FFmpeg on shared hosting.
NVENC, on NVIDIA hardware
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p5 -cq 23 -c:a copy out.mp4
Note -cq rather than -crf. The scales are not the same, and the number that looked right in software will not look right here.
To decode on the card as well, so the frames never travel back to system memory:
ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 \ -c:v h264_nvenc -preset p5 -cq 23 -c:a copy out.mp4
That second form is substantially faster and substantially more fragile: any filter that expects frames in system memory will fail, because the frames are not there. Adding a scale or an overlay to a fully accelerated pipeline requires the hardware versions of those filters.
VAAPI, on Intel and AMD
ffmpeg -vaapi_device /dev/dri/renderD128 -i input.mp4 \ -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 24 -c:a copy out.mp4
The format=nv12,hwupload is not decoration. VAAPI needs frames in a pixel format it accepts, uploaded to the device, and leaving it out produces an error that does not mention either.
If /dev/dri/renderD128 does not exist, there is no accessible device, which inside a container usually means it was not passed through rather than that it is missing.
Where the speed actually goes
People enable hardware acceleration and see a fraction of the improvement they expected, almost always for one of two reasons.
Filters in the middle. If frames decode on the card, come back to system memory for a scale, and return for encoding, the transfers cost more than the filter saves. Either keep the whole chain on the device or accept software decoding.
The bottleneck was elsewhere. If the job was reading from slow storage or the source needed heavy filtering, the encoder was never the constraint. Time a plain software run first so you know what you are comparing against.
When to use which
Live streaming. Hardware, without hesitation. Encoding must keep up with real time, and file size is not being stored.
A queue of user uploads. Usually hardware. Throughput is the constraint, and an upload processed in thirty seconds instead of five minutes changes the product. Handling video uploads from a web application goes into the queue around it.
A library served thousands of times. Software. The size penalty is charged on every view, and the encode happens once. Choosing a video codec goes over the same reasoning applied to the codec itself.
Measure before deciding. Encode one representative file both ways, compare the durations and the resulting sizes, and the answer for your content will be obvious. Performance optimisation explains the rest of the levers.
Confirm the device is actually being used
A command that names a hardware encoder can silently fall back to software, and the only visible difference is the speed.
ffmpeg -hide_banner -encoders | grep -E 'nvenc|vaapi|qsv' ls -la /dev/dri/ 2>/dev/null nvidia-smi 2>/dev/null | head -12
Watch the utilisation figure while a job runs. If it stays near zero while the encode proceeds, the work is happening on the processor regardless of what the command asked for.
Inside a container the device has to be passed through explicitly, and its absence produces exactly this: a command that runs, completes, and used none of the hardware it named.
Measure the actual gain on your own material
Hardware encoding is dramatically faster on some content and barely different on others, and the only way to know is to compare.
time ffmpeg -nostdin -i sample.mp4 -c:v libx264 -crf 23 -preset medium /tmp/cpu.mp4 time ffmpeg -nostdin -i sample.mp4 -c:v h264_nvenc -cq 23 /tmp/gpu.mp4 ls -la /tmp/cpu.mp4 /tmp/gpu.mp4
Compare the times and the file sizes together. Hardware output is typically larger at equivalent quality, so a faster encode that produces a file a third bigger costs you in delivery what it saved in processing.
That trade is worth making for a live stream or a large queue, and rarely worth it for a library that will be downloaded many times. The decision follows from the numbers rather than from the technology. CRF, two pass and bitrate covers the quality comparison.
Watch the machine while the job runs
The clearest evidence of what is happening comes from looking at both processors during an encode.
nvidia-smi dmon -c 10 2>/dev/null top -b -n 3 | grep -i ffmpeg | head -3 vainfo 2>/dev/null | head -8
A hardware encode shows the device busy and the processor comparatively idle. A software fallback shows the opposite, and the command that requested hardware gave no warning about it.
Run this once when setting up a pipeline rather than trusting the command. Everything afterwards depends on it, and a fallback discovered later means every job since was slower than intended.
The quality settings do not transfer
A value that produces good results with a software encoder means something different on hardware, and copying it produces disappointment.
ffmpeg -i in.mp4 -c:v h264_nvenc -rc vbr -cq 23 -b:v 0 out.mp4 ffprobe -v error -show_entries format=size,bit_rate -of default=nw=1 out.mp4
The quality scale is separate, and the rate control mode has to be set explicitly or the encoder targets a bitrate rather than a quality level.
Compare file sizes at several settings on your own material and pick from the results rather than from a recommended number. Hardware encoders differ between generations, so a value that suited one card is not necessarily right on the next.