Repository navigation
Practical experience: overcoming a per-TCP-flow bandwidth limit with Aggligator #29
ReWoIf
started this conversation in
Show and tell
Replies: 2 comments
0 replies
|
Thanks for sharing this write-up and the measurements! To make this setup easier without needing separate proxy ports just to establish multiple links, I have added I also added a page on overcoming per-flow bandwidth limits to the website that references your report. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment


Uh oh!
There was an error while loading. Please reload this page.
I would like to share a practical use case for Aggligator that may be useful to other users.
## The problem
My ISP appeared to enforce a bandwidth limit of approximately 2.5 Mbps on each individual outgoing TCP flow.
This did not look like a total bandwidth limit on my connection. A single TCP transfer stayed close to 2.5 Mbps, while there was still much more available capacity on the line. I also tried using multiple application streams over the same TCP connection, but this did not improve the speed. The traffic was still carried by one outer TCP flow and remained subject to the same limitation.
## What helped
I used Aggligator to carry one logical connection over multiple independent TCP links.
In my setup, Aggligator received 16 separate local SOCKS5 paths. Each path could establish its own transport flow to the remote server. Aggligator then distributed the data across those links and presented one logical connection to the application.
The SOCKS5 layer was only a way to provide independent paths. The important part was that the paths resulted in separate outer TCP connections. This is different from opening more application streams inside one existing TCP connection.
With this setup, my measured outgoing throughput increased from approximately 2.5 Mbps to approximately 180 Mbps. That is roughly a 70-fold improvement under the same ISP connection.
I do not consider this a universal multiplier. The result depends on where the provider applies traffic shaping, the available capacity, latency, packet loss, the remote server, the number of links, and the overhead of the transport.
## The important distinction
The key difference was:
Therefore, simply increasing the number of threads or streams in an application is not necessarily equivalent to using independent transport links.
## Configuration that worked for me
I used 16 aggregated links. The following Aggligator configuration worked well for my workload:
These values should not be treated as universal recommendations. I arrived at them by testing throughput and stability in my own environment.
Larger buffers and queues can help keep high-latency links busy, but they also increase memory use and the amount of data that can be in flight. The right values depend on the bandwidth-delay product, packet loss, number of links, and number of simultaneous logical connections.
Sixteen links is also not a magic number. Fewer links may be sufficient in some networks, while additional links may only add overhead if the provider limits the total subscriber bandwidth rather than each individual flow.
Practical limitations
Aggligator is especially useful when the bottleneck is applied per connection. It cannot create additional capacity if the provider enforces a single aggregate limit for the entire subscriber line.
The links must be independent at the layer where the shaping occurs. Duplicating one already-limited tunnel does not automatically guarantee a speed increase.
Aggligator and agg-tunnel are primarily TCP-oriented. In my VPN setup, UDP traffic was carried through a UDP-over-TCP layer before being aggregated. This was useful for general traffic, but TCP retransmission and head-of-line blocking can add latency when packets are lost. I would therefore test gaming, voice, and other real-time traffic separately instead of assuming that a bulk-transfer configuration is optimal for them.
It is also important to measure upload and download independently. A provider may apply different policies in the two directions.
Conclusion
The main practical lesson from my setup is that Aggligator is not merely a way to add more application threads. Its important property is the ability to distribute one logical connection over multiple independent transport flows while handling ordering, acknowledgements, retransmission, and link failures.
For a connection affected by a per-TCP-flow bandwidth limit, this can make a very large difference. In my case, it changed the achievable upstream speed from approximately 2.5 Mbps to approximately 180 Mbps.
All reactions