Diagnosing Stutter in Godot 4: Physics Tick vs Render Frame Mismatch
When Godot 4 reports 60+ FPS but motion looks juddery, the culprit is often a physics‑tick versus render‑frame mismatch. This guide walks through the symptoms, diagnosis, and fixes – from enabling physics interpolation to cleaning up frame‑time spikes.
05 Oct 2026, 15:22 UTC

Recognizable Condition
In many Godot 4 projects you’ll see a game report 60+ FPS in the status bar, yet the camera or character motion feels jerky or “juddery”. The motion is not dropping frames – the frame‑time graph is flat – but the visual update is out of sync with the physics simulation. This is a classic physics‑tick versus rendering‑frame mismatch.
Root Causes
| Cause | Typical Symptom | Quick Check |
|---|---|---|
| Physics/Render rate mismatch | Consistent FPS but uneven motion | Compare Engine.get_physics_ticks_per_second() to your display refresh |
Node moved in _process() while physics body updates in _physics_process() | Camera or sprite jumps each frame | Locate the motion code in the scene tree |
| V‑Sync or window mode mis‑configured | Judder appears only on certain displays | Toggle V‑Sync and test on 60 Hz vs. 144 Hz screens |
| Frame‑time spikes (GC, shader compile, synchronous loads) | Sudden spikes on the frame‑time graph | Open the Debugger → Profiler → Frame Time |
Diagnostic Checklist
- Open the Frame‑Time Graph
In the editor, go toDebugger → Profiler → Frame Time. A flat line that steps in equal increments indicates a rate mismatch; jagged spikes point to actual frame stalls. - Verify FPS and Physics Tick Rate
In a script (e.g., a singleton), print the values:var fps = Engine.get_frames_per_second() var pps = Engine.get_physics_ticks_per_second() print("FPS:", fps, "| Physics Ticks:", pps)Typical Godot 4 default:
pps = 60. If you’re running on a 144 Hz display,ppsfpsmismatches will cause judder. - Check Node Update Methods
Inspect the scripts that move the camera or animated sprite. If the node’sglobal_transformis set in_process()while the physics body is updated in_physics_process(), the transforms will be updated at different rates. - Toggle V‑Sync and FPS Cap
InProject Settings → Window → Rendering → V-Sync, enable and disable V‑Sync. Also try settingProject Settings → Display → FPS → Max FPSto 60. Observe whether the judder pattern changes. - Inspect for Frame‑Time Spikes
If the frame‑time graph shows irregular spikes, run the built‑inProfilerto identify GC, shader compilation, or synchronous resource loads on those frames.
Targeted Fixes
1. Enable Physics Interpolation (Preferred)
Godot 4 includes a project setting that interpolates node transforms between fixed physics ticks at render time:
Project Settings → Physics → Common → Physics Interpolation (boolean)
Turn it on. The engine will automatically blend the last two physics states when drawing each frame, smoothing motion without changing the physics tick rate.
When using interpolation, make sure you do not manually set global_transform in _process() or any other per‑render‑frame method – that bypasses the interpolation system and re‑introduces jitter.
2. Align Physics and Render Rates
For high‑refresh displays, you can raise physics_ticks_per_second to match the display rate (e.g., 120 or 144). This is more CPU‑heavy and can affect physics stability, so use it only if interpolation is unsuitable:
Project Settings → Physics → Common → Physics Ticks Per Second
After changing, verify that Engine.get_physics_ticks_per_second() matches the new value.
3. Resolve V‑Sync Issues
On some monitors, V‑Sync can lock the frame rate to the refresh cycle, causing a visible pulse each frame. Try disabling V‑Sync if you see judder only when it’s enabled.
4. Eliminate Frame‑Time Spikes
- Pre‑compile shaders:
Project Settings → Rendering → Shaders → Pre‑compile Shaders. - Pre‑load resources in
_ready()or viaResourceLoader.load_interactive(). - Avoid per‑frame allocations; reuse objects or use object pools.
- Defer node creation to a later frame or use a dedicated “spawner” node.
Escalation Criteria
If after enabling physics interpolation, aligning tick rates, and cleaning up allocations the judder persists, it may be a deeper engine issue.
- Confirm that the problem reproduces on a minimal scene: a single
RigidBody2Dmoving under a camera that follows it. - Run the built‑in
Profilerand capture a trace of the problematic frames. - Check the Godot 4 release notes for any known interpolation bugs in your minor version.
- File an issue on the official Godot GitHub repo, attaching the minimal project and profiler data.
Practical Tips
- Use
Engine.is_physics_interpolation_enabled()to programmatically verify the setting at runtime. - When debugging, temporarily disable interpolation and observe the change in motion; a disappearance of judder confirms interpolation is the culprit.
- Remember that enabling interpolation introduces a one‑tick visual latency (≈16 ms on a 60 Hz tick), which may be noticeable in competitive games.
- For projects that require both high physics fidelity and smooth rendering, consider a hybrid approach: keep
pps = 60, enable interpolation, and use a highermax_fpsto allow the renderer to stay ahead of physics. - Always test on the target hardware and monitor configuration; a 60 Hz display will behave differently from a 144 Hz one.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.