[HN Gopher] Caddyhttp: Enable HTTP/3 by Default
       ___________________________________________________________________
        
       Caddyhttp: Enable HTTP/3 by Default
        
       Author : fariszr
       Score  : 227 points
       Date   : 2022-09-08 17:09 UTC (5 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | rubatuga wrote:
       | Bad idea to use HTTP/3, HTTP/2 should be good enough
        
       | michael_michael wrote:
       | Thanks for a great piece of software that I use every day in
       | production and just works.
       | 
       | At first I was scared of how stupid simple it is. It feels like
       | web servers are supposed to have giant config files with a
       | hundred mysterious knobs to twiddle. Now I always default to
       | Caddy, and have yet to find an instance where it didn't fit my
       | needs. Congrats.
        
         | lynndotpy wrote:
         | This is my experience as well. I've spent weekends trying to
         | figure things out with Apache + Nginx + Let's Encrypt. Figured
         | it out with Caddy within minutes. Really happy I found this
         | software.
        
       | mholt wrote:
       | Oh hey HN. This is in the Caddy 2.6 beta already:
       | https://github.com/caddyserver/caddy/releases/tag/v2.6.0-bet... -
       | please try it out!
       | 
       | Thanks to Marten Seemann for maintaining the quic-go library we
       | use. (I still haven't heard whether Go will add HTTP/3 to the
       | standard library.)
       | 
       | Caddy 2.6 should be the first stable release of a general-purpose
       | server to support and enable standardized HTTP/3 by default. HTTP
       | versions can be toggled on or off. (Meaning you can serve _only_
       | HTTP /3 exclusively if you're hard-core.)
       | 
       | PS. Caddy 2.6 will be our biggest release since 2.0. My draft
       | release notes are about 23 KB. We're looking at huge performance
       | improvements and powerful new features like events, virtual file
       | systems, HTTP 103 Early Hints, and a lot of other enhancements
       | I'm excited to show off on behalf of our collaborators!
        
         | purim wrote:
         | Does Caddy have the same issue with configuration spaghetti
         | problem with Traefik? How does it differ from Traefik's model?
        
           | mholt wrote:
           | I'm not super familiar with Traefik, but if you're talking
           | about using container labels for config, no, Caddy's config
           | is given as a JSON document through a REST API. The CLI can
           | let you use config files if you prefer. Or the Caddyfile is a
           | more human-friendly format that Caddy supports by default.
           | You can actually use any config format you want if there's a
           | config adapter for it: https://caddyserver.com/docs/config-
           | adapters
        
           | robk wrote:
           | Caddy is vastly vastly better in this regard. Traefik config
           | files drive me insane when rewriting anything.
        
         | asb wrote:
         | I've just moved over to Caddy and had a really good experience
         | in doing so (thank you to you and all the other Caddy
         | contributors!). One thing that stuck out to me during setup is
         | that it seemed surprising to see gzip encoding not enabled by
         | default. Wouldn't it make sense for a server that enables https
         | by out of the box with zero configuration and soon supports
         | http3 to also gzip by default?
        
           | mholt wrote:
           | Good question!
           | 
           | When I first announced Caddy in 2015 and the server got busy,
           | it started downloading everything as .gz files. (facepalm)
           | (good ol' days)
           | 
           | But that's just a fun story, not actually the reason we don't
           | enable it by default...
           | 
           | The tricky thing about enabling features by default is that
           | turning them off is awkward in config. And while we like to
           | have "magic" in Caddy, we don't like too much magic. Plus,
           | gzip performance in Go is less good (but more memory-safe)
           | than it is in C and assembly. Klauspost's flate
           | implementation is very fast and that's the one we use. But
           | even with a super-fast implementation, gzip requires memory
           | and CPU that busy servers may be in short supply of.
           | 
           | So it's opt-in for now. We can always change it later; going
           | the other way is harder.
           | 
           | (Caddy also supports serving pre-compressed files, if
           | enabled! And starting with Caddy 2.6, those can be teleported
           | at the speed of electricity to HTTP clients using sendfile.
           | HTTPS also sees faster file serving in 2.6 due to optimized
           | copying.)
           | 
           | See also:
           | 
           | https://serverfault.com/questions/296770/why-arent-
           | features-...
        
             | asb wrote:
             | Thanks for the response! I'd imagined reasoning along those
             | lines. I'd perhaps expect that people anticipating such
             | high load that gzipping output is problematic would be
             | investing enough time in server setup to review and tweak
             | these options. And for everyone else, compression by
             | default is a good starting point. Moving from Nginx (HTTP2
             | off by default) to Caddy (HTTP2 on by default) you'd
             | already need to review your setup if running a highly
             | trafficked site to ensure any reverse proxied servers can
             | handle the additional request load due to multiplexing.
             | 
             | But it's obviously a trade-off and there's lots to weigh
             | up...
        
             | layer8 wrote:
             | If gzip is enabled, is the gzipped version of a static file
             | cached in memory, or is it gzipped anew for each request?
        
               | mholt wrote:
               | Caddy doesn't cache responses by default, but you can
               | enable caching with the cache plugin:
               | https://github.com/caddyserver/cache-handler/
        
             | tyingq wrote:
             | It is an interesting decision point, and I get your
             | reasoning. But, I have noticed there are a good number of
             | websites that could be better for their users (especially
             | mobile users), because someone just took the defaults.
             | 
             | Not high priority, but if Caddy would offer a report of
             | things that aren't configured but perhaps should be...that
             | could help. Things like Cache-control/Expires/Etag headers,
             | Gzip/Deflate, Caching, and so on.
        
             | hsbauauvhabzb wrote:
             | Why was gzipping everything a facepalm? Performance?
        
               | francislavoie wrote:
               | It was making the browser download files with the .gz
               | extension, instead of serving the content in a way that
               | the browser would display. TL;DR it was broken at the
               | time. But it was a very long time ago.
        
           | JZerf wrote:
           | In addition to the reasons that mholt mentioned in response
           | to your question, enabling HTTP/GZIP compression could
           | possibly be less secure for some web server configurations
           | due to things like the BREACH attack. See https://en.wikipedi
           | a.org/wiki/HTTP_compression#Security_impl... and
           | https://en.wikipedia.org/wiki/BREACH for more info. I might
           | be wrong but I don't think that current web serving protocols
           | mitigate an attack like this. It might be better to default
           | to safe settings that don't use HTTP/GZIP compression even if
           | it might slow things down for the time being.
        
             | thadt wrote:
             | Eh, it's not just current web serving protocols. Any
             | protocol where:
             | 
             | - An application uses compression
             | 
             | - An attacker is able to supply chosen data to it
             | 
             | - The application compresses the attacker's data and static
             | secret data together
             | 
             | - The attacker is able to monitor the size of the
             | compressed data
             | 
             | - This can be repeated by the attacker a number of times
             | 
             | will be vulnerable to having its secret data stolen by
             | techniques like BREACH. If you want your secret data to
             | stay secret, don't compress it with attacker chosen
             | plaintext where the resulting size could be monitored.
        
         | fariszr wrote:
         | Absolutely awesome!
         | 
         | I have recently gave Caddy a shot, and immediately loved it!.
         | 
         | I am a bit worried about the performance deficit compared to
         | apache or Nginx, but none of my servers really have reached the
         | scale where it actually matters.
         | 
         | Its unfortunate that there is no dynamic brotli support, but oh
         | well, a trade off I'm willing to make.
         | 
         | One of things that aren't clear to me are Caddy plugins. How
         | big of an affect do they have on peformance? Are plugins a core
         | part of Caddy's usage? Or are they just exist to cover some
         | edge cases?
         | 
         | I'm thinking of using the caddy-filter and caddy-crowdsec-
         | bouncer plugins.
        
           | mholt wrote:
           | Glad you liked it!
           | 
           | Caddy's performance is competitive with nginx, but there are
           | too many dimensions to discuss here. I guarantee that for
           | most people, your web server will not be your bottleneck.
           | 
           | Dynamic brotli is expensive, as brotli compression is
           | inefficient. There are no optimized Go implementations of
           | this yet. But Caddy can serve precompressed brotli files
           | _without any separate plugins._
           | 
           | What do you mean by "what affect do [plugins] have on
           | performance"? All features in Caddy are plugins, some just
           | come installed by default:
           | https://caddyserver.com/docs/architecture -- even its HTTP
           | server is a plugin. (All plugins are compiled in natively.)
        
             | fariszr wrote:
             | > What do you mean by "what affect do [plugins] have on
             | performance"? All features in Caddy are plugins, some just
             | come installed by default:
             | https://caddyserver.com/docs/architecture -- even its HTTP
             | server is a plugin.
             | 
             | Oh I didn't know that, thanks for the awesome project!
        
           | francislavoie wrote:
           | Having plugins installed has no performance incursion at all
           | (because they don't run unless configured), but using them
           | will, of course affect performance. But it depends on the
           | plugin and what it does.
           | 
           | You have to do your own benchmarking to see what effect they
           | have to performance. Everyone has different needs and
           | configs, so it's not possible to give authoritative
           | benchmarks. Just try it out and see.
           | 
           | Regarding brotli, there is a plugin you can try if you'd like
           | https://github.com/ueffel/caddy-brotli, but brotli's on-the-
           | fly performance is not that good. It works well if you pre-
           | compress you assets though, and you can serve those with the
           | file_server directive's precompressed option.
        
       | manishsharan wrote:
       | I have been using HAproxy and it has been very performant but the
       | lack of documentation for its APIs may be the reason I will start
       | playing with Caddy.
        
         | TimWolla wrote:
         | I'm surprised you find the documentation lacking. What type of
         | API are you talking about? The internal C API? Lua?
         | Configuration? Something else?
         | 
         | Disclosure: I'm a community contributor to HAProxy and help
         | maintain the issue tracker.
        
       | CodesInChaos wrote:
       | Since address validation is about blocking senders which forge
       | their IP address, I think the number of connection attempts which
       | where the client doesn't eventually validate its address should
       | factor into the decision to enable this feature. This should
       | rarely happen for legitimate clients (e.g. connection
       | loss/cancellation during the first roundtrip) but always happen
       | for IP address forgers.
       | 
       | Or perhaps simply use the number of half-open/embryonic
       | connections as the metric.
        
         | mholt wrote:
         | Good point. Our current metric (number of active requests) is a
         | bit naive, but mostly does the job essentially for free. If
         | your proposed metric doesn't cost too much in memory, it might
         | be a good fit.
        
           | CodesInChaos wrote:
           | How does such an attacker influence your active requests
           | metric? Is it incremented when the initial UDP packet arrives
           | (even though the http request itself hasn't arrived yet) and
           | decremented when it times out?
        
             | mholt wrote:
             | No, currently we increment it when the HTTP request is
             | parsed. (It counts HTTP requests, not packets/connections.)
             | This was a quick and easy way to count; but I am very open
             | to improving this! Feel free to submit a proposal or a PR.
             | 
             | Ref: https://github.com/caddyserver/caddy/blob/50748e19c34f
             | c90882...
        
               | CodesInChaos wrote:
               | In that case, I don't think your metric works _at all_ ,
               | since legitimate users will increase it, but attackers
               | won't. During an attack it will either remain the same,
               | or even go down as fewer legitimate users manage to
               | connect.
               | 
               | This attack is the QUIC equivalent of a SYN flood, which
               | results in half-open connections, because the attacker is
               | unable to complete the connection by responding to
               | message the server sends. RequireAddressValidation
               | corresponds enabling syn cookies.
               | 
               | Unfortunately I don't use caddy myself, and don't have
               | time to get involved deeper in improving this.
        
               | mholt wrote:
               | I opened an issue with quic-go to get ideas for a better
               | metric: https://github.com/lucas-clemente/quic-
               | go/issues/3549
        
       | 0xEFF wrote:
       | I've been using Caddy in a 3 node HA cluster sharing an anycast
       | bgp address for about 18 months now and it's been fantastic.
       | Certs "just work" across the cluster once consul is wired up. I
       | recently added IPv6 which also "just works."
       | 
       | greenpau/caddy-security is fantastic and "just works" for OIDC
       | sso.
       | 
       | mholt, thanks for recently adding the ability to bind to multiple
       | specific IP addresses by default, this help me conserve precious
       | public IPv4 addresses.
        
         | jabart wrote:
         | This is a thing? Any docs on this as the top search is this
         | comment.
        
           | francislavoie wrote:
           | For which part? The comment you replied to mentions a bunch
           | of different features, and a plugin.
        
             | jabart wrote:
             | The HA Cluster with an Anycast IP.
        
               | francislavoie wrote:
               | They're essentially just saying they run multiple
               | instances of Caddy, and those instances are reached by
               | clients via Anycast. This isn't anything specific to
               | Caddy, that's networking-level stuff, in front of Caddy.
        
               | jabart wrote:
               | TCP needs a connection to be tracked or it counts as
               | invalid session since the tuple wouldn't existing in the
               | connection table. So there has to be something going on
               | or something in front of Caddy doing ip based hashing to
               | a backend caddy instance. Most anycast setups I have seen
               | have been geographic which means unless you move you
               | won't get routed to the wrong endpoint.
               | 
               | *http3/quic gets around this be setting a connection id
               | in the UDP packets so mobile phones jumping towers can
               | still be tracked if they get a new IP.
        
       | westurner wrote:
       | For HTTP/3 support with python clients:
       | 
       | - aioquic supports HTTP/3 only now
       | https://github.com/aiortc/aioquic
       | 
       | - httpx is mostly requests-compatible, supports client-side
       | caching, and HTTP/1.1 & HTTP/2, and here's the issue for HTTP/3
       | support: https://github.com/encode/httpx/issues/275
        
       | howeyc wrote:
       | does it work with "tls internal" or do the certs need to be
       | signed by an outside CA for HTTP/3 to be enabled.
        
         | mholt wrote:
         | Yes it works with self-signed certificates!
        
           | superkuh wrote:
           | I'm really glad to hear this is an option. But will browsers
           | accessing the website accept the self-signed certs when
           | setting up the TLS connection required by QUIC? I don't know
           | how they behave. I'm genuinely asking.
        
             | francislavoie wrote:
             | Yes they do, as long as you installed Caddy's root CA cert
             | in the browser's trust store. Caddy will attempt to install
             | it automatically with
             | https://github.com/smallstep/truststore if possible
             | (usually requires root) but if it fails you can try again
             | with "sudo caddy trust". You might be using a client or
             | trust store that isn't supported though, in which case
             | you'll need to install the root cert manually.
        
       | seabrookmx wrote:
       | Tangential, but Google is serving HTTP/3 by default out of Google
       | Cloud now:
       | https://cloud.google.com/blog/products/networking/cloud-cdn-...
       | 
       | Pretty cool stuff.
        
       | srameshc wrote:
       | I very recently tried Caddy for the first time and it is one of
       | the best software experiences I had especially because of it's
       | ease of use.
        
         | 41b696ef1113 wrote:
         | My only complaint with it is this half-way json vs standard
         | config file situation in which it finds itself. The documents
         | push you to the json system, but most of the available
         | documents are in the config system.
        
           | francislavoie wrote:
           | JSON is the "machine readable" config language for Caddy, but
           | a great majority of users are using the Caddyfile. What are
           | you confused about specifically?
        
           | asb wrote:
           | There's also some handy features that are only available in
           | the JSON format. e.g. `strip_path_suffix` and `http_redirect`
           | for the `rewrite` handler (https://github.com/caddyserver/cad
           | dy/issues/2011#issuecommen...), which would be a more
           | ergonomic way to set a rule to strip trailing slashes than
           | handling via regex.
        
             | francislavoie wrote:
             | While it is true that some features are only possible via
             | JSON config, the ones you mentioned _are_ available in the
             | Caddyfile. See the uri directive which lets you strip a
             | suffix, and redir which performs Location redirects. Also,
             | the issue you linked to is from an early beta of Caddy v2,
             | and the discussion and config there no longer applies.
        
               | asb wrote:
               | The uri directive does expose stripping a suffix, but
               | that's an internal rewrite, correct?
               | 
               | For any /foo/ /bar/ /baz/ I want to redirect to /foo,
               | /bar, or /baz. Unless I'm missing something, this needs
               | to be done like so right now:
               | @trailing_slash path_regexp trailing_slash ^/(.*)/$
               | redir @trailing_slash /{re.trailing_slash.1} 308
        
               | mholt wrote:
               | The uri directive can strip_prefix, strip_suffix, or do
               | substring replacements:
               | https://caddyserver.com/docs/caddyfile/directives/uri
               | 
               | It can also do regex replacements on the path portion of
               | the URI. And yes, these are internal rewrites since uri
               | is a directive that wires up the rewrite handler.
               | 
               | We actually have a special section in the docs all about
               | enforcing trailing slashes, including external redirects:
               | https://caddyserver.com/docs/caddyfile/patterns#trailing-
               | sla...
               | 
               | Note that the file_server will automatically enforce
               | canonical URIs, including redirecting to add or remove
               | the trailing slash according to whether the resource is a
               | file or a directory.
               | 
               | To redirect many unspecified paths, your regex is
               | probably the best way to do it for now. Feel free to open
               | an issue to propose an alternative!
        
               | asb wrote:
               | Thanks! I'd read all that documentation and came to the
               | same conclusion. I'm using disable_canonical_uris as I
               | prefer avoiding trailing slashes even for directories (as
               | I see it, page_name/index.html layout is an
               | implementation detail, and I'd like Caddy to expose it as
               | /page_name).
               | 
               | I'll follow up with issues tomorrow (I think an issue for
               | updating the common caddyfile patterns bit on the website
               | also makes sense - I suspect a blanket rule for removing
               | trailing slashes is more likely to be a common pattern
               | people seek a solution for than removing a trailing slash
               | on explicitly enumerated paths).
        
               | francislavoie wrote:
               | The problem is, in the browser, relative URLs (like on
               | CSS/JS assets and such) won't be relative to your
               | index.html if you remove the trailing slash, and they'll
               | instead be relative to the parent directory. That can
               | mess things up.
               | 
               | Of course if you're using absolute paths in your HTML
               | then this isn't a problem, but it does become a problem
               | if you want to move to serving this same site from a
               | subpath, because then your absolute paths won't be
               | constrained to this subpath.
        
       | Matthias247 wrote:
       | I'm curious about the implementation, and haven't looked at the
       | source of quic-go yet: Does it use a single UDP socket to handle
       | datagrams for all QUIC connections, does it use connected UDP
       | sockets per connection, or does it use multiple UDP sockets,
       | where each handle a certain set of connections - and where an
       | external load balancer is required to redirect to the sockets?
       | 
       | Unfortunately there's no best answer for this: Using a single
       | socket will allow for connection migration, but it will end up
       | being a bottleneck in terms of scalability since it will
       | serialize access on a lot of kernel and driver datastructures
       | (just a single transmit/receive queue). Connected sockets avoid
       | that, but don't allow for address migration. And doing external
       | load balancing gets far more complex than just starting a binary
       | - even the most simple solution requires running XDP code.
        
         | password4321 wrote:
         | > _connected UDP sockets per connection_
         | 
         | I think I'm stumbling over terminology here, but UDP is
         | connectionless, right? I think the QUIC protocol re-implements
         | connections on top of it, but I've never heard of "connected
         | UDP".
         | 
         | A socket pool does seem to make sense from a performance
         | standpoint!
        
           | Matthias247 wrote:
           | UDP is connectionless. Connected UDP sockets are a OS
           | construct, and don't influence anything that happens on the
           | wire. If you "connect" a UDP socket, you don't have to use
           | sendto and recvfrom anymore, and all packets received and
           | sent (via send/recv APIs) are targetting the same peer. It's
           | kind of just sets up some routes in the kernel, but doesn't
           | make anything stateful or reliable at the networking layer.
        
       | westurner wrote:
       | lucaslorentz/caddy-docker-proxy works like Traefik, in that
       | Container metadata labels are added to the reverse proxy
       | configuration which is reloaded upon container events, which you
       | can listen to when you subscribe to a Docker/Podman_v3 socket
       | (which is unfortunately not read only)
       | 
       | So, with Caddy or Traefik, a container label can enable HTTP/3
       | (QUIC (UDP port 1704)) for just that container.
       | 
       | "Labels to Caddyfile conversion"
       | https://github.com/lucaslorentz/caddy-docker-proxy#labels-to...
       | 
       | From https://news.ycombinator.com/item?id=26127879 re:
       | containersec :
       | 
       | > > _- [docker-socket-proxy] Creates a HAproxy container that
       | proxies limited access to the [docker] socket_
        
         | mholt wrote:
         | This is a little-known awesome project! If you like how Traefik
         | is configured with Docker labels but want to use Caddy, well
         | now you can have your cake and eat it, too.
        
         | francislavoie wrote:
         | The point of the link in OP is that now in v2.6, Caddy enables
         | HTTP/3 by default, and doesn't need to be explicitly enabled by
         | the user.
         | 
         | So I'm not exactly sure the point you're trying to make. But
         | yes, CDP is an awesome project!
        
           | westurner wrote:
           | That is a good point. Is there any way to disable HTTP/3
           | support with just config?
           | 
           | The (unversioned?) docs have: https://caddyserver.com/docs/mo
           | dules/http#servers/experiment... :
           | 
           | > servers/experimental_http3: _Enable experimental HTTP /3
           | support. Note that HTTP/3 is not a finished standard and has
           | extremely limited client support. This field is not subject
           | to compatibility promises_
           | 
           | TIL caddy has Prometheus metrics support (in addition to
           | automatic LetsEncrypt X.509 Cert renewals)
        
             | mholt wrote:
             | Yes, the docs have been updated at
             | https://github.com/caddyserver/website but haven't been
             | deployed yet. There is a new protocols option:
             | protocols h1 h2
             | 
             | will disable Http/3 but leave 1.1 and 2 on.
        
             | francislavoie wrote:
             | Yeah those docs are for v2.5. The experimental_http3 option
             | is removed in v2.6 (which is currently only in beta, stable
             | release coming soon). To configure protocols and disable
             | HTTP/3, you'll now use the "protocols" option (inside of
             | the "servers" global option), and it would look like
             | "protocols h1 h2" (the default is "h1 h2 h3").
        
         | fariszr wrote:
         | There is also nginx_proxy, based on nginx.
         | 
         | https://github.com/nginx-proxy/nginx-proxy
         | 
         | Note on both projects, if you care about security, you should
         | split the generator/controller container out of the main
         | webserver container, so the docker socket is not used in
         | container that is directly exposed.
        
       | kgersen wrote:
       | Beware of a performance hit (in term of bps not req/s) if you
       | push big data with Caddy.
       | 
       | Go implementation of HTTP/2 already took a /5 hit over http/1.1
       | (Go http/2 implementation is 5x slower than Go http/1.1)
       | 
       | With HTTP/3 our early benchs indicate /2 ot /3 from HTTP/2 (so
       | /10 from http/1.1)
        
         | mholt wrote:
         | Marten is in the process of making a bunch of optimizations
         | [0], as are we within Caddy, and 2.6 includes some of those. It
         | will only get better with time.
         | 
         | Most users do not operate at nearly the volume required to feel
         | the impact, including enterprises.
         | 
         | Would be interested in repeating your experiments and knowing
         | your real world use case and seeing how similar they are.
         | 
         | [0]: https://github.com/lucas-clemente/quic-go/issues/3526
        
           | kgersen wrote:
           | We do speed tests hence we saw the issue. See
           | https://github.com/golang/go/issues/47840
           | 
           | Yeah I agree this is a edge case, 99,99% of Caddy users don't
           | push so much data ;)
           | 
           | But Caddy can't be used as a big files download server for
           | instance, unless sticking with HTTP/1.1 (that and sendfile +
           | kTLS not been supported last time I checked?) (at least with
           | a single http instance).
           | 
           | Another issue for HTTP/3 is https://github.com/lucas-
           | clemente/quic-go/wiki/UDP-Receive-B... Current Linux in WSL
           | for instance has this issue. This will probably resolves over
           | time as more and more Linux distros will take HTTP/3
           | requirements into account.
        
         | Matthias247 wrote:
         | with BPS you mean throughput on a single request? On an
         | unconstrained connection (like loopback)? In this case you are
         | mostly measuring CPU efficiency, since for a real world
         | deployment the network connection would likely be the
         | bottleneck. In that real world setup then loss of CPU
         | efficiency becomes a scaling challenge, which actually makes it
         | less RPS.
         | 
         | Btw: A good recommendation for anyone doing benchmarking is to
         | both measure throughput for a single connection, but also
         | throughput for the whole server when using lots of connections
         | (e.g. 100 connections per core, and each connection doing
         | multiple concurrent requests). The latter will point out
         | further scaling issues.
         | 
         | In terms of full system efficiency HTTP/2 vs HTTP/1 (with TLS)
         | is actually not that bad for good implementations - might have
         | 10-50% more cost but in the end the performance critical parts
         | (doing syscalls for TCP sockets) are the same for both. QUIC
         | can be much worse. Well optimized setups (which e.g. use
         | optimized UDP APIs with GSO or even XDP) somewhere between
         | 50-100% more expensive than TCP+TLS setups. And simpler
         | implementations can be 5x as expensive, and might not even
         | scale beyond a single CPU core.
        
       | pachico wrote:
       | Weirdly enough, among the reasons to switch from nginx to Caddy I
       | never find the lack of observability nginx and its almost useless
       | Prometheus exporter have.
       | 
       | I see several posts discussing under which circumstances or use
       | cases one might outperform the other but they never seem to care
       | about having decent metrics.
       | 
       | I might overrate the importance of this, who knows...
        
         | nginxlegacy wrote:
         | nginx was great for its time - glorious even compare to Apache.
         | 
         | Now it is legacy software being run into the ground.
         | 
         | It's old school, has idiotic defaults, is poorly supported
         | unless you pay thousands of dollars, and has terrible language
         | integration. People aren't writing internet scale software in
         | lua for a reason.
        
           | excitom wrote:
           | Wow, that's some unsubstantiated mud slinging.
           | 
           | On the paid support point: Isn't that the model for all open
           | source projects that want to progress past the "If you like
           | it, please donate" stage?
        
           | xet7 wrote:
           | Aren't? But there is https://redbean.dev that uses Lua, and
           | is faster than Go.
        
             | coder543 wrote:
             | Redbean is a webserver. Go is not a webserver. Redbean
             | cannot be "faster than Go". That's like saying that a car
             | is faster than aluminum. Do you have benchmarks of Redbean
             | versus Caddy that you can point to? I certainly haven't
             | been able to find any.
             | 
             | I also haven't been able to find any in-depth independent
             | benchmarks of Redbean. About the only thing I could find
             | was someone struggling to reproduce the benchmark
             | results.[0]
             | 
             | Personally, I've dealt with more than enough memory safety
             | vulnerabilities caused by no programmer being good enough
             | to write safe and correct C (or C++). Those vulnerabilities
             | are easily prevented by choosing just about any other
             | language people are likely to know about... so, I have no
             | desire to deploy anything like Redbean when alternatives
             | exist. It's cool to see the hacks they've been able to do
             | with Cosmopolitan to make cross platform binaries, but
             | hacks like that are not what I want for anything other than
             | educational purposes, at least not until they've been more
             | battle tested.
             | 
             | [0]: https://github.com/jart/cosmopolitan/issues/72
        
               | mholt wrote:
               | Great points. I also think it's important to stop
               | deploying C to the edge.
               | 
               | PS. Go might someday compile for cosmopolitan if someone
               | writes a port for it:
               | https://github.com/golang/go/issues/51900
        
               | xet7 wrote:
               | I did see that benchmark result previously but did not
               | find that page yet with quick look.
               | 
               | From https://redbean.dev is this:
               | 
               | "If you want Rust-like promises then redbean can be
               | compiled with ASAN memory safety. Cosmopolitan Libc has
               | the only open source implementation of the Address
               | Sanitizer runtime that's intended for production use. It
               | causes redbean worker processes to crash and log a report
               | should a bug like a buffer overrun, use-after-free, or
               | stack smash occur. This has a marginal impact on
               | performance. It can be useful in environments where
               | interruptions in a service are more desirable than
               | risking the system being compromised."
               | 
               | More at https://redbean.dev/#security
        
               | coder543 wrote:
               | ASAN by itself cannot make those guarantees, from what I
               | understand. Cosmopolitan would also have to make sure
               | never to reuse virtual memory addresses for a start, and
               | there's actually even more to it than that. So, no, I'm
               | not impressed by arbitrary claims like that. It's such a
               | bold claim. If it were true, Apple and Google would be
               | adopting this ASAN implementation ASAP since they have
               | tons of C and C++ code that would benefit from better
               | safety at marginal performance cost.
               | 
               | In the mean time, if Redbean and Cosmopolitan want Rust-
               | like promises of memory safety... they need to write it
               | in Rust.
        
         | tmpz22 wrote:
         | What would decent metrics be to compare the performance of
         | Nginx and Caddy?
        
           | francislavoie wrote:
           | It's not really possible to compare the performance of
           | webservers apples to apples. Really, you need to do your own
           | benchmarking to determine which solution is best for you. But
           | keep in mind that the web server is rarely the bottleneck,
           | usually your app and database IO are where it takes the most
           | time.
        
             | password4321 wrote:
             | What is this I'm reading here, the voice of reason?!
             | 
             | The last frontier for these types of comparisons is unusual
             | circumstances like embedded platforms with limited
             | resources.
        
             | pachico wrote:
             | Indeed, this is why those hello world benchmarks are just
             | noise.
        
       | nykolasz wrote:
       | Will have to give Caddy a try. Been a long time nginx user, but
       | they have been very slow to implement new features (including
       | HTTP/3), unfortunately.
        
         | number6 wrote:
         | I tried caddy for my home setup. Replacing nginx and traefik. I
         | am wondering if I should ditch them in production too. I am
         | hesitant, cause I don't see caddy as "business" software: nginx
         | has a learning curve and configuration to master, where caddy
         | just does the job, sane defaults and not much to "work". It
         | just doesn't feel like work using caddy...
        
           | francislavoie wrote:
           | Large companies like Stripe use Caddy. It's definitely not a
           | toy. It is, and has been production ready for many years.
        
             | number6 wrote:
             | I guess it's just me than; all the stuff I have learned:
             | setting the right labels for traefik, debugging it for
             | hours. Now it's just:
             | 
             | ```
             | 
             | caddy: example.com
             | 
             | caddy.reverse_proxy: {{ upstream 8080 }}
             | 
             | ```
        
               | francislavoie wrote:
               | Yep! The CDP plugin
               | https://github.com/lucaslorentz/caddy-docker-proxy makes
               | configuration per docker service pretty easy!
        
         | fariszr wrote:
         | It should come in the next release
         | 
         | > Two critical capabilities for security and scalability of web
         | applications and traffic, HTTP3 and QUIC, are coming in the
         | next version we ship
         | 
         | https://www.nginx.com/blog/future-of-nginx-getting-back-to-o...
        
       ___________________________________________________________________
       (page generated 2022-09-08 23:00 UTC)