4 ms·
HTTP/2 is just plain silly, HTTP/3 is a silly idea but implemented correctly. Neither are particularly useful unless you're a web browser. I'm sticking to HTTP
by mgaunard 4y ago
HTTP/2 is just plain silly, HTTP/3 is a silly idea but implemented correctly.
Neither are particularly useful unless you're a web browser. I'm sticking to HTTP/1.1 myself in all of my code.
- jFriedensreich 4y agocomments like this without giving arguments why something is silly are not super helpful
- mgaunard 4y agoYou'd simply need to know what those protocols are and how TCP works to understand the argument. Funnily enough most engineers don't seem to have any idea how TCP works these days.
- ilyt 4y agoThat is an example of argument: > HTTP/2 is bad because XYZ, HTTP 3 at least fixes Z Note giving reasons, and preferably also reasoning behind those reasons. You know, the "arguments" Here is what clown riding that dunning-kruger peak thinks that "argument" is: > HTTP/2 is just plain silly, HTTP/3 is a silly idea but implemented correctly.
- mort96 4y agoYou provided no argument, there is nothing to understand.
- tlamponi 4y agoAt Proxmox we use HTTP/2 (h2) in our backup project to asynchronously stream chunked data to the server, works great for that and wouldn't be really possible with HTTP 1.1; at least not with major headache and extra overhead. We also plan to closer evaluate HTTP/3 (h3) soon, mainly to see how the promised improvements, like no head of line blocking, turn out in practice for our use case. So I'd disagree that h2 or h3 is useless "unless you're a web browser"; but sure if you use HTTP only to provide a simple text (e.g., JSON) based API it might not be _that_ relevant. But some benefits like faster TLS setup might even make a difference there, e.g., faster initial startup, fewer packets transmitted, IIRC even packet sniffing should be a bit harder to do with h3. If those benefits are worth it on its own, depends then probably on how easy it's to integrate in your project, iow., if your framework/standard lib/ecosystem/... already supports h3 nicely. We use the rust hyper crate for most of our HTTP* communication, and their h3 implementation is still marked as experimental; and as we're not in a rush we'll just wait until the hyper project stabilizes h3.
- mgaunard 4y agoI don't see what's preventing HTTP 1.1 to chunk your responses. What HTTP 2 does is that it makes it possible to send multiple responses in parallel instead of one after each other.
- intelVISA 4y ago[flagged]
- tlamponi 4y agoYeah as said, we chunk backup data into (64 KiB to 4 MiB) chunks and send each in (parallel) async streams.. Chunked transfer isn't the issue, I know that would be easily dooable with h1.1, but it would be one serialized & sync stream.
- mgaunard 4y agoYou do realize you're sending it over TCP? It still ends up serialized. All you're doing is reducing the latency of the first request.
- tlamponi 4y agoNo it doesn't gets serialized just by using TCP, the multiplexed streams are still handled concurrently, better utilizing the waits that come from IO heavy workloads. Doing the same on top of http 1.1 can work but it'd be just rebuilding http 2 with more overhead; or use multiple http 1.1 connections, which takes up more OS resources and still has more overhead for binary data due to being text — and encoding to base64 then gziping or using deflate to get somewhat down im size again won't make it faster or more efficient. But yeah on package loss there's head of line blocking, which http 3 solves by using UDP and handling the reliability on the higher level.
- mgaunard 4y agoTCP must send all data in order. To implement that, all data sent out gets written to a retransmit buffer (which may be dynamically sized, but only up to a maximum), and that data only gets removed once acked by the other end. Once the retransmit buffer is full, you are unable to write more data; your TCP implementation would then most likely suspend your process and wake it up once it can write again. Your thread is spending its time waiting for the other end to ack before it can send more data, delaying any other kind of work your thread has to do (such as serving other clients). The rate at which it can write doesn't magically increase by attempting to write multiple streams concurrently; quite the opposite. The rate is controlled by the other end, and what you should do if you implement a high-performance TCP service (HTTP or not) is simply disconnect clients that require you to ever block. Now you could say, "I don't care, I write the data asynchronously". Asynchronous writes are very bad and an anti-pattern, they should typically never be used because they mean you are just queueing data indefinitely until it is eventually written, wasting massive amounts of RAM (if not taking the machine down entirely). Queues in general are serious business and require a careful design to ensure the producer doesn't produce data faster than the consumer, with adequate back-pressure algorithms. It is better to keep track of when you can write and decide on how to handle not being able to write rather than block or queue like an idiot. Multiplexing with HTTP/2 logically makes the TCP stream which is logically a spsc queue into a pseudo-mpsc queue. Those are also way more difficult to reason about to guarantee fairness and back-pressure, they're pretty much a bottleneck by design. It's just a bad idea any way you look at it.
- mananaysiempre 4y agoFrom where I’m standing QUIC looks like a good contender for a super-TCP like what SCTP never succeeded at becoming. Except there don’t seem to be any (C) libraries with ease of use and lack of inbuilt opinion approaching TCP sockets. (Happy to be proved wrong on that point!) And of course the lack of TLS-less options (outside MsQuic IIUC?) hurts experimentation severely.
- smashed 4y agoStandard posix sockets are mostly just system calls. The TCP state machine is implemented in the OS kernel. You can switch to raw socket and do the TCP syn/ack dance on your own but this is mostly done for network testing/pen testing, as there are more overhead involved, not less. This is mostly because the OS actually controls the send/receive buffers used by the actual network drivers. The userland program just takes care of filling these buffers and the kernel and drivers take care of emptying them (i.e. sending). TCP flow control is handled by the kernel, freeing the app to focus on its data. This abstraction actually works quite well. There are frameworks for userland network stacks, when you're working in high performance networking and need to avoid any overhead the kernel could introduce. The drawback is you need to implement the entire stack, including the low level driver, otherwise it would be slower than what you can already do with classic sockets.
- mananaysiempre 4y agoI referred to sockets as an API design, not to express an opinion on whether you should place your protocol implementations inside or outside the kernel. (Although that’s undeniably an interesting question that by all rights should have been settled by now, but isn’t.) Even then, I didn’t mean you should reproduce the Berkeley socket API verbatim (ZeroMQ-style); multiple streams per connection does not sound like a particularly good fit to it (although apparently people have managed to cram SCTP in there[1]?). I only meant that with the current mainstream libraries[2,3,4], establishing a QUIC connection and transmitting bytestreams or datagrams over it seems quite a bit more involved than performing the equivalent TCP actions using sockets. [1] https://datatracker.ietf.org/doc/html/rfc6458 https://datatracker.ietf.org/doc/html/rfc6458 [2] https://quiche.googlesource.com/quiche https://quiche.googlesource.com/quiche [3] https://github.com/microsoft/msquic https://github.com/microsoft/msquic [4] https://github.com/litespeedtech/lsquic https://github.com/litespeedtech/lsquic
- preseinger 4y agoHTTP/2 provides immediate and significant performance benefits for many use cases without any browser being involved at all most often, it helps when there are multiple logical connections muxed over a single physical connection
- mgaunard 4y agoIt does not make sense to ever do that, at least so long as you understand TCP.
- jeroenhd 4y agoExcept it obviously does, as demonstrated by many benchmarks on the web. HTTP/2 is faster than HTTP 1.1 for loading resources on a web page. In real life, browsers open up to four to six HTTP 1.1 connections and maintain them for pipelining. You can increase that number to pretty much anything and enjoy a web full of "permission denied" pages, timeouts and IP bans. I did that for a while when I followed one of those "how to make Firefox faster" guides as a kid, cannot recommend. That's also four to six three way handshakes, each taking several hundred milliseconds to complete with a risk of failure and retrying, most of which are pretty meaningless, with a hard limit on the amount of individual files one can request at the same time. You'll also have to deal with the traffic congestion engine kicking in multiple times when the WiFi connection degrades. There's also no real way to bypass the TCP slow start for every connection, so you'd better have an excellent connection available or you're artificially restricting your throughput when those streams suddenly start delivering data. The inline mixing of HTTP/2 removes a whole bunch of restrictions. There are still a bunch of restrictions that only got fixed in HTTP/3 but there's no doubt that HTTP connections improved when HTTP/2 came about.
- mgaunard 4y agoIf a server refuses to process N concurrent requests per second with HTTP/1.1 but happily does so with HTTP/2, the problem lies with the server, not the protocol.
- intelVISA 4y agoVery true, HTTP/1.1 was The Last Good One; engineers advocating 2 & 3 should be held in suspicious regard.
- preseinger 4y agothe limits of HTTP/1 are well-known and easy to hit in any high-volume system, browser or otherwise there's plenty to criticize about HTTP/2 and HTTP/3 but they're definitely beneficial in many circumstances