Fixed Update runs only when required. It's run multiple times a frame to catch up to the current time, and it's skipped when ahead.
I like to look at this way: Fixed Update is fake
Fixed Update is run repeatedly until fixed time catches up with game time, and the result is displayed. This keeps the delta time a fixed length (resulting in consistent simulation1), at the cost of fixed time not perfectly aligning to real time.
For example, you could advance Fixed Update 1 / Time.fixedDeltaTime
times to move it forward by a second. That can be done in an instant, ignoring real time, and that's what Fixed Update is doing.
You can read Unity's version of this description in the Important Classes - Time section of the scripting manual.
You can use the timeline view of the Unity Profiler to see what is actually occuring in your frame.
FixedUpdate
isn't the only code running at this fixed rate.
You can see an expanded version of a frame in the Unity documentation: order of execution for event functions.
Don't think about Update and FixedUpdate as executing in parallel, because it is completely linear.
Background threads do work, including scheduling rendering, performing parallel tasks, and so on. But the execution of your Update
/FixedUpdate
code is linear.
Start at the top right dot, and follow the choices until the diagram exits.
FixedUpdate
Because FixedUpdate
is not guaranteed to run every frame, this makes it a very poor place to poll instantaneous input.
Time.maximumDeltaTime
bounds the number of times fixed update can run due to a this limit on the amount of time that can pass in one frame2.
This helps prevent a fixed update cascade, where the cost of running many fixed updates to catch up causes the frame time to rise, which in turn causes more fixed updates.
If you want to understand why variable time is complicated, Unity has written some complex blogs like fixing Time.deltaTime in Unity 2020.2 for smoother gameplay: What did it take?↩
This is a virtual time limit. The frame will still take the same amount of real time to run.↩