When I originally stated You shouldn’t get flickering if your render time is longer than the refresh time I should have clarified this was if your window size was constant.
Flickering is not quite ‘unavoidable’ since the OS/Window Manager/Driver may not exhibit this (it could for example rescale the content). Additionally I would not describe what I’ve seen as flickering, but this is somewhat subjective.
glfwSwapInterval(1) does not guarantee that the rendering will take one frame - it requests that the buffer swap does not occur immediately on render completion but when the next display refresh occurs. So with 60Hz refresh if your rendering takes longer than 1/60s (~16ms) then you get the buffer swapping at the next refresh time of 2/60s or 30Hz. However, when running in a window some OS/Window Manager/Driver combinations do not honor refresh rate requests.
If your rendering is slower than your refresh rate then you will have frames during resizing where the window size is not equal to the last rendered framebuffer size, which will potentially produce visual issues. To resolve these you need your rendering to be faster than the refresh rate to start with, at which point multithreading the rendering and event loop may help reduce the residual issues which remain due to input timing.
In my case I simply ignore this issue - if the user is resizing or moving the window they are not interacting with the content so I don’t worry about it. For fullscreen OpenGL apps this obviously also isn’t an issue.