HTTP/3 is everywhere but nowhere
httptoolkit.com
httptoolkit.com
> This seems contradictory. What's going on?
IT administrators and DevOps engineers such as myself typically terminate HTTP/3 connections at the load balancer, terminate SSL, then pass back HTTP 1.1 (_maybe_ 2 if the service is GRPC or GraphQL) to the backing service. This is way easier to administer and debug, and is supported by most reverse proxies. As such, there's not much need for HTTP/3 in server side languages like Golang and Python, as HTTP/1.1 is almost always available (and faster and easier to debug!) in the datacenter anyways.
HTTP/3 and IPv6 are mobile centric technologies that are not well suited for the datacenter. They really shine on ephemeral spotty connections, but add a lot of overhead in a scenario where most connections between machines are static, gigabit, low-latency connections.
It's always a headache to learn that some container orchestration system doesn't support IPv6. Or an http client. Or a DNS resolver. Or whatever.
Not to mention the supreme annoyance I have that, to this day, my ISP still does not have IPv6 addressing available.
"Everywhere but nowhere" is sorta how I'd describe ipv6. Most hardware and lower-level software supports it, so obviously it wasn't impossible to support a new protocol, but it's not being used.
Exactly. I would love to have seen the world in which that happened, and where all the other parts of IPv6 were independently proposed (and likely many of them rejected as unwanted).
There were also some small things. And routers often having bad defaults for v6, which btw, would not even be a concern if they left the big thing alone.
Sure, "make the addresses bigger" would have required providing DHCPv6, DNS AAAA records, and various other protocol updates for protocols that embedded IP addresses. And making changes to the protocol header at the same time (e.g. removing the redundant checksum) were also a good idea.
It didn't require pushing SLAAC instead of DHCP.
It didn't require recommending (though fortunately not requiring) IPsec for all IPv6 stacks.
It didn't require changing the address syntax to use colons, causing pain for all protocols that used `IP:port` or similar.
It didn't require mandating link-local addresses for every interface.
It didn't require adding a mandatory address-collision-detection mechanism.
And I'm sure I'm forgetting a few.
It didn't require the Ruby Goldberg "on link" network mechanism.
It didn't require multicast instead of broadcasts for local network discovery.
It didn't require using DNS config (of all things) to specify V4/V6 priority.
It didn't require adding a "flow label" that is nobody to this day knows how to use properly.
The list of fails is ridiculous.
Disconnect your phone from Wi-Fi and visit https://ifconfig.co/ . If you're a Verizon customer, it's probably going to show you an IPv6 address. It's huge, right now, today.
One of the world's largest ISPs, Vodafone, is yet to support IPv6.
What Google supports is irrelevant if your ISP can't handle the traffic.
Vodafone's network is reported to handle around 20% of the world's traffic. It's not a random ISP. It's network does not support IPv6. It is how a big chunk of all internet users experience the internet. Claiming it doesn't matter in a discussion over IPv6 adoption rate is ludicrous.
Especially since getaddrinfo was ported over from more streams/OSI oriented stacks pretty late, precisely because BSD Sockets required separate path for every protocol.
On hw side, by mid-1990s even changing one routing-important field would mean possibly a new generation of ASICs needed with more capabilities.
Essentially, once you agree to break one field, the costs are so big why not try fixing other parts? Especially given that IETF has rejected an already implemented solution of just going with OSI for layer 3.
And btw, what I suggested would actually work without userspace code changes until you want to start subdividing the /32s. Cause v4 addresses would've still been valid in v6.
Next step would be upgrading all those parts like DNS, DHCP, etc to accept the 128-bit addrs, which again can be done in isolation. Then finally, ISPs or home routers can start handing out longer addresses like 1.1.1.1.2.
If it means upgrading every program, then your plan works but it's the same as how things work today. You're telling people to do a thing, and they aren't bothering. The "simple" step isn't simple at all.
If it doesn't mean upgrading every program, then your rollout fails on the last step. You start handing out longer addresses and legacy programs can't access them.
For a good decade a lot of software had to be slowly patched in every place that made a socket to add v6 support, and sometimes multiple times because getaddrinfo didn't reach everyone early enough.
> results in hardcoding protocol details in application code
Are you suggesting that this could have been implemented a different way? Example: IP could be negotiated to upgrade from v4 to v6? I am curious about your ideas.Of course, code that operates on packets, in the TCP/IP stack of the OS would have still needed to be rewritten. But that is far less code than "every application that opens a socket".
Of course, this only applies to code that uses IPs only to open connections. There's lots of application code that does more things with IPs, such as parsing, displaying, validating etc. All of this code would still need to be rewritten to accept IPv6 addresses (and its much more complex string representations), that part is inevitable.
While the sockaddr struct allowed to to abstractly handle v4/v6 socket connections, there wasn’t a clean way to do all of that additional stuff and IP address logic leaked into all kinds of software where you wouldn’t first expect it.
Something as simple as a web app that needs to inspect proxy headers would even have it.
It also didn’t help that it became practice to explicitly not trust the addr resolution offered by the sockets API because it would do unexpected things like resolving something that looked like an integer to a uint32 and then a 4 byte V4 addr.
It isn't about upgrading one protocol to another but about having the operating system abstract away the different protocols from the application.
Resolve the A and AAAA records, and try to connect to them at the same time. The first successful connection wins (maaaaybe with a slight bias for IPv6).
This would have required an API that uses the host name and folds the DNS resolution and connection into one call. Instead, the BSD socket API remained at the "network assembly" level with the `sockaddr_in/sockaddr_in6` structures used for address information.
For the examples I am going to use the typical "HTTP to example.com" case.
Some OSI-focused stacks provided high level abstraction that gave you a socket already set for listening or connected to another service, based on combination of "host name", "service name", and "service type".
You'd use something like
connect("example.com", "http", SVC_STREAM_GRACEFUL_CLOSE) // using OSI-like name for the kind of service TCP provides
and as far as application is concerned, it does not need to know if it's ipv4, ipv6, X.25, or a direct serial connection (OSI concept of separating "service" from "protocol" is really a great idea that got lost)Similar approach was done in Plan 9 (and thus everyone who uses Go is going to see something similar) with the dial API:
dial("example.com!http",0,0,0)
As part of IPv6 effort an attempt at providing something similar with BSD Sockets was made, namely getaddrinfo which gives back information to be fed to socket/bind/connect calls - but for a long time people still learnt from old material which had them manually fill in socket parameters without GAI so adoption was slowed down.When machine 2 receives a packet from 1.1.1.1 at 2.2.2.2 it sends a ipv6 ping-like packet to the ipv4-mapped address ::ffff:1.1.1.1 saying something like "hey you can also contact me at 22::22 and if machine 1 undertands then it can try to use the new address for the following packets.
I can see how it would be hard to secure this operation.
Can you elaborate? Here, or with links? What kinds of overhead and cruft?
* You can't fragment packets.
* The redundant checksum header was removed.
* No more private addressing (unless you're a glutton for punishment).
* No more NAT (see above).
* Simpler routing.
* Doesn't require DHCP.
It benefits hugely from the lessons learned with IPv4.
Private addressing is still needed with IPv6, it's a crucial part of how address allocation works, and it's the only way to reliably connect to a client-like IPv6 device on the local network, since its public IP address will change all the time for privacy reasons, assuming it respects best practices.
Routing is only simpler if the ISPs actually hand out the large prefixes they are supposed to. Not all of them do.
DHCP is still required for many use cases. So now you have two solutions for handing out addresses, and you need to figure out when to use SLAAC and when to use DHCP. This is strictly more complex than IPv4, not simpler. SLAAC is mostly just unnecessary cruft, a cute little simple path for limited use cases, but it can never replace DHCPv6 for all use cases (e.g. for subnets smaller than a /64, for communicating additional information like a local DNS server or NTP server, for complex network topologies, for server machines etc).
OK. So what happens if your ISP connection goes down? Your router will detect this and withdraw the ISP's prefix.
So now you can't print because your printer doesn't have an address. Good luck.
> * Doesn't require DHCP.
This turns out to be a problem, as you can't easily see what's going on in the network.
The question of whether or not you use private addressing is, AFAICT, independent of the protocol. I mean, there's no material difference between private and public addressing.
> * No more NAT (see above).
Ditto. You don't have to NAT over IPv4, and you can NAT over IPv6; and - you may want to or need to, depending on restrictions on your connection.
> * Simpler routing
In what way?
> * Doesn't require DHCP.
IPv4 doesn't require DHCP either, IIANM.
But - point taken on the other simplifications!
* Private addressing is a feature, not a bug, in the datacenter.
* NAT is a feature, not a bug, in the datacenter.
* Simpler routing matters more on bad connections, but is less of a problem on good ones.
* DHCP is a feature, not a bug, in the datacenter.
Overall, it adds features that I don't need in my datacenter, and takes away others that I do and now need to add back. Like I said: it's great outside the datacenter, not so great inside it.
I always found that to be a desperate talking point. 'Prepare your network for the incredibly rare event where you intend to integrate directly' (didn't anyone hear of network segmentation?). It makes a lot more sense to worry about the ISP unilaterally changing your prefix - something that can only happen in IPv6.
ISPs unilaterally change your DHCP address on IPv4 all the time. And in any situation where you would have a static address for IPv4, your ISP should have no problem giving you a static v6 prefix. This argument makes no sense at all.
My understanding is that for some bizarre reason this is not usually the case with IPv6
which could use HTTP/2 or HTTP/3
and HTTP/2 for the localhost (or unix socket) gateway<->app step to provide e.g. WebTransport support
Most application frameworks that I've dealt with have limited capabilities to handle concurrent requests, so it becomes a minor issue to have 100+ connections between the app and the lb.
On the flipside, apps talking to the LB can create all sorts of headaches if they have even modest sized pools. 20 TCP connections from 100 different apps and you are already looking at hard to handle TCP flooding.
IPv6 is the same deal, I sort of understand where the confusion comes from around QUIC because so much was discussed about mobile early on, and it just got parroted heavily in the rumor mill, but IPv6? that long predates the mobile explosion, and again, it helps as an application, but ascribing it as the only application because of it's applicability somewhere else doesn't hold up to basic scrutiny. The largest data centers these days are pushing up against a whole v4 IP class (I know, classes are dead, sorta) in hardware addressable compute units - a trend that is not slowing.
We did this with quic data center side: https://tailscale.com/blog/living-in-the-future#the-c10k-pro... and while it might be slightly crazy in and of itself, it's far more practical with multiplexing than with a million excessively sized buffers competing over pools and so on.
There is absolutely value to quic and ipv6 in the data center, perhaps it's not so useful for traditionally shaped and sized LAMP stacks, but you can absolutely make great use of these at scale and in modern architectures, and they open a lot of doors/relax constraints in the design space. This also doesn't mean everyone needs to reach for them, but I don't think they should be discarded or ascribed limited purpose so blithely.
Sure, but now you've lost some of the benefits of HTTP/3, such as the header compression and less head-of-line blocking. To some degree the load balancer can solve this by using multiple parallel HTTP 1.1 streams, but in practice I've seen pretty bad results in many common scenarios.
HTTP client packages often use a small, fixed number of connections per domain. So if you have two servers talking to each other and there's slow requests mixed in with short RPCs, the latter can sit in a queue for tens of seconds.
However IPv6 is perfectly suited to the datacentre. So long as you have properly infrastructure setup (ie properly functioning DNS) IPv6 is a godsend for simplifying medium scale infra.
In fact, if you want to get close to a million hosts, you need ipv6.
[1] Me and http/2 have beef, TCP multiplexing was always going to be a bad idea, but because idealism got in the way of testing
> At the same time, neither QUIC nor HTTP/3 are included in the standard libraries of any major languages including Node.js, Go, Rust, Python or Ruby.
.NET actually looking like it has decent support for any teams that are interested[0] (side note: sad that .NET and C# are not considered "major"...). There is an open source C library that they've published that seems rather far along[1]Support for Windows, Linux[2], and Mac[3] (the latter two with some caveats).
Overall, I think for most dev teams that are not building networking focused products/platforms, HTTP/3 is probably way down the stack of optimizations and things that they want to think about, especially if the libraries available have edge cases and are too early for production. Who wants to debug issues with low-level protocol implementations when there are features to ship, releases to stabilize, and defects to fix?
[0] https://learn.microsoft.com/en-us/dotnet/fundamentals/networ...
[1] https://github.com/microsoft/msquic
[2] https://learn.microsoft.com/en-us/dotnet/fundamentals/networ...
[3] https://learn.microsoft.com/en-us/dotnet/fundamentals/networ...
I've said it before on here, but the tech community severely underrates .NET today. It's not Windows only (and hasn't been for ~8 years) plus C# is a very nice language. F# is also an option for people who like functional languages. I'd highly recommend giving it a try if you haven't already.
I work on .NET and work on Mac (hate the OS, but the hardware and battery life are way better).
Last startup, we shipped AWS t4g Arm64 and GCP x64 Linux containers. A few devs started on Windows (because of their preferred platform), but we all ended up on M1 MacBook Pros using a mix of Rider and VS Code.
Common misconception between old .NET Framework and new .NET # (e.g. .NET 9) (MS terrible naming). C#/.NET has been capable of cross platform binaries for close to a decade?
I have a bit more info here: https://typescript-is-like-csharp.chrlschn.dev/pages/intro-a...
"Since there's no standardized way to obtain native macOS SDK for use on Windows/Linux, or Windows SDK for use on Linux/macOS, or a Linux SDK for use on Windows/macOS, Native AOT does not support cross-OS compilation. Cross-OS compilation with Native AOT requires some form of emulation, like a virtual machine or Windows WSL."
Now, you don't have to actually use AOT, the other deployment options are actually much easier to cross-build, but true cross build AOT is still not supported.
(this comment is correct: https://news.ycombinator.com/item?id=43388962 ; runtime-dependent and self-contained are fine)
> Native AOT does not support cross-OS compilation
> ...runtime-dependent and self-contained are fine
This certainly reads like you moved the goal posts and recognized it.You're not going to convince someone who is looking for a way to make something not work however minor it is and not the other way around.
Or you can cross-compile and run without having dotnet on the target system, I do it from Linux to all three platforms all the time, it's pretty seamless. The application can be packaged into a single binary (similar to Go), or as a bunch of files which you can then then package up into a zip file.
dotnet publish -r osx-x64 --self-contained
https://learn.microsoft.com/en-us/dotnet/core/deploying/#pub...Also, if you want to have just a single binary, you want to do 'dotnet publish /p:PublishSingleFile=true /p:PublishTrimmed=true' instead. Self-contained build means it just ships everything needed to run in a folder without merging the assembly files or without trimming unreachable code and standard library components.
But if it’s native Go code, then cross platform compiling is just an a few environmental variables
GOOS=darwin
GOARCH=arm64Look at this garbage API that for no reason whatsoever mirrors winapi on posix for example.
Then after you painfully wrote your linux application despite all of that, you find out that .net is not included by any linux distribution, so have fun distributing your app!
Launching a new process can be as easy as `Process.Start(path, args)`.
Although if you are doing this, I can recommend using CliWrap package instead which provides nicer UX. Anything is possible the second you stop looking for a strawman.
> you find out that .net is not included by any linux distribution
Would I? If it's a CLI or a GUI application, I'd distribute it as either a native binary or as the recipe the user will be easily able to build with the .NET SDK (which is a standard approach - you'd need Rustc and Cargo in the same way).
Lastly - no one wants to put up with the maintainers with such attitude and you know well enough that "not included in any linux distribution" is both provably false and a non-factor - in all the distributions that matter it is `sudo {package manager} install dotnet9` away :)
Yeah I do have a life. I advice you to get one as well.
> Launching a new process can be as easy as `Process.Start(path, args);`.
-_-' Same exact problem. Letting every single process do their own escaping of the arguments. A proper portable API would have an array of strings for the arguments, to map execve(). That's how on windows every program does its own escaping and there's lots of programs doing it differently than others, but not how it works on posix.
Thanks for confirming you don't even comprehend the issue here. Crying "strawman!" won't help.
> If it's a CLI or a GUI application, I'd distribute it as either a native binary or as the recipe the user will be easily able to build with the .NET SDK (which is a standard approach - you'd need Rustc and Cargo in the same way).
You can't do any GUI in .NET outside of windows and you know it fully well.
The difference with cargo or go or pip is that all of these are found in every linux distribution, while .net is in none. Please go ahead and misunderstand this sentence on purpose like you've been doing so far.
> in all the distributions that matter it is `sudo {package manager} install dotnet9` away :)
I guess ubuntu, debian, red hat do not matter? What's left? neonsunsetimaginarylinux?
On the off chance you are making an intentionally inflammatory reply - you could also ask normally.
Let me try one last time (and now I vaguely remember having similar conversation here before).
On Ubuntu:
sudo apt install dotnet9
On RHEL (8 or 9): sudo dnf install dotnet-sdk-9.0
On Alpine: sudo apk add dotnet9-sdk
Then, you can get a simple cross-platform application template like this: dotnet new install Avalonia.Templates && \
dotnet new avalonia.app -o AvaloniaExample && \
cd AvaloniaExample && \
dotnet publish -o build -p:PublishAot=true && \
./build/AvaloniaExample
The above can target: Linux, macOS, Windows, WASM and with some caveats Android and iOS (although I would not recommend using Avalonia for mobile devices over e.g. Flutter).The build folder will contain the native application itself and the Skia dynamically linked dependency alongside it (and possibly some symbols you can delete). This is very similar to the way Qt applications are shipped.
This is just one GUI framework. There are other: Uno Platform, Gir.Core (GTK4 + GObject libraries), SDL2 via Silk.NET, Eto. I'm sure there's more.
What is bewildering is you could argue about "first-class" or "subpar", etc. But "does not work at all" is just ridiculous and indefensible. What kind of thought process leads to this conclusion?
In any case, I doubt you're going to read this since your replies seem to indicate interest in tilting at any windmill with ".NET" label on it instead, but at least my conscience is clear that I tried to explain this to the best of my ability.
> The difference with cargo or go or pip is that all of these are found in every linux distribution, while .net is in none.
This statement is false. It is also in arch. If it is not in debian and ubuntu, that is their fault. (But it would not surprise me, any user will soon run into the fact that even for non-obscure software there are no up-to-date packages in the main repo. The default escape hatch is to add extra repo sources, but my advice is to skip those distro's altogether anyways, unless you have very specific needs.)
But then again, if you think package management is a serious topic and then dismiss .net for the python mess, come on.
> the APIs are windows oriented?
The design of this particular API might be off. I guess this dates from the pivot to cross-platform. Usually, tuning for .net performance is better on Linux. I think nobody in MS believes in Windows as a platform really, it is a sinking ship.
Of course. Microsoft is a tiny poor company. It couldn't possibly afford to hire a consultant to do this kind of job.
> But then again, if you think package management is a serious topic and then dismiss .net for the python mess, come on.
What mess? apt solves the mess, there's no mess if you stay away from pypi (which I advice you do).
> I think nobody in MS believes in Windows as a platform really, it is a sinking ship.
I'm rather sure governments will still use it in 20 or 30 years.
Self-contained will work fine because we precompile the runtime and libraries for all supported platforms.
Native AOT won't, because we rely on the system linker and native libraries. This is the same situation as for C++ and Rust. Unlike Go, which doesn't use anything from the system, we try to support interop with system libraries directly, and in particular rely on the system crypto libraries by default.
Unfortunately, the consequence of relying on system libraries is that you actually have to have a copy of the system libraries to link against them, and a linker that supports that. In practice, clang is actually a fine cross-linker for all these platforms, but acquiring the system libraries is an issue. None of the major OSes provide libraries in a way that would be easy to acquire and deliver to clang, and we don't want to get into the business of building and redistributing the libcs for all platforms (and then be responsible for bugs etc).
Note that if you use cgo and call any C code from Go you will end up in the same situation even for Go -- because then you need a copy of the target system libc and a suitable system linker.
.NET ain't hip.
Today’s MS is not what it was back then. But long memories are not a bad thing, really. If .NET suffers a bit from some unfair perception, perhaps that can remind MS and others what happens when you take an aggressively adversarial approach.
https://arstechnica.com/security/2024/01/microsoft-network-b...
https://en.wikipedia.org/wiki/Embrace,_extend,_and_extinguis...
In fact when Microsoft purchased GitHub, quite a few people did leave and close their account. But GitHub already had such a monumental market lead that the departures ended up being a drop in the ocean.
To be honest, I’m still waiting for the moment when Microsoft managed to fuck it all up like they did with Skype.
If you write a project in C#, you've committed to it and it's ecosystem. Getting out of there when MS makes a choice you don't agree with is going to be near impossible.
TypeScript though I had no idea about! Good for them!
> GitHub was purchased, which is a bit different.
Why is that different? The purchase was 7 years ago (?) at this point.Do we make an exemption for SharePoint because it, too, is an extension of FrontPage acquired via Vermeer?[0]
At what point does it lose its exemption from "Hate All Things Microsoft"? 10 years? 20 years?
It only matters in the context of it being "ironic" that it is used and favored in the coding community.
Microsoft contributions to Python?
Do they all trigger some weird instant irrational reaction?
In my head, when I think Microsoft I think about the stress and anger I feel using Windows, and the OS-level notification I got apropos of nothing a few minutes ago trying to sell me an Xbox Game Pass subscription. The fear of what is going to break in the next forced update. For months now I haven't been able to do a task as simple as take a screenshot on my PC because seemingly the flash effect it plays gets caught in the image and the resulting screenshot has all the colors blown out, so it's mostly white.
So yes, this does color my opinion of how many ecosystems of theirs I want to tie myself too (minimal)
I would never have predicted Microsoft would still be developing a (sort of) Github competitor after acquiring Github. Why not plow all of that focus and energy into making Github the best project management system around? Project management in Github is one of the biggest gripes people have - even on Teams and Enterprise.
That said, Microsoft is never going to be able to completely kill Azure DevOps. If nothing else, they'll have to keep it alive for enterprise customers' TFVC source control history.
Surely there's a migration path to git from TFVC? Many large projects successfully moved from CVS and SVN into git.
I'm just surprised that, after 7 years of owning Github, Microsoft hasn't plowed their resources into Github's Projects. It's literally the number one complaint I see regarding project management inside Github - and would likely be an easy way to scale subscriptions for Teams and Enterprise. Heck, today it's still impossible to generate a Burn Down chart without using 3rd party "Apps" or the API.
If you need branch history, or more than 180 days worth of history, the only option is third-party tooling (git-tfs). It seems to work good enough for development purposes (i.e. git blame)... but I'm not sure if it's good enough if we need the history for legal purposes.
I'm baffled by insistent behavior like this. I think it is just alienating people and even if they move ecosystems, the negative impression will stay.
If you engage in bad faith behavior in a technical discussion, can you be expected to conduct yourself acceptably in a professional setting? Unlikely.
This is a discussion about HTTP/3 support of all things. Why does it happen only when someone leaves a briefly positive note on C#? I don't know any other language (besides PHP, to an extent) that gets the same amount of hate.
The link itself is also quite outdated and mainly consists of posts from Miguel de Icaza who's promoting Swift, arguably less OSS language. Take from that what you will.
Fanboys are a bit in denial about this.
I should also add that the general public only saw the tip of the iceberg in this entire episode. Miguel spent a lot of time and effort internally trying to right the .NET ship, gradually escalating through management until he finally gave up.
Instead, the complaints you will read here are about what the authors think .NET’s problems are without ever verifying if any of that is true in hopes of making swipes for god knows what reason, because posting something accurate requires knowledge on the subject and the results of a cursory search usually do not support cheap arguments.
(and I see this as an embarrassment because you can learn a lot from doing research instead of repeating the same tired phrases you heard elsewhere)
Call it TypeScript++ or just `dot`; rebrand it Microsoft! Look at this thread full of misunderstandings and confusion around modern .NET!
Speaking for myself, I happen to like .NET from the technical perspective. While both the language and the stdlib have a lot of cruft from days of yore, it can mostly be ignored, and that aside it's a fast runtime with a decently expressive type system giving one considerable flexibility to pick the right tool to model different domains. It also has great tooling around it. But this all is separate from the question of how open .NET really is, and its long-term prospects in that department.
https://github.com/ghuntley/isdotnetopen
The website doesn't even explain what they mean by open.
Nor they explain why they think .NET is not open source.
Further, the twitter posts themselves are still relevant I believe. If someone took over my repo, I'd remember it 3 years later.
So far, there was little demand to write another debugger integration (because, really, the debugger core is implemented in the runtime itself - what vsdbg, NetCoreDbg and Rider all primarily do is consume the runtime API).
For a long time, .NET was completely proprietary, and only ran on Windows.
Now it is open source and cross platform, but it is still fighting the momentum of being seen as Windows-only.
they clearly WANT applications written in .net not to be cross platform
If you want a cross platform UI, use WPF with Avalonia. Or if you want something entirely from Microsoft themselves, there's MAUI as an option.
HTML is all you need for a cross platform UI.
FTFY
Case in point: both Teams and VS Code: both web view wrappers.
Some trading shops are still using WPF and some are even using Windows Forms apps still.
It can, but not easily. As OP has said, it is a wrapper around Win32, and not an opaque one - it literally has stuff like e.g. the Message struct with members like HWnd and LParam.
Mono did try at one point, but they kept hitting edge cases where this kind of stuff would break things. Eventually they gave up and just wrapped Wine. So, yes, if you really really want to run WinForms on Linux, Mono is where it's at. But ... why?
Note that C++, Rust, Go all don't have any kind of standard GUI support out of the box at all.
But that's not really what's being discussed in the context of this thread: application servers handling HTTP/3.
To give one example with a particularly large user base, NVidia control center was a WinForms app for a very long time.
These are user-facing applications anyway, not back-end ones which is the more common use-case of .NET (where Linux is the most popular OS).
About back-end - I would repeat my question but I don't want to derail the conversation too far away from the original subject.
sudo apt-get install dotnet-sdk-9.0
No?Which means that nothing written in .net will enter the real repository until that changes.
> making it needlessly complex for everyone (including Rust)
have I missed something?
Because I didn't have to do that. Have you considered your distro might be special for reasons that have nothing to do with .NET?
My bet is this is a pitched battle inside Oracle, and the forces that keep it open have been winning...so far.
> multiple OSS alternatives out there
What does this mean? > And it turns out that TS is syntactically and semantically much closer to Go, so you can often convert the former to the latter mechanically.
Are there examples of this?I ask because I've been working on a Nest.js backend in TS and it's remarkably similar to C# .NET Web APIs (controllers, classes, DI). Really curious to see the translation from TS to Go.
There's a screenshot comparing the two side-by-side, IIRC it was showcased on the video of the talk (if someone has a timestamp - please post).
The other part of it is that C# is very firmly in the nominal typing camp, while TS is entirely structurally typed. Go can do both.
Especially for big backend APIs: https://typescript-is-like-csharp.chrlschn.dev/
ASP is actually very good these days and feels cleaner than Spring Boot. There's less choice but the available choices are good. It has arguably the best gRPC implementation. It's just a nice experience over all.
I've been doing a writeup comparing how ORMs work in TypeScript vs ORMs in .NET and one thing that is magical is that having the `Expression` type enables a much more functional and fluent experience with ORMs.
[0] https://learn.microsoft.com/en-us/dotnet/csharp/advanced-top...
Having been working in TS with Prisma for a bit, what stands out is how a Prisma query is effectively trying to express an expression tree in structural form
An example on TS with Prisma:
const loadedAda2 = await tx.runner.findFirst({
where: { email: 'ada@example.org' },
include: {
races: {
where: {
AND: [
{ position: { lte: 10 } },
{ time: { lte: 120 } },
{
race: {
name: { contains: 'New' }
}
}
]
}
}
}
})
(Other query tools like Kysely end up using strings (though with the support of TypeScript at dev time))And the same in C# with EF and LINQ:
var loadedAda = await db.Runners
.Include(r => r.RaceResults.Where(
finish => finish.Position <= 10
&& finish.Time <= TimeSpan.FromHours(2)
&& finish.Race.Name.Contains("New")
)
)
.FirstAsync(r => r.Email == "ada@example.org");
The difference being that the C# code is actually passing an expression tree and the code itself is not evaluated, allowing C# to read the code and convert it to SQL.Proper macros operate on AST, which it to say, it is exactly like the Expression stuff in C#, except it can represent the entirety of the language instead of some subset of it (C# doesn't even fully support the entirety of System.Linq.Expressions - e.g. if you want LoopExpression, you have to spell the tree out explicitly itself).
> TS does not have macro facilities
That I'm aware; I'm curious how this works on Go or Rust.For procedural macros, what you get is not even the syntax tree but rather the token tree: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html. You can then use stdlib to parse that into a Rust syntax tree (which is roughly the equivalent of Expression): https://docs.rs/syn/latest/syn/enum.Expr.html
Or you can do your own parsing, meaning that you can handle pretty much any syntax that can be lexed as Rust tokens. Which means that e.g. the C# LINQ syntactic sugar (from ... select ... where etc) can also be implemented as a macro. Or you could handle raw SQL and do typechecking on it.
Plus now Microsoft is being a bully when it comes to Cursor and the other VS Code forks, and won’t let the .net extensions work. I jumped through a lot of hoops but they keep finding ways to break it. I don’t want an adversarial relationship with my development stack.
I miss C# and I really don’t like Python as a language, but I don’t see myself doing a lot more C# in the future if these trends continue.
There's a huge difference from Copilot in 2023, if that was your example.
Also, interesting you feel more productive on a language you don't even like than your "main" one.
Last startup we built our entire backend in .NET and C#. Every dev ended up using MacBooks. We shipped to AWS t4g Arm64 Linux targets.
This mis-perception is so irrational and not based on any facts.
You're seeming like the node developers trying to push js everywhere because it's all they know. It's not a very rational approach I think.
I write it very explicitly here[0]:
> Should you use C# for web front-ends?
>
> We're only considering backends here; I do not think that .NET-based front-ends (e.g. Blazor) are competitive in all use cases.
We are in a thread about...backend application servers.Most of my side projects are TS/JS and run serverless Node.js functions on the BE[1]. I don't choose favorites; I choose the right one for the job.
[0] https://typescript-is-like-csharp.chrlschn.dev/pages/intro-a...
.NET omission notwithstanding, one of the languages in the list is not like the others: Rust has a deliberately minimal standard library and doesn't include HTTP at all. I don't follow Rust HTTP/3 efforts closely, but there are at least two actively developed libraries: quiche and quinn.
https://docs.python.org/3/library/http.client.html#module-ht...
https://docs.python.org/3/library/http.server.html#module-ht...
Even Microsoft does not use C# for their new projects. See the new TypeScript compiler that is being rewritten in Go. So I think it is safe to say C# is indeed a minor language.
> So I think it is safe to say C# is indeed a minor language
That's not really the case; StackOverflow survey[0] shows C# (27.1%) right behind Java (30.3%) and well ahead of Go (13.5%), Rust (12.6%), Kotlin (9.4%), Ruby (5.2%), and Scala (2.6%). If we exclude HTML/CSS, Bash/Shell, and SQL, C# would be #5 in actual languages used over the past year by devs in this survey.You get the same result from scraping job postings: https://www.devjobsscanner.com/blog/top-8-most-demanded-prog...
1. JS/TS (note these two are collapsed)
2. Python
3. Java
4. C#
Two completely separate sources with the same output... > See the new TypeScript compiler that is being rewritten in Go
If they had started from scratch, Anders mentioned the considerations would be different. But because they had an existing body of code that was not class based, it would be more of a re-write (C#) versus a refactor (Go). A lot of folks read the headline without actually reading Anders' comments and reasoning.C# is good for many things -- in particular application backends, game engines (both Godot and Unity) -- and not optimal for other things -- like serverless functions. Each language has a place and Go and Python are certainly better for CLI tools, for example.
SO is one data point, but there are certainly others.
You get the same result from scraping job postings: https://www.devjobsscanner.com/blog/top-8-most-demanded-prog...
1. JS/TS (note these two are collapsed)
2. Python
3. Java
4. C#
Two datapoints, completely discrete, same result.Can we rule out sample bias here? After all, Jon Skeet [0] is an important part of the Stack Overflow's C# community.
It might just be the case that C# and Java developers use Stack Overflow more than users of other languages.
[0] https://toggl.com/blog/save-princess-8-programming-languages
1. JS/TS (note these two are collapsed)
2. Python
3. Java
4. C#
So now you have two data points that align and are completely independent measuring two different things (one self reported, one based on employer job postings).I'd say it's consistent and reliable?
It's not like people use StackOverflow because it's written in C#; people use StackOverflow because Google points us there.
I don't understand this reasoning at all, and I'm hoping you can shed some light on it.
As far as I know, C# supports static methods. Thus, using OO in C# would not have been required, would it?
I feel like I'm missing something here.
var foo: { bar: { baz: string } }
which have no equivalent in C#, because it doesn't have anonymous struct types, and its typing system is almost entirely nominal. Go, on the other hand, can translate this directly pretty much mechanically: var foo struct { bar struct { baz string } }
And keep in mind that they aren't completely ditching the existing implementation, either, so for a while they're going to have to e.g. fix bugs in both side by side. It helps when the code can also be mapped almost 1:1. type Platform = "Mastodon" | "Bluesky" | "Threads";
type Profile = {
name: string,
socials: {
handle: string,
platform: Platform
}[]
}
function getProfiles() : Profile[] {
return [{
name: "Charles",
socials: [
{ handle: "@chrlschn", platform: "Mastodon" },
{ handle: "@chrlschn", platform: "Bluesky" }
]
},
{
name: "Sandra",
socials: [
{ handle: "@sndrchn", platform: "Threads" }
]
}]
}
Versus: using Profile = (
string Name,
(
string Handle,
Platform Platform
)[] Socials // Array of tuples in another tuple
);
enum Platform { Mastodon, Bluesky, Threads }
Profile[] GetProfiles() => new[] {
("Charles", new[] {
("@chrlschn", Platform.Mastodon),
("@chrlschn", Platform.Bluesky),
}),
("Sandra", new[] {
("@sndrchn", Platform.Threads)
}),
};
With some caveatsConsidering how fast the TypeScript compiler is, the TypeGo -> Go transpilation might as well be similar (up to a constant factor) in speed to Go compilation itself.
I'd give it a try. As a highly enthusiastic Go programmer, a powerful TypeScript-like type system is something I'd welcome in Go with open arms.
All of the above was easy to implement in Rust
It's more about right tool for the right job.
Good example is Azure CLI; it's Python. Microsoft is also a big contributor in the Python scene[0]
I don't think it's surprising at all that they didn't use C# to write a compiler for TS.
They have internal champions for Rust[1]
I'd say Microsoft is possibly one of the most diverse shops when it comes to tech selection.
[0] https://devblogs.microsoft.com/python/supporting-the-python-...
[1] https://www.theregister.com/2022/09/20/rust_microsoft_c/
The thing that they actually wanted is data-centric programming with structural types.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/s...
But apparently there aren't enough people willing to actually do the work.
> sad that .NET and C# are not considered "major"...
No need to be sad about that list. Java is also missing. There must be millions of enterprise programmers in the world using Java.I just checked the Java class HttpClient (a common JDK11+ HTTP client). It currently does not support HTTP/3, so add one more to the list!
Ref: https://docs.oracle.com/en/java/javase/24/docs/api/java.net....
Also, most of the very best network clients are now built on top of NettyIO. I can see an "incubator codec" here: https://github.com/netty/netty-incubator-codec-http3
Holy hell, this code is ridiculously complex: https://github.com/netty/netty-incubator-codec-http3/tree/ma...
I'm not hating on NettyIO here, but the protocol looks complex. Yet another reason why it is so slow to be deployed to more application frameworks.
And it is obviously only popular in the dark matter of Enterprise Software Development.
And to Rust ... definitely. Rust is a niche product for system development. A very good one. A very popular one. But nothing you need for your day to day microservice.
> And it is obviously only popular in the dark matter of Enterprise Software Development.
Well, and apparently for game development given both Godot and Unity use C# and various builds of .NETAdditionally, I'd posit that for most client applications, a few extra ms of latency on a request isn't really a big deal. Sure, I can imagine applications that might care, but I can't think of any applications I have (as a developer or as a user) where I'd trade to have more complexity on the networking layer for potentially saving a few ms per request, or more likely just on the first request.
For all the CPU optimisations we're doing, cutting out a 50ms roundtrip for establishing a HTTP connection feels like a great area to optimize performance.
HTTP/3 makes a meaningful difference for machines that need to work with HTTP endpoints, which is what Google needed it for: it will save them (and any other web based system similar to theirs) tons of time and bandwidth, which at their scale directly translates to dollars saved. But it makes no overall difference to individual humans who are loading a web page or web app.
There's a good argument to be made about wasting round trips and HTTP/3 adoption fixing that, but it's not grounded in the human experience, because the human experience isn't going to notice it and go "...did something change? everything feels so much faster now".
HTTP/3 is a good optimization, and you can't sell it based on "it improves things for humans" because it doesn't. It improves things for machines, and given that essentially all internet traffic these days is handled by large scale machine systems, that's a perfectly sufficient reason for adoption.
Today I have fibre at home, but mobile networks are still patchy. I'm talking sub 1Mbps and high ping/jitter sometimes. So you can see why I think an "irrelevant" optimisation that removes 300ms from a page reload, no compression vs brotli/zstd, jpg vs avif, etc, are important for me, a human.
It's important to keep in mind that many users out there don't have a fast and low latency connections, at least not all the time. What takes 300ms to complete on our fast machine and fast WiFi at the office might take 1s on someone else's device and connection. It's harder to understand this if we only use fast connections/hardware though.
It's good because it speeds up the overall response by a measurable degree, not because it makes the experience better. That only happens in conjunction with tons of other improvements, the big ones of which are completely unrelated to the protocol itself and are instead related to how the page is programmed.
How is everyone this bad are understanding that if someone claims A cannot be justified because of B, that does not mean that A cannot be justified. It's near-trivially justified in this case. This crowd really should know better.
Nearly all of my real world performance issues have come from a very small set of functionality running extremely poorly.
For example, Google hires 10 engineers, they deploy HTTP/3, it saves 0.5% cpu usage, Google saves a million dollars and covers the salary of the said 10 engineers.
For the vast majority of society, the savings don't matter. Perhaps even deploying it is a net-negative with a ROI of decades. Or, the incentives can be misaligned leading to exploitation of personal information. For example, see chrome manifest v3.
It's okay to question whether we need it.
Many optimizations have bad ROI because users' lives are an externality for the industry. It's Good and Professional to save some people-weeks in development, at the cost of burning people-centuries of your users' life in aggregate. And like with pollution, you usually can't pin the problem on anyone, as it's just a sum of great many parties each doing tiny damage.
This isn't exactly true, but some of the potential reasons are pretty bad. Software turning into an ad platform or otherwise spying on users has made numerous corporations wealthier than the gods at the expense of the user is probably one of the most common ones.
That seems like an absurd statement to the point I wonder if I’m missing something.
It's a material benefit over networks with packet loss and/or high latency. An individual human trying to accomplish something in an elevator, parking garage, or crowded venue will care about a connection being faster with a greater likelihood of success.
Navigating from my phone at 4g and my fiber connection has drastic differences.
Especially noticeable when on vacations or places with poor connections, TLS handshakes can take many, many, many, seconds..After the handshake and an established connection it's very different.
So then (modern) mobile shouldn't be all that special.
Kinda.
So 5g is faster, but its still wireless, and shared spectrum. This means that the more people that use it, or the further they are away, the speed and bandwidth per client is adjusted.
(I'm not sure of the coding scheme for 5G, so take this with caution) For mobiles that are further away, or have a higher noise floor, the symbol rate (ie the number of radiowave "bits" that are being sent) is reduced so that there is a high chance they will be understood at the other end (Shannon's law, or something) Like in wifi, as the signal gets weaker, the headline connection speed drops from 100mb+ to 11.
In wifi, that tends to degrade the whole AP's performance, in 5G I'm not sure.
Either way, a bad connection will give you dropped packets.
That's a valid concern. That's the baseline already though, so everyone is already living with that without much in the way of a concern. It's a nice-to-have.
The problem OP presents is what are the tradeoffs for that nice-to-have. Is security holes an acceptable tradeoff?
maybe you can point out where that's what I said
AWS are pretty good though. However it is notable I get good speeds and latency using S3 over HTTP/1.1 for backing up several hundreds gigs of data, so not sure if HTTP/3 makes any difference if it is already good enough without.
There are other advantages: the article elaborates.
Even still, the question is, what’s worse: a cacheable request that has to go through DNS and a slow-start stage because it’s to an unrelated domain, or a potentially(?) noncacheable one that can reuse the existing connection? On a fast Internet connection, the answer is nonobvious to me.
On a fast internet connection, the answer doesn't matter because the internet connection is fast. On a slow internet connection, cacheable requests are better.
That's a software architecture problem, not a transport layer problem.
I did find it amusing how the author of the linked article says the megacorps are obsessed with improving performance (including the use of HTTP/3 to apparently help improve performance). In my experience the worst performing apps are those from the megacorps! I use Microsoft apps regularly at work and the performance is woeful even on a fibre connection using a HTTP/3 capable browser and/or their very own apps on their very own OS.
There is work going on right now[1] to implement the QUIC protocol in the linux kernel, which gets used in userspace via standard socket() APIs like you would with TCP. Of course, who knows if it’ll ultimately get merged in.
The 10+ different ways you specify a custom CA is a problem I can't wait to see the back of.
Regardless, your proposal suffers from the usual stuff about proliferating standards (https://xkcd.com/927/): a kernel interface will never get fully adopted by everyone, and then your "10+ ways" will become "11+ ways".
Meanwhile, all the major OSes have their own trust store, and yet some apps choose to do things in a different way. Putting this into the kernel isn't going to change that.
No, the asymmetric cryptography is all done in userspace. Then, post-handshake, symmetric cryptography (e.g., AES) is done in-kernel. This is the same way it works with TCP if you’re using kTLS.
That's not given, either as UDP is normally not prioritized under congestion.
And VPNs are carrying arbitrary traffic. You don't even know what it is. Assigning this anything less than "normal" priority is ridiculous.
In general middleboxes should stop trying to be smart. They will fail, will make things worse, and should embrace being as dumb and simple as possible. Don't try to identify traffic, just forward every packet you can and drop them at random when the pipe is full. The endpoints will figure it out.
HTTP/3 is terrible for fast connections (with download speeds on gigabit fiber notably capped) and great for bad ones (where latency + three way handshakes make the web unusable).
Perhaps there should be some kind of addon/setting for the browser to detect the quality of the network (doesn't it already for some JS API?) and dynamically enable/disable HTTP/3 for the best performance. I can live with it off 99% of the time, but those rare times I'm dropped to 2G speeds, it's a night and day difference.
That's not what it is, though. The graph embedded in the article shows HTTP/3 delivering content 1.5x-2x faster than HTTP/2, with differences in the hundreds of ms.
Sure, that's not latency, but consider that HTTP/3 can do fewer round-trips. RTs are often what kill you.
Whether or not this is a good trade off for the negatives you mention is still arguable, but you seem to be unfairly minimizing HTTP/3's benefits.
Then you're trying to rely on the OS for this when it should actually be a dynamically linked third party library under some open source license.
Trying to get the OS to do it fails to one of two problems. Either each OS provides its own interface, and then every application has to be rewritten for each OS and developers don't want to deal with that so they go back to using a portable library, or the OS vendors all have to get together and agree on a standard interface, but then at least Microsoft refuses to participate and that doesn't happen either.
The real problem here is that mobile platforms fail to offer a package manager with the level of dependency management that has existed on Linux for decades. The way this should work is that you open Google Play and install whatever app that requires a QUIC library, it lists the QUIC library as a dependency, so the third party open source library gets installed and dynamically linked in the background, and the Play Store then updates the library (and therefore any apps that use it) automatically.
But what happens instead is that all the apps statically link the library and then end up using old insecure versions, because the store never bothered to implement proper library dependency management.
Fortunately, this recently changed and OpenSSL 3.5 will finally provide an API for third party QUIC stacks.[1] It works differently than all the other existing implementations, as it's push-based instead of pull-based. It remains to be seen what it means for the ecosystem.
As far as developers are concerned, we still live, have always lived and will always be living in a "plaintext HTTP 1.1 only" world, because those are the abstractions that browser APIs and application servers still maintain. All the crazy stuff in between - encryption, CDNs, changing network protocols - are just as abstracted away as the different hops of an IP packet and might just as well not exist from the application perspective.
Because semantics are the same for every version.
Just as python3 had almost nothing for programmer over python2, apart from print needing brackets. Sure it was technically better, and allowed for future gains, but in practice, for the end user, there was no real reason to adopt it.
For devs outside of FAANG, there is no real reason to learn how to setup and implement http3
However, for high latency mobile connections while roaming and continuously using the internet, it’s quite an optimisation.
I wouldn’t expect even the vast majority of devs in FAANG to care. It should purely be an infrastructural change that has no impact on application semantics.
acquisition finished in 2019
there are quite a lot of features, but it's hard to say what constitutes a new module. (well, there's "Feature: the ngx_stream_set_module." so maybe yes?)
https://arstechnica.com/information-technology/2024/02/nginx...
Node.js just posted an update on the state of QUIC, which underlies http3 & has had some work over the years. They're struggling with openssl being slow to get adequate API support going. There's efforts that have working books for quic, but the prospect of switching is somewhat onerous.
Really unfortunate; so much of this work has been done for Node & there's just no straightforward path forwards.
Sites that use their own apache/nginx/whatever servers are not benefiting from this and need to do work. And this is of course not helped by the fact that http3 support in many servers is indeed still lacking. Which at this point should be a strong hint to maybe start considering something more modern/up to date.
Http clients used for API calls between servers that maybe use pipelining and connection reuse, benefit less from using HTTP3. So, fixing http clients to support http3 is less urgent. Though there probably are some good reasons to support this anyway. Likewise there is little benefit in ensuring communication between microservices in e.g. Kubernetes happens over http3.
https://niquests.readthedocs.io/en/latest/
Traditionally these types of things are developed outside the stdlib for Python. I’m not sure why they draw the line where they do between urllib vs niquests, but it does sometimes feel like the batteries-included nature of Python is a little neglected in some areas. A good HTTP library seems like it belongs in the stdlib.
> Requests is in a perpetual feature freeze, only the BDFL can add or approve of new features. The maintainers believe that Requests is a feature-complete piece of software at this time.
> One of the most important skills to have while maintaining a largely-used open source project is learning the ability to say “no” to suggested changes, while keeping an open ear and mind.
> If you believe there is a feature missing, feel free to raise a feature request, but please do be aware that the overwhelming likelihood is that your feature request will not be accepted.
— https://requests.readthedocs.io/en/latest/dev/contributing/#...
The whole point of requests is to make HTTP requests easy. HTTPLib was/is an arse to use.
as HTTP3 is really not that widely adopted, and where it is, has fallbacks to 1.1 whats the point?
Plus the people who are keen on HTTP3 also seem to be keen on async, https://github.com/aiortc/aioquic/tree/main/examples which even though it isn't seems to be overly complex and difficult to use. Contrast that to r.get(url)....
Besides, I was responding to this:
> The reason given for not including it in the stdlib was so it could evolve more rapidly.
Pointing out that it isn’t evolving at all is a perfectly reasonable response to that.
So nobody considered HTTP/3 interesting enough to rush and add support for it very quickly. It'll get there, but fast? I don't think so, see IPv6.
Also, nobody considered HTTP/3 worth enough of paying for maintainers to add support for it.
In a sense the need for IPv6 is driven by corporates just like that for HTTP/3.
I work in the networking space and outside of dealing with certain European subsidiaries, we don't use IPv6 anywhere. It's a pain to use and the IPv6 stacks on equipment (routers, firewalls, etc) are no where near the quality, affordability, and reliability of their IPv4 stacks.
Outside of Europe I don't know anyone not FAANG sized that managed to get it done in the last few years.
In my dealings with small to medium sized biz, I usually go the SDWAN route to aggregate and balance in IPv4 space instead as it is MUCH easier to get it done from an ISP.
https://blog.ipspace.net/2010/12/small-site-multihoming-in-i...
But BGP+PI is indeed how multihoming is supposed to work, both in IPv4 and IPv6. (Well, in IPv6, you can put two prefixes on-link and do poor man's multihoming that way, which you cannot reliably in IPv4.) Of course, if you define “it cannot be BGP+PI”, then indeed it's probably harder, but if you exclude the intended solution, obviously there's no intended solution.
Unfortunately, some ISPs (including mine) limit this to /64 only, which is extremely limiting.
Then came IP telephony backbone and the mobile internet, topped up with the cloud, and the need became acute. For the large corporations involved, at least.
The bigger thing is carrying this "you don't need it" attitude to a product used by billions. Thousands of network operators who do not believe in "you don't need it" are now forced to make their network work for Android. If those purists had guts they should go to the IETF and formally deprecate stateful DHCPv6.
If you read the huge bug on it, Google's counter argument is stateful dhcpv6 significantly complicates tethering to the point of needing an ipv6 nat. That's a very practical position to take, hardly "purist network objectionists"
It's those purists at Google that decide that NAT66 is evil and should not be used and therefore they have chosen not to support stateful DHCPv6.
Since Go has strong backwards compatibility guarantees, they're unlikely to commit to APIs that may need to change in the standard library.
Why would the open source community prioritize this?
"We'll get to IPv6 after we finish IPv5"
That explains it. I've seen this when using 3 year old browsers on retail web sites recently. A few cloud providers think I’m a bot.
Also there are a thousand other signals besides HTTP/3. It's not going to make a difference.
Something like 1% of HTTP hits pose some risk of spam or fraud, those where somebody is trying to post a message or a transaction or something. The other 99% are just requesting a static HTML document or JPEG (or its moral equivalent with unwarranted and untrustworthy dynamic content injected). Static file serving is very difficult to DDoS, even without a caching CDN like Fastly. There is still a potentially large bandwidth cost, but generally the DoS actor has to pay more than the victim website, making it relatively unappealing.
Should web sites really be weighing "a thousand signals" to decide which version of the truth to present a given user with? That sounds dystopian to me.
> Something like 1% of HTTP hits pose some risk of spam or fraud
It doesn't matter if it's a tiny percentage of requests that are spam/fraud. The only thing that matters is the absolute amount, and that's massive.
> Static file serving is very difficult to DDoS
No it's not, and most pages aren't particularly static. They're hitting all sorts of databases and caches and stores.
> generally the DoS actor has to pay more than the victim website
No, generally the DDoS actor pays very little, because they're using bots infecting other people's devices. The bandwidth is free because it's stolen.
> be weighing "a thousand signals" to decide which version of the truth
Nobody said anything about "truth". You're either blocked or you're not. Page content isn't changing.
Yes, spam and fraud and abuse prevention does require weighing a thousand signals. It always has. It sucks, but the world is an adversarial place, and the internet wasn't designed with that in mind.
---
According to other commenters the main use case for HTTP/3 is ads serving. Should I assume your project is an ad server? I could disable HTTP/3 in my browser to block ads. You see that this is a bit silly, right?
The two other commenters are wrong, ads are not the main use case at all. And disabling HTTP/3 won't block ads, not even the tiniest bit. It appears you are getting a lot of misinformation.
For example: "We were receiving 1000 spam and 100 legitimate comments per day even though we used hCaptcha on the comment form. When we disabled HTTP 1.1 on the comment endpoint, the spam stopped entirely, and we still received 95 legitimate comments per day." (in this scenario, I don't think it's necessary to further elaborate what counts as a "spam comment" if it's the usual type. If it's not the usual type then you will have to elaborate it.)
If you don't want to talk about basic concepts like bots or fraud, and don't understand how and why detection mechanisms for them exist, I suggest you do your own research. There are lots of explanations out there. An HN comment isn't a place where I can help you with that, sorry.
I have dealt with DDoS attacks with and without a service like Cloudflare, and without something like Cloudflare, the costs are extremely high. These are not clients pulling in millions of dollars of sales, even per year. There are IP blocks, but sometimes those bots are running on networks shared with the client's customers. Most clients I deal with couldn't fathom dealing with a static website, even if I could give them a hidden backend that pushed all files to a CDN for caching. I have enough trouble explaining why a page isn't showing recent changes, even with a big button stating to press it if your page changes do not display (integration with the Cloudflare caching API).
Bots, human fraud, it's all a balancing act while trying to give your clients the easiest solution possible for them to run their business online. Without a massive hosting budget, it's not feasible to provide for an easily maintainable client solution, that is also easy on their clients, and prevents abuse from bots and those that would cause fraud or damage.
A large part of this issue is web development being totally foreign to most users, and clients being burned by past developers that disappeared when needed the most, or hit with a large charge for an update that seems to be "simple". This pushes clients to want a solution where they can make the changes, and that leads to a dynamic website for static content. If you were to stop taking this type of business to further privacy, there are probably tens or hundreds of other companies in your own city that will gladly take on the work.
This absolutely is dystopian, but also current reality. Unless you are able to run completely privately online, the Internet as a whole has become dystopian because shutting down bad actors has been thrown into the hands of individuals instead of part of the backbone to how the Internet functions. Just my two cents, as a developer that needs to use these resources, but also runs a VPN on my phone and desktop nearly all the time for privacy (as well as some speed benefits, depending on the VPN provider).
I use Cloudflare through my employer because I deal with clients that aren't willing to spend a few hundred dollars a month on hosting. In order to keep up with sales of new websites for these clients (where the real money lies), I need to keep hosting costs down, while also providing high-availability and security. Bot traffic is a real problem, and while I would love to not require using Cloudflare in favor of other technologies to keep a site running quickly and securely, I just can't find another solution near a similar price point. I've already tweaked the CMS I use to actually run with less than the minimum recommended requirements, so would have to take a more hostile action towards my clients to keep them at the same cost (such as using a less powerful CMS, or setting expiration headers far in the future - which doesn't help with bots).
If anyone has suggestions, I'd be open to them, but working for a small business I don't have the luxury to not run with Cloudflare (or a similar service if one exists). I have worked with this CMS since 2013, and have gone into the internals of the code to try and find every way to reduce memory and CPU usage so I don't need to depend on other services, but I don't see too many returns anymore.
I am all for internet privacy, and don't like where things are going, but also do work for lots of small businesses including charities and "mom and pop" shops that can't afford extra server resources. In no way do I use Cloudflare to erode user privacy or trust, but can understand others looking at it that way. If I had the option to pick my clients and their budgets, it wouldn't be an issue.
if ($server_protocol != HTTP/2.0) { return 444; }
It knocks out a lot of bots. I am thankful that most bots are poorly maintained and most botters are just skiddies that could not maintain the code if they wanted to.[1] - https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#...
The http client libraries almost everywhere do lack support, though.
> Really it's hard to point to any popular open-source tools that fully support HTTP/3: rollout has barely even started.
But isn’t Caddy a widely used reverse proxy with HTTP/3 support? Or what features are missing?
I do hope to see more QUIC and HTTP/3 support, but to be honest, even h2 support in many cases sucks pretty hard. The Go HTTP interface is still pretty much HTTP/1 oriented and really needs a rehaul, and even the h2 implementation feels like it still lacks some battle testing. I think that is a damn shame.
Citation needed.
I even used its experimental http3 support in v2, and now it's stable in v3. As stable as it can get I guess.
At best those amazeballs advantages are applicable only at Google's scale, and have very little impact anywhere else.
Worse, still,
--- start quote ---
We find that over fast Internet, the UDP+QUIC+HTTP/3 stack suffers a data rate reduction of up to 45.2% compared to the TCP+TLS+HTTP/2 counterpart. Moreover, the performance gap between QUIC and HTTP/2 grows as the underlying bandwidth increases.
https://arxiv.org/abs/2310.09423
--- end quote ---
And if you believe the discussion here https://news.ycombinator.com/item?id=25970258 it increased the load on the server unless you can "spend years optimizing it".
Has Google said anything? Is it dependent on certain e.g. server-side factors? Did Google "get this wrong" or was this intentional? E.g. is it by far a net positive to be faster on slow internet where the difference is perceivable, than to be slower on fast internet because it's still lightning-fast even when it's slower?
-higher latency connections.
-packet loss under multiplexing scenarios / suboptimal connections (e.g. mobile).
These are the situations where it shines and runs away from HTTP/2. And this has been the promised advantage from the outset, and is literally the problem it is designed to solve.
Given that the linked paper mentions the word latency once in an irrelevant context, I think that's telling. Of course there is no advantage -- and in fact is an expected disadvantage -- when your client and server are 0ms from each other with 0% packet loss. Now put them 100ms from each other with 5% packet loss/reordering/retransmission and multiplexing.
This is absolutely massive
Quite frequently I'd love to have just 5% packet loss.
It's interesting how people often say HTTP/3 only benefits the megas like Google. A few years back I worked on a data centric system (fund administration) where we had a single centralized server cluster serving high value users across the globe. Because of the integration and real-time nature of the data, it wasn't possible to replicate to servers around the world, nor was local (relative to the user) caching of much value at all.
QUIC (which became HTTP/3) proved a significant improvement for users of the system. Users in the UK, Singapore, Australia, Germany, California, and so on, were all using a system in Toronto basically transparently, with great usability. That it was continents away suddenly didn't matter.
Most if my servers have about 40-50% packet loss.
50% is just a half. So we naturally expect our 3000gbit links to turn into 1gbit links, but that's not how tcp works.
And yet it's somehow being pushed as a be-all solve-all replacement despite this:
--- start quote ---
We experimentally demonstrate that QUIC’s performance degradation affects not only bulk file transfers but also other applications including video content delivery and web browsing, despite their intermittent traffic patterns. QUIC incurs a video bitrate reduction of up to 9.8% compared to HTTP/2 when delivering DASH (Sodagar, 2011) video chunks over high-speed Ethernet and 5G. Again, such QoE degradation only exhibits when the underlying bandwidth is sufficiently high. For example, the impact is hidden over 4G but unleashed over 5G. QUIC’s page load time (PLT) is 3.0% longer than HTTP/2’s, averaged across 100 representative websites, with a long tail of page load time gaps over 50%.
--- end quote ---
Latency is all good ... until latency isn't the only thing affecting the performance
> Of course there is no advantage -- and in fact is an expected disadvantage -- when your client and server are 0ms from each other with 0% packet loss. Now put them 100ms from each other with 5% packet loss/reordering/retransmission and multiplexing.
Indeed, why not claim something that article never claimed and then claim moral superiority for yourself. Nowhere in the article do authors claim to have servers 0ms from each other with 0 packet loss.
Additionally, if your performance degrades even in these ideal conditions, what does this promise for non-ideal conditions?
But it isn't a be-all solve-all replacement. The whole point of HTTP/3 is that you can still use HTTP/2 all you want in your build-outs, and it uses as appropriate. If large file, many packet, high speed sustained performance is your thing and you've got problems with HTTP/3, deploy it on an HTTP/2 server. Go nuts. Positively nothing will go awry. Everything will be fine.
You're arguing a strawman.
>Additionally, if your performance degrades even in these ideal conditions, what does this promise for non-ideal conditions?
This is an absolutely nonsensical statement. HTTP/3 is quite literally built for situations where you have many small requests, often in suboptimal situations. The average web user interacting with an average web page over something other than their local ethernet connection, exchanging tens of thousands of back and forths for different resources and navigations and posts. Screeching, with moral superiority I might add, that if it pins the CPU using their oddball no-name server -- oh, and where they bizarrely forced the HTTP/3 server to use HTTP/2 congestion control because that made the results funner -- with their client machine with a CPU 1/4 the performance of my smartphone, downloading a many GB file, isn't the big win you seem to think it is.
Ah yes. Basically back to some links I discussed. Oh, it's amazing but you have to be careful what you deploy, and when, and you have to switch between HTTP/2 and HTTP/3 for some unspecified criteria which may or may not be better in one or another while the article we're in comments to decries "why oh why so few implement HTTP/3"
> HTTP/3 is quite literally built for situations where you have many small requests, often in suboptimal situations.
That is what Google markets it as, for sure.
The rest of that sentence I could not parse.
Can you point me to this Google "marketing"?
Google doesn't particularly care if you use HTTP/3. They don't even build it into the tools they build like Go or Dart, at least not in a timely manner. There was a passing bit of technical notes for RFCs and as they added it in Chromium, but otherwise they've been remarkably silent about it.
Yet they moved trillions of web requests to HTTP/3. Maybe they really don't know what they're doing. Cloudflare also clearly hasn't the slightest, right? Fools!
>while the article we're in comments to decries
HTTP/3 is complex to implement. Very complex. It's pretty simple to understand why it hasn't seen wide implementation in every random tool. And for many people HTTP/2 is fine, especially as you're probably just going to drop Cloudflare (which has HTTP/3) with caching in front of it anyways.
[1]This is based on public benchmarks, try searching for `TCP vs QUIC`
Multiplexing is very common but unless you are at megacorp scale (or operating a cloud hosting platform) packetloss within your own wired network infrastructure isn't a super common issue. Compared to say packetloss to mobile clients on bad networks where QUIC can really provide a significantly improved experience.
https://www.haproxy.com/blog/announcing-haproxy-2-6
Live example: https://theandrewbailey.com/
This matters because for a lot of operating systems, UDP buffers are still tuned to nearly 1990s levels, and are insufficient to overcome BDP challenges. For CDNs / edge deployment systems such as Cloudflare/Fastly, this may not be "statistically relevant" for their customers, in that they're close to "statistically most" of their customers, however for users in locations where these organizations do not have anywhere near such a good presence (APAC, the islands, etc), their experiences are getting _far worse_.
Fighting HTTP/1.1 for money is going to fail unless you invent something fundamentally better.
I'm not sure why it would be in the Rust std, Rust std doesn't even have HTTP/1 or TLS, it's not supposed to support any network layer higher than what's provided by the OS.
The benefits only show in poorly connected networks (public internet), so that's pretty exclusively where it should be used - anything internet-facing.
There's ongoing work exploring QUIC-in-kernel-space at https://github.com/lxin/quic, and more generally HTTP/3 will be increasingly optimized over time as it moves towards becoming the majority of HTTP traffic (a few years off, but looks likely eventually). There's no fundamental reason I'm aware of that HTTP/3 would be _inevitably_ slower than HTTP/2, it seems likely for now that it's largely implementation details.
There's plenty of internet-facing cases with average-at-best connectivity where HTTP/3 would be beneficial today, and isn't available (non-megacorp Android apps, CLI tools, IoT, desktop apps, etc). Even on the backend, it's very common to have connections between datacenters with significant latency (e.g. distributed CDN to central application server/database).
So I don't see how HTTP/3 would of helped there. Most IoT applications are not very sensitive to things like latency and what counts as reliability is very much dependent on the situation. A simple protocol is an advantage.
IoT is not about latency. IoT is about devices being behind a NAT which does not allow inbound connections.
With UDP-based HTTP/3 it is possible to do "udp hole punching".
That works reliably with all the various types of NAT?
In the sense that nothing is really reliable in the presence of state-level adversaries censuring traffic, malicious ISPs, and crappy hardware. In general I have been more successful with QUIC hole punching than with ipv6.
But having a standard and relatively broadly implemented way to make reliable "TCP-like" streams over UDP is a great thing regardless.
The nicest feature of HTTP/3 is that it is UDP based, and thus does not allow so much interception by the malicious ISPs.
nginx's implementation works. (but for me it caused a strange performance degradation with Seafile)
By terminating an udp stream and fetching the backend data using http 2.0?
This might be enough for static web and such, but in a "new web" you'd want to use all those nice features of http/3 which have no direct equivalent in http/2, like multiplexing udp streams for video and such.
And if you forward the udp stream itself, what do you do with the certificate? Use a selfsigned one with no expiration date and add a custom CA? Seems laborious.
That doesn't matter too much, since a certain "security" company is doing deep packet inspection and blocking anything that isn't Firefox, Chrome, or Safari.
Basically if your browser provides even a tiny bit of privacy, Cloudflare blocks it randomly.
Even the latest deployments on Rocky 9 are using a 4 year old version of cURL
When you're writing libraries distributed as binaries for other teams you can't just statically link whatever you want willy nilly.
You could imagine us shipping our library as a DLL/.so and static-linking libcurl, but that comes with a bunch of its own problems.
You need to be in control of the final link if you're shipping a .a to other teams
If you want to use a private curl as an implementation detail then the only safe way to do it is to ship a .so, make sure all the symbols are private and that symbol interposition is switched off.
If you ship a .a then the final link can always make symbols public again.
but what turned out to be a big problem (not enough IP addresses for clients) was solved by CGNAT and a simple market (for servers)
of course it's important to understand that it was cheaper to deploy thousands of CGNAT boxes than to upgrade the whole Internet (and corresponding software)
Also, IoT crap tends to disable IPv6 (for saving a few kilobytes of ROM I think) but that stuff is better off locked behind six levels of NAT anyway.
You cannot manually set an IPv6 address or gateway for a WiFi, it's forced DHCP only. All of this works for IPv4.
Right now there's no critical mass, and the most commonly used most-reference implementation of an HTTP client doesn't support HTTP/3 in any standardized way.
The problem here is Akamai really in only supporting HTTP1.1 to the origin. Cloudfare I think only supports HTTP2 to origin. Does Fastly yet support QUIC to origin? Does Cloudfront, I could only find information about it supporting QUIC the last mile.
Maybe more CDN support will drive web server support.
For the hyperscale web sure, but for the long tail web that is very unclear.
Maybe really some users does not care more about it,as a developper I'd rather not taking much overhead to maintain a server that support http/3.
(I guess though that quiche has been an option if you like to write Rust like it's C.)
Use the tool for the job. If a single-threaded Python server running HTTP/1.1 works for your IT app, then use that. HTTP/3 has nothing to offer you.
HTTP/3 speeds up that kind of content by reducing connection startup times to all of them, which can be compounded.
it's good for multiple resources from the same host, maybe you have a lot of images on your photo blog or something
But users of most other websites won't see a ton of noticable benefits unless they have facebook/netflix/google levels of traffic. And at that point, you're either highly focused on the end user component code or you've outsourced it to a CDN that'll do the http3 for you anyways.
What's time until last byte though?
Yeah, The metric that got you promoted is cool and all, but if my application works on files atomically, it's the time until last byte that has meaning to me.
I'm also gonna assume a bit more, and say it's also the byte where the service can start processing someone else's connection. So if http/3 increases the load on servers, with their CPU, instead of network hardware, with their ASIC, this would be a net loss as soon as you look at amount of complete requests per energy used. Instead of just looking at single session metrics.
I guess I should probably read the HTTP/3 spec now...
Like dotnet?
It's astonishing change. You could have used the same argument to show that any dismaying historical development was "astonishing progress". From my point of view HTTP/3 looks like an advantage for hyperscalers but no benefit to regular users using small-scale websites.
That's progress toward a future I don't want to arrive.