Fail Faster

For a long time I have heard complaints that Xdebug, with its debugger enabled, slows down applications, even if there is no IDE listening.

I have never been able to reproduce this, as on Linux (and macOS), TCP connections to a localhost ports fail immediately if that port is not open.

Xdebug waits for up to 200ms when making a debug connection. This is configurable with the xdebug.connect_timeout_ms setting.

But if there is nothing listening, there should not be any delay, as it ought to be an immediate error.

I wrote a comment in an issue from 2024:

The error message ERR: Time-out connecting to debugging client, waited: 200 ms. indicates that your network stack doesn't immediately reject the connection if it can't be made. That's usually due to a (misconfigured) firewall.

It turns out, that it is not a firewall, but that Windows itself behaves bad here. Instead of failing immediately, it does retry sending TCP SYN packets to try to establish a connection. This is pointless on the local loopback interface, as network packets cannot get lost.

Through a post by Daniel Stenberg on Mastodon, I found out the cause, and a solution.

He explains how it affects curl's Happy Eyeballs algorithm in a blog post from 2024. Although Xdebug does not use Happy Eyeballs, the underlying problem is the same.

Last week, Marcel Jamin wrote to the curl mailing list, with a solution. This solution disables the retry mechanism to establish a connection. And in turn that means, that there is no longer a delay on Windows either.

I have today merged a pull request for Xdebug which implements this solution. The patch is part of the upcoming Xdebug 3.6 release.

Shortlink

This article has a short URL available: https://drck.me/fail-faster-kbh

Comments

@blog nice one

@blog I think it probably is a firewall issue really, unless Windows is ignoring the RST packets that tell it nothing is listening.

That's what happens on linux - the SYN is sent and gets an RST and that is reported as a connection failure with EPORTUNREACH but if you firewall loopback so it doesn't get the RST then you get the Windows behaviour of it retrying SYN packets.

There's nothing special about the loopback handling in linux.

Add Comment

Name:
Email:

Will not be posted. Please leave empty instead of filling in garbage though!
Comment:

Please follow the reStructured Text format. Do not use the comment form to report issues in software, use the relevant issue tracker. I will not answer them here.


All comments are moderated
Become a Patron!
Mastodon
GitHub
LinkedIn
RSS Feed
Flickr
YouTube
Vimeo
Email

My Amazon wishlist can be found here.

Human-Made Webring
previous | random | next

Life Line