Dev.to WebDev 🛠 Dev 👁 0 📖 5 min read

CRF 23 Gave Me 15 MB on One Clip and 30 MB on Another: "Compress by Quality" vs "Compress to a Size", Measured

Originally published on DEV.to — tested with VidSmaller. Most video compressors offer two ways to ask for a smaller file. One is "keep this quality" (a CRF number). The other is "make it this size" (a target in MB). The

CRF 23 Gave Me 15 MB on One Clip and 30 MB on Another: "Compress by Quality" vs "Compress to a Size", Measured

Originally published on DEV.to — tested with VidSmaller.

Most video compressors offer two ways to ask for a smaller file. One is "keep this quality" (a CRF number). The other is "make it this size" (a target in MB). They sound like two routes to the same place. They aren't, and the difference only shows up once you run both on more than one clip.

So I did: three 60-second 1080p clips from Blender's open movies, five real cloud compressions, every output downloaded and measured against the upload with ffmpeg's SSIM and PSNR filters.

The short version:

Clip (upload) CRF 23 ("quality") Target 20 MB ("size")
Tears of Steel, 101 MB 15.1 MB · SSIM 0.9897 18.7 MB · SSIM 0.9909
Sintel, 77.3 MB 30.2 MB · SSIM 0.9844 18.7 MB · SSIM 0.9764
Big Buck Bunny, 17.4 MB 16.3 MB (−6.1%) · SSIM 0.9914 not run

Same CRF, 2× different file sizes. Same target, identical sizes, different quality. That's the whole trade-off, and the rest of this post shows how to pick.

Disclosure: I build VidSmaller, the cloud compressor used for every run here. All numbers are from these runs; nothing is estimated unless I say so.

The setup

  • Clips (all CC BY 3.0, © Blender Foundation): a 60 s cut of Tears of Steel (live action + VFX, 1920×800, 106,098,955 bytes), a 60 s cut of Sintel (animation, 1920×818, 81,101,968 bytes) and a 60 s cut of Big Buck Bunny (animation, 1920×1080, 18,210,139 bytes — already a lean 2.4 Mbps file).
  • Tool: vidsmaller.com → Advanced Compression, H.264, speed "Faster (default)", MP4. Driven by a headless Chrome, signed in to my own account.
  • Measurement: stat for bytes, ffprobe for bitrate, the x264 settings string inside each output (it records rc=crf crf=23.0 or rc=2pass bitrate=…), and ffmpeg ssim + psnr against the exact file I uploaded.

One note on units before the numbers: the app shows sizes in binary megabytes. "18.7 MB" on the card is 19,624,758 bytes (18.7 MiB, 19.6 decimal MB). Either way it's under 20.

Step 1: Find the two modes

On the homepage compressor, switch to Advanced Compression and open Compression Method. "Target a video quality" is CRF mode; "Target a file size" is the size mode. (The other three — percentage, resolution, max bitrate — are out of scope here.)

VidSmaller Advanced Compression: the Compression Method menu with Target a file size, Target a video quality, percentage, resolution and max bitrate

The hint under the menu is the one-line version of this article: "Pick a file size for an exact ceiling, or a video quality to let the size follow."

Step 2: CRF 23 on the live-action clip

I loaded the 101 MB Tears of Steel cut, chose Target a video quality, and left CRF 23 · Recommended (default).

Tears of Steel 101 MB loaded, Target a video quality, CRF 23 selected, Estimated result 90.1 MB

Look at the line under the file name: Estimated result: 90.1 MB. Keep that number in mind.

Result card: 101 MB → 15.1 MB, −85.1%

101 MB → 15.1 MB (−85.1%). Video bitrate 1.97 Mbps, SSIM 0.9897, PSNR 46.26 dB. The x264 string confirms rc=crf crf=23.0.

The estimate was off by 6×. In quality mode nobody can know the size before encoding — that's the point of CRF — so treat the pre-run estimate as a placeholder. (In my three CRF runs it was 90.1, 68.9 and 15.5 MB, about 89% of each upload every time.)

Step 3: Same CRF 23 on the animated clip

Same settings, Sintel (77.3 MB on the card).

Sintel 77.3 MB loaded with CRF 23, Estimated result 68.9 MB

Result card: 77.3 MB → 30.2 MB, −60.9%

77.3 MB → 30.2 MB (−60.9%). Video bitrate 4.09 Mbps — more than double Tears of Steel's 1.97 Mbps, from a smaller upload. SSIM 0.9844, PSNR 43.77 dB.

This is what CRF means: "spend whatever bits this content needs to look like CRF 23". Sintel's sand, gravel and fast camera moves need more bits than Tears of Steel's dark interiors, so the file came out twice as big. Quality across the two clips stayed close (SSIM within 0.0053); size didn't.

Step 4: CRF 23 on a file that's already compressed

Big Buck Bunny's 60 s cut is only 17.4 MB (2.4 Mbps for 1080p30 — already lean).

Big Buck Bunny 17.4 MB loaded with CRF 23, Estimated result 15.5 MB

Recent compressions: big-buck-bunny 17.4 MB → 16.3 MB −6.1%, tears-of-steel 101 MB → 15.1 MB −85.1%

17.4 MB → 16.3 MB, just −6.1%. SSIM 0.9914. CRF has no idea what size you need; if the source is already near "CRF 23 quality", you get almost nothing back. If you need a phone clip under a hard limit, CRF can leave you above it.

Step 5: Target 20 MB on both big clips

Now the other mode. Target a file size, typed 20 in the MB box.

Tears of Steel with Target a file size, 20 MB typed, Estimated result 20.0 MB

Result card: 101 MB → 18.7 MB, −81.5%

Tears of Steel: 101 MB → 18.7 MB (−81.5%), rc=2pass bitrate=2463. SSIM 0.9909, PSNR 47.00 dB.

Sintel with Target a file size, 20 MB

Result card: 77.3 MB → 18.7 MB, −75.8%

Sintel: 77.3 MB → 18.7 MB (−75.8%), rc=2pass bitrate=2466. SSIM 0.9764, PSNR 41.38 dB.

Both landed at 18.7 MB (19,624,758 and 19,612,900 bytes) — a two-pass encode at ~2.46 Mbps video either way. The size held; the quality moved.

Step 6: Put the four numbers side by side

Chart: Tears of Steel CRF 23 15.1 MB SSIM 0.9897, target 20 18.7 MB SSIM 0.9909; Sintel CRF 23 30.2 MB SSIM 0.9844, target 20 18.7 MB SSIM 0.9764

Two things fall out:

  1. On Tears of Steel, the 20 MB target was more than the clip needed. It spent 24% more bytes than CRF 23 (18.7 vs 15.1 MB) for +0.0012 SSIM. If your limit is 20 MB, CRF 23 already fit with room to spare.
  2. On Sintel, the 20 MB target cost real quality. It's 38% smaller than CRF 23 (18.7 vs 30.2 MB), and SSIM drops from 0.9844 to 0.9764 (PSNR −2.4 dB).

What does that drop look like? Here's the worst frame of the Sintel size run (frame 1397, 0:58.2), cropped at 100%:

100% crop of Sintel frame 1397: upload, CRF 23 30.2 MB (frame SSIM 0.965), target 20 MB 18.7 MB (frame SSIM 0.934); gravel texture smoother in the 20 MB version

The gravel in the 20 MB version is visibly smoother and the shadow edges are softer. Fine on a phone in a chat, noticeable on a monitor. Most frames are much closer than this one.

So which one should you use?

Use "target a file size" when there's a hard number: a chat app's upload cap, an email attachment limit, a form that rejects anything over X MB. You'll always fit; the price is that busy footage gets softer. The Telegram, Slack and X/Twitter pages walk through each app's limits.

Use "target a video quality" (CRF) when there's no hard limit — archiving, a site you host yourself, a long meeting recording you just want lighter. You get consistent quality and the smallest file that delivers it. On easy content that can be much smaller than any target you'd have guessed (Tears of Steel: 15.1 MB without asking).

Check two things before trusting CRF on a deadline:

  • Is the source already lean? Big Buck Bunny only dropped 6.1%. If a 17 MB file must go under 15, CRF 23 won't do it — a size target will.
  • Does the result happen to fit? Run CRF first, and only switch to a size target if it comes out too big. That's what I'd do with a 4K phone clip.

If you want to go past the default, VidSmaller's CRF explainer covers what 18, 26 or 28 trade away.

Practical notes from the runs

  • Each run here was 1 credit (the button label said "Cost 1 credit"). A signed-out guest gets one compression (up to 200 MB / 3 min) — enough to try one mode on one clip. A free account adds one welcome credit (500 MB). Re-running this five-job comparison needs a pack (pricing: $3 for 50 credits).
  • Timing: click to "Your video is ready", including the upload, took 30–45 s for the runs I timed.
  • Surround audio: my first Sintel cut kept the film's 6-channel audio and was rejected with "This is not a readable video file". A stereo downmix of the same video went through, and the failed attempt's credit was refunded automatically. If you hit that message with a movie-style file, try stereo audio first.
  • Sintel was re-exported to fix that (x264 CRF 16, 10.8 Mbps), so its SSIM numbers are measured against that upload, not the original film master.

If you'd rather not upload at all, my other tool, videocompress.dev, does target-size compression inside the browser tab.

Credits: Tears of Steel (mango.blender.org), Sintel (durian.blender.org) and Big Buck Bunny (peach.blender.org) © Blender Foundation, CC BY 3.0.

Related: Before you pay for H.265: measured against a real H.264 encode (Hashnode) · Discord's 20 MB limit with one preset tap (Hashnode) · I typed 48, 18 and 9 MB into a video compressor (Medium)

— mengyuxuan

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.