Almost every piece of compression advice you will find was written with camera footage in mind. Drop the resolution, raise the CRF, accept a little softness because nobody looks that closely at grass. Apply that to a screen recording and you get a file where the code is unreadable, the UI labels have turned to mush, and the size barely moved.
Screen capture breaks the assumptions. It is worth understanding how, because the fixes are almost the opposite of the usual ones.
What makes screen content unusual
Camera footage is noisy, soft at the edges, and never truly still. Even a locked-off tripod shot has sensor noise moving in every pixel, which is why grain is expensive and why encoders spend so much of their effort on it.
A screen recording is the opposite on every count. Long stretches are perfectly static, pixel for pixel, so the encoder can describe several seconds of a paused editor in almost no data at all. The content is synthetic: hard black-on-white edges, single-pixel strokes, glyph antialiasing, flat regions of exact colour. And when it does move, it moves in ways video codecs are bad at, because a page scroll shifts the entire frame by a non-integer number of pixels while the text inside it stays sharp.
The practical consequence is that the bitrate of a screen recording is wildly uneven. Ninety seconds of a static slide costs almost nothing. Four seconds of scrolling through a file costs more than a second of most camera footage. Averages mislead you here more than anywhere else.
Resolution is the thing you keep
This is the part that goes against the usual advice, so it is worth being precise about why.
When you downscale camera footage, you throw away detail that was soft to begin with. A blade of grass at 1080p becomes a slightly blurrier blade of grass at 720p and nobody can name what changed. When you downscale text, you are resampling glyph strokes that were one or two pixels wide. A one-pixel stroke does not become a smaller stroke, it becomes a grey smear, and the difference between l, 1 and I stops existing.
It gets worse with the specific numbers involved. 1920 to 1280 is a factor of 1.5, so every output pixel is a weighted blend of source pixels that do not line up with it. Halving to 960x540 at least samples cleanly, but 540 lines is not enough to carry a terminal font either.
There is a real arithmetic cost to keeping 1080p: 2,073,600 pixels per frame against 921,600 at 720p, so you are asking the encoder to describe more than twice as many. On camera footage that cost is what you pay to see detail. On screen content you are usually paying it to see anything, because below a threshold the text is not degraded, it is illegible, and an illegible tutorial is not a smaller file, it is a wasted one.
Keep the resolution. Find the savings somewhere else.
Frame rate is what to cut
Screen recorders default to 30 or 60 fps because they are built on the same pipelines as game capture. Almost nothing on a screen needs that.
A slide deck with the occasional transition is fine at 10 fps. A talk with a cursor moving around is fine at 15. A code walkthrough with scrolling is comfortable at 24 or 30. The only screen recordings that genuinely want 60 are ones demonstrating animation, scroll physics or input latency, where the smoothness is the subject.
Be honest about what this saves, because the internet routinely overstates it. Halving the frame rate does not halve the file. The frames you keep are further apart in time, so each one differs more from its predecessor and costs more to encode. In practice going from 60 to 30 tends to save meaningfully less than half, and going from 30 to 15 saves less again. It is still usually the largest single saving available on screen content, and unlike downscaling it costs you nothing you can read.
Cut it in the recorder if you can — that is the version of this advice that saves you bytes. If the recording already exists, the compressor has a frame rate row that drops frames on the way through, and it works slightly differently: the tool caps the bitrate rather than the quality, so thinning the frames does not shrink the file. It hands each frame that survives a larger share of the same budget instead, which is what makes a tight target size look clean on scrolling text.
Why red text on black smears
Nearly all delivery video is 4:2:0 chroma subsampled, meaning colour information is stored at half resolution horizontally and vertically while brightness is stored at full resolution. Human vision is far more sensitive to luminance detail than to colour detail, so for camera footage this is close to free, and it removes half the data before compression even starts.
Synthetic content is where the assumption breaks. Coloured text on a contrasting background, syntax highlighting in particular, has fine detail that lives entirely in the colour channels. Red keywords on a dark background are the classic case: they come back blurred and fringed while white text in the same frame is perfectly crisp. That is not the encoder failing or your bitrate being too low. It is 4:2:0 doing exactly what it says on the tin.
You can encode 4:4:4 with -pix_fmt yuv444p and the problem disappears, at the cost of a file that many players, most browsers and a fair number of hardware decoders will refuse. It is a reasonable choice for an archive and a poor one for anything you send to somebody. The practical mitigations are to raise the bitrate a little, or to use a theme with more luminance contrast in the first place, which is why so much technical video ends up on light backgrounds.
Settings worth starting from
These are starting points to encode and look at, not measurements. Screen content varies enormously with how much scrolling it contains, and the only way to know is to encode the busiest thirty seconds and judge it.
| Content | 1080p starting bitrate | Frame rate |
|---|---|---|
| Static slides, occasional transition | 300–600 kbps | 10–15 fps |
| Talking through a UI, cursor moving | 600–1,200 kbps | 15–24 fps |
| Code editor with scrolling | 1,500–3,000 kbps | 24–30 fps |
| App demo with animation and video | 3,000–5,000 kbps | 30 fps |
| Anything demonstrating smoothness | 5,000+ kbps | 60 fps |
A CRF encode is usually a better fit than a bitrate target here, because the content is so uneven that a fixed bitrate wastes bits on the static parts and starves the scrolling ones. CRF 20 to 23 holds small text well at 1080p. If there is no code or spreadsheet on screen — a slide deck, a talking head in the corner — 24 to 28 is fine and much smaller; the CRF guide has the rest of the scale.
A command that works
ffmpeg -i recording.mkv -c:v libx264 -crf 21 -preset slow -r 24 \
-pix_fmt yuv420p -c:a aac -b:a 64k -ac 1 -movflags +faststart out.mp4
-r 24 drops frames to reach the new rate. -preset slow is worth the wait on screen content specifically, because the long static stretches are where a thorough encoder finds its largest wins. The audio is mono at 64 kbps because a screen recording’s audio is one person talking into one microphone, and stereo at 128 is spending twice what that needs.
The input there is an MKV because that is what OBS writes by default, and it writes it for a good reason: an MKV survives a crash mid-recording where an MP4 usually does not. It also will not play in a browser or a chat embed, so the re-encode above is doing double duty, and if all you need is the container changed then remuxing an MKV takes seconds and touches nothing.
There is also -tune stillimage, which biases x264 toward preserving sharp detail. It is genuinely useful for a recording that is almost entirely static slides. For anything with real scrolling in it, leave it off and let the encoder use its normal motion handling.
Recording settings beat compression settings
The biggest wins are upstream of any of this.
Record at the display’s native resolution, and if the display is 4K, set the capture to 1080p rather than recording 4K and downscaling afterwards. Scaling a 4K desktop to 1080p resamples the text through the same blur described above; capturing at 1080p renders the text at 1080p and it stays sharp.
Close what does not need to be in the frame. Every extra panel is more detail for the encoder to carry and one more thing that changes when you did not want it to. If you can record a window rather than the whole desktop, do.
And record at a sane frame rate to begin with, since a real 24 fps capture is always better than 60 fps decimated to 24 after the fact.
Whatever you record, there is almost always dead footage at both ends: the seconds spent finding the right window, and the seconds spent reaching for the stop button. Cutting them is free in a way no compression setting is, and it does not need an editor: there are trim handles in the compressor, and only the range between them is encoded. In target-size mode the budget is divided by that range rather than by the original runtime, so the walkthrough gets the bits the fumbling was going to spend.
The privacy part
Screen recordings are the category where uploading to a compression service is most obviously a bad idea. They routinely contain a browser tab bar, an email notification arriving at the wrong moment, a file tree with client names in it, a terminal with a hostname, or an API key that was on screen for four frames.
Everything on this site runs FFmpeg compiled to WebAssembly inside your own browser tab, so nothing is transmitted anywhere. The trade is speed: WebAssembly is slower than native code, and if the browser cannot hand it SharedArrayBuffer it falls back to a single-threaded core that is slower still. For a long screen recording that is a real cost, and the FFmpeg comparison says plainly when the command line is the better tool. But for a ten-minute walkthrough of an internal dashboard, waiting a few extra minutes on your own machine is not much of a price.
If you are aiming at a specific ceiling rather than a quality level, the target-size pages take the number and solve the bitrate from your clip’s length.