Syncthing not using multiple QUIC streams?

Hello.

I was curious how Syncthing actually uses QUIC and multiple QUIC streams, but I could not find any trace of clever uses of streams. In fact the listener code seems to ever only accept a single stream. Similarly there is only one stream opened ever.

Doesn’t this downgrade QUIC to basically TCP like semantics? What are the advantages of using QUIC this way?

Honestly, I would expect TCP to be much more tuned for this single-stream use case and even exhibit better performance than QUIC here. In contrast HTTP/3 seems to open a QUIC stream per request.

Indeed we use QUIC just like a worse TCP. It’s not clear to me what we’d gain by multiple streams, but perhaps it would be better somehow. You’re welcome to experiment and PR. :slight_smile:

Edit: thinking a little further I guess the gain could be that packet loss on one request wouldn’t hold up another, which would be advantageous. Taking advantage of it would require some re-plumbing of the protocol package though.

1 Like

I currently manage 3 distinct and separate networks within my company. They synchronize signage devices (advertising and videos), each one is on a passenger bus, and the link is made through 5ghz Wi-Fi when they return to base. In each base there is a miniserver with nextcloud and syncthing running below, where the new multimedia content is stored. I have always used TCP, but mikrotik (The whole network is based on mikrotik) works at least twice as powerful in utp/quic. I’m trying to migrate part of the fleet to QUIC and I can upload my results if you want. The fear is that the server only handles one quic connection at a time. There are hundreds of devices. And rarely is one connected at the same time.

This fear is unfounded.

There’s a draft PR on GitHub where I implememented multiple QUIC streams for Syncthing requests; both one stream per request, and just round robin:ing requests over ~64 streams or so. This should be better in principle, but I was unable to find any situation where it improved performance, and it’s a fair amount of code to accomplish it. We’ll see if it’s worth incorporating.

1 Like

Okay. I will perform my tests on a new closed network. I can allocate that fleet to quic. The buses carry a 128gb microsd, of which it uses approximately 56gb of mp4 content generally, which are rotated once a week.

The buses use WDS 5ghz with a single ip & mac. That is, they do not need to go back to base to update, an updated bus does it when it encounters others that have expired files.

1 Like

Would a link aggregation type setup benefit from the round-robin over multiple QUIC streams/connections? Also I wonder on high latency connections if this provides real benefit.

I’m looking to deploy this on very long international links. We are setting up in the next week or two and may do some experimenting. We are expecting much faster (and more reliable) transfer compared to FTP, but just have no idea what we’re going to get.

Because of the network topology it seems in early looks we are getting all QUIC connections, and no TCP connections, but it’s still early. This may be because of firewall (no port forwards) and holepunching. But I need to read a little more to understand if that’s what’s actually going on.

In the first case no, because all streams share the same UDP “connection” (protocol-address-port five tuple) so they all end up on the same physical link.

With latency and packet loss there could be an improvement and I was hoping for that, but in all my tests TCP was better anyway.

However the multiple-connection work I did (PR open) handles all of these things better.

Ok got it. I don’t know much about UDP but I thought the different UDP streams would have different source ports and the L3+L4 hashing would get different links. But since UDP (I guess?) expects replies from the other side presumably addressed to the source port I guess that doesn’t work.

Thanks for the reply.

To be fair, our quic-go version is lagging behind and I’d expect a significant performance boost once we can use GSO.