To cap the framerate, the game sleeps and integer amount of milliseconds. For a frame to render,1000 / cl_maxfps->valuemilliseconds have to have passed since the last frame. This is an integer division where everything after the comma is chopped off after the calculation. It works pretty well for low framerates because you don't notice the chop-off there, but for high framerates you come to the point where the integer division becomes noticeable. Bascially, 1000/cl_maxfps->value evaluates to "3" for all values from 251 to 333, so the game always sleeps 3 milliseconds there, which always gives you the same framerate.You could try using cl_sleep to cap the framerate, but I guess this will get you the same issue. Jitspoe could probably fix that pretty easily for the next build by using microseconds there instead of milliseconds, but then again, you can never know how long it takes for the next build to be released
For now, I guess the easiest way is to use an external tool.
Edit: The effect gets even worse for higher cl_maxfps values: 334 to 500 is the same, 501 to 1000 is the same and from 1001 on its no limit at all (or, better: no limit other than the forced 1ms frametime that always happens)
Edit 2: I missed that the cvar's value is a float which leads to floating point arithmetic, so my explanation above is wrong. The correct answer is related though: The game keeps track of how much time has passed since the last frame was rendered with an integer variable counting the milliseconds since the last frame. This counter has to go above
1000 / cl_maxfps->value
in order to render a new frame. And here, it does not matter whether you want the time passed to go above 3,01 (maxfps 333) or above 3,99 (maxfps 251). The condition will only be met after a 4msec sleep, so you'll always get the same framerate for any maxfps value between these two values. The first edit should still be correct though.