DEV Community

AsyncMonk
AsyncMonk

Posted on

Should a small web app serve H.265? I did the byte math on two 1080p clips

Every few months someone tells me my two small tool sites should serve H.265 because it is "half the size". I ran the numbers on two 1080p clips first, and for a small web app my answer is no, not as a switch. At the same preset H.265 came out 19 to 30% smaller, which is a real saving per view. But I can't drop the H.264 copy, so storage grows by roughly three quarters, and the saving only shows up on views that actually get the H.265 file. So H.265 goes in as an optional second copy, H.264 stays the default, and whether a given clip deserves the copy comes down to one number per clip: how many views it takes to pay the copy back.

What I measured and on what

I used ImgIng (https://imging.ai/), a browser video compressor, for the encodes, on an Apple M4 Mac with macOS 26.5 and Chromium 149 on 2026-10-19, each job run once. The first clip is Isak Zvegelj's "Ljubljana Street Country Guitar Performance" from Wikimedia Commons (CC BY 3.0), trimmed to 60 seconds and re-encoded at a bitrate typical of phones, so it isn't straight off a phone. The second is a 60-second lecture-style screen recording I generated frame by frame, so it is cleaner and stiller than a real one. I used two presets, "HD balanced" (1080p, up to 30 fps) and "smallest size" (1080×608, 24 fps), and scored quality with ffmpeg's libvmaf against the source.

The saving per view is real but you pay it back in storage

MB here is a million bytes. "Views to break even" is how many H.265 fetches it takes before the bytes saved equal the bytes the extra copy occupies.

Clip, preset H.264 H.265 Saved per view Extra storage Views to break even
Guitar, HD balanced 57.16 MB 46.13 MB 11.03 MB +80.7% 4.2
Guitar, smallest size 10.49 MB 7.85 MB 2.64 MB +74.9% 3.0
Screen, HD balanced 9.36 MB 6.58 MB 2.78 MB +70.3% 2.4
Screen, smallest size 10.05 MB 7.73 MB 2.31 MB +77.0% 3.3

Quality held up at the HD preset, VMAF 96.67 against 97.16 on the guitar clip and 98.42 against 98.03 on the screen recording. That break-even column is bytes, not money. Storage is billed monthly and egress per view, so plug in your provider's prices. On my sites most clips get a handful of plays and then nothing, which is the part of the table where H.265 barely earns its keep. My cat, who is named Server, has watched more of my demo videos than most of my users.

The table also flatters H.265, because it assumes every view gets the H.265 file. If only some share of visitors can play it, the break-even grows by one over that share. At half the visitors, the guitar clip at the HD preset needs about 8.4 views and the screen recording about 4.7. I don't know that share for my sites. Chromium 149, Chrome 155, Firefox 151 and a macOS WebKit 26.5 build all showed picture on that Mac, but I haven't tested Windows, Android, iPhone Safari or in-app browsers, and those are most of my traffic. The smallest-size rows say something else too. Once a clip is already squeezed hard, the H.265 copy saves only 2.3 to 2.6 MB per view, so there's less to win per view in the first place.

Making the copy is a one-time cost

The copy also has to be made once per clip. In the browser that only works where a hardware HEVC encoder answers. On that Mac VideoEncoder.isConfigSupported said yes to HEVC Main in Chromium 149 and Chrome 155 and no in Firefox 151, and with hardware video encoding switched off ImgIng offered no H.265 path for an H.264 source at all. So on my sites it's a server job. HandBrake's "Fast 1080p30" preset with only the encoder swapped to x265 took 52.4 seconds on the guitar clip against 24.1 for x264, and 17.0 against 7.7 on the screen recording. That's about 2.2 times the encode time on this M4, paid once, which matters less than the storage that follows it every month. I'd expect a similar ratio on a rented VPS, but I haven't checked.

What I'm doing on my own sites

Playback is the other reason H.264 stays. A stripped-down Chromium build played the H.265 file with no picture and no error, though its canPlayType answered with an empty string for HEVC. So H.264 is the only rendition every clip must have. A clip gets an H.265 copy only after it has been played more often than its break-even number, scaled up for the visitors who can't play H.265, encoded on the server in a quiet hour, never promised to users as something their browser will produce. The page offers both sources, H.265 first, and calls canPlayType before choosing, so a browser that answers with an empty string never sees the HEVC file. Before switching any of this on I'll run canPlayType on a cheap Windows laptop and an Android phone, because those are the machines my visitors actually have and the ones I haven't tested yet.

Top comments (0)