Profiler changes game performance when open, strange behavior, Heisenbug

Godot version: 4.5.1

Renderer: GL Compatibility (gl_compatibility)
OS: Windows 11

The Problem

My 2D side-scroller test scene runs with periodic frame time spikes.
The lows drop to ~20 FPS, with frame process time hitting 40+ms every
few seconds — even when I’m just jumping around with no enemies,
bullets, or particles on screen.

But here’s the strange part: the moment I open Godot’s Debugger →
Profiler tab and run the scene, the problem vanishes completely
.
Smooth 160+ FPS, no spikes. Close the Profiler — spikes return.

Main Suspicion

I suspect the root cause is calling Performance.get_monitor() inside
_physics_process() without the Profiler active. My hypothesis is:

  • When the Profiler is closed, Performance.get_monitor() hits a
    code path that has unexpected overhead — perhaps locking, string
    lookup, or a slow property query.

  • When the Profiler is open, the engine internally hooks the same
    monitors into its own sampling system, which changes the execution
    path and eliminates the overhead.

This is a classic Heisenbug: any attempt to observe the performance
changes the performance itself. The Profiler makes the problem
disappear, so I can’t use it to diagnose the cause. Any custom
GDScript that reads Performance.get_monitor() inside _physics_process()
also alters the frame timing, making it impossible to get a clean
measurement of the “uninstrumented” state.

Project Settings

renderer/rendering_method=“gl_compatibility”
settings/stdout/print_fps=true
window/stretch/mode=“canvas_items”
window/stretch/scale=3.0

No explicit application/run/max_fps or vsync override is set.

My Questions

  1. Does the Godot engine behave differently depending on whether the Profiler is open?

  2. Is GL Compatibility on Windows known to have similar frame-
    synchronization quirks that the Profiler masks?

  3. How can I reliably monitor FPS without opening the Profiler,
    without calling Performance.get_monitor() in GDScript, and when
    settings/stdout/print_fps=true is too low-frequency to catch
    intermittent spikes?