Do svidaniya, Igor, and thank you for Nginx
nginx.com
nginx.com
Some of the container/orchestration world has tried to supplant the need for it as a reverse proxy, but you get so many goodies out of the box just by sticking this in front of your app, and for very little overhead.
I remember the pre-Nginx days and all of the struggles people routinely ran into with options like Apache or other reverse proxy tools.
I feel like I knew at one point why it got so thoroughly supplanted by nginx but I don't remember now why that happened.
This was 2006 and nginx was the only realistic alternative on the market. It worked beautifully since day 1. It saved my startup. Next year we got acquired by Google.
I only got 1 crash with nginx and it was partially my fault, I had an "expires 30y" on some images, and a morning on feb 2008 I came to the office and the whole site was down. After a very quick gdb session under panic I realized it was trying to get a weekday name on an array with a negative index. Nginx was adding 30 years to the current date and that was over 2038 and it overflowed. Igor fixed that issue in hours, and he graciously explained that I could have used "expires max"
Nginx has powered all my startups since then (Freepik, Flaticon, Slidesgo, Besoccer).
This guy has added more real value to the economy than most unicorns. A true hero.
This classic 2007 tutorial starts by pointing out that NGINX parses the HTTP verb by looking at the second letter first, so that if it's O it knows to check for POST or COPY!
https://web.archive.org/web/20070505051653/http://www.riceon...
I think that if you want to support all verbs, you face at least 3 'ambiguities' whether you first check the first, second, or third character of the string. (It must be at most the third, as the shortest verbs are 3 characters long.)
First checking the first character is ambiguous between POST, PUT and PATCH. First checking the second character is ambiguous between HEAD, DELETE, and GET. First checking the third character is ambiguous between GET, PUT, OPTIONS, and PATCH. [0]
edit As danachow points out, the verbs are not all used with the same frequency. If real-world performance is the goal we'd presumably want to optimise for the GET case, which presumably means first checking the first character, as the 'G' is unique to GET.
[0] https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
if (m[0] == 'G') {
r->method = NGX_HTTP_GET;
break;
} else if (m[0] == 'P') {
switch(m[1]) { ... }
} else if ...
this should be fast enough.First, the async model was literally years ahead of Apache. It leaned heavily on interfaces like epoll to manage large connection pools with a small number of processes, while Apache still used a thread or process per connection.
Second, it removed exactly the right features - those with minimal benefit and high performance impact. The classic example is .htaccess, which adds (at least) one stat to every single request, but in practice was only needed for the horrible multi-tenant LAMP reseller setups of the day - everyone else was fine with static centralized configuration.
The Architecture of Open Source Applications - volume II - nginx:
Here's there I ended up: https://github.com/nginx/nginx/blob/363505e806feebb7ceb1f9ed...
PS, I'm not totally sure, but they definitely use the count of letters as an optimization, and it seems they increment the bits associated with each type, so the order of the bits behind each NGX_HTTP_GET etc seems to matter...!
https://github.com/nginx/nginx/blob/67d160bf25e02ba6679bb6c3...
Someday I will understand :)
ngx_http_v2_parse_method iterates through all the tests, starting with the first test (GET).
They compare request method string length to test string length then on matching lengths compare each character in the request method string to the test string.
Fully matching strings set the request method numerical value from the test value and returns OK.
Any non-matching characters GOTO the next test.
After that it does a sanity check on the request method string characters (A to Z or _ or -) and returns OK or DECLINED as appropriate.
For the macros defining the HTTP method numerical values I think they're set up that way as bitmasks for bitwise operations.
For example, they do things like[1]
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD)))
Here HTTP request method value is bitwise AND against (0x00000002 OR 0x00000004)Any non-zero value here would be true and any zero value is false. So if the request method bit value AND matches either GET or HEAD bits then this conditional is false.
[1] https://github.com/nginx/nginx/blob/a64190933e06758d50eea926...
But there indeed came a time (maybe 2010ish?) where nginx took the lead with gread strides and most people (even the die-hard fans) mostly moved to nginx, that's about when it was clear that it would probably win and stay for the forseeable future. Back in those circles at least (see some other comments for the PHP FPM story) Apache was only kept for setups with lots of different other dependencies, like mod_svn or webdav, if you "only" needed a webserver to front PHP it was nginx.
I also remember many people holding out on adopting Apache 2.2 for a looong time.
With Apache, at their current max load, the systems would just completely fall over, but with lighttpd, at that same load, the system breathed a little hard. I could push lighttpd 10x more before it fell over.
Then we started looking at replacing the haproxy solution, and I looked at nginx. I tried it out. I also tried out replacing lighttpd with nginx. And no matter how hard I pushed nginx, I couldn’t get the damn thing to breathe hard. I couldn’t even push the load average up over 1.0.
We went back to lighttpd and haproxy because those tools gave us better monitoring and logging, but we always held nginx in our back pocket in reserve, in case we needed another 10x beyond what lighttpd+haproxy could do.
And yes, I did get invited to Edinburgh to do a nice little talk on the subject.
They had their ups and downs over the years, but ihiji did end up getting acquired by Control4, and the founders are now off doing other weird and cool things.
https://serverfault.com/questions/330413/lighttpds-memory-le...
We were serving dynamic content via FastCGI, IIRC.
This was a long time ago and I'm pretty hazy on the details, but I'm pretty sure I remember finding memory leak bug discussions on the lighttpd website around that time, and no clear answers on how to avoid it.
The proper workaround was to send an X-Sendfile header to instruct lighttpd to fetch the file itself, instead of serving the content directly from the backend. It was also more efficient, but it required changes to backend code that made it less portable. I don't know if the bug was ever fixed as lighttpd development had slowed to a crawl and nginx arrived just in time to take away all the market share.
The introduction of PHP-FPM around the same time was another factor that favored nginx, because lighttpd typically integrated with PHP using a more fragile setup called fcgi-wrapper. PHP-FPM was much nicer to work with, and nginx could even load-balance across FPM pools. A lot of WordPress sites switched to nginx and never looked back.
Back then people were getting into using VPS services like linode, and memory usage mattered a lot.
It does mean you are doing health checks from each client service/app, but it only eats a few mb of ram, and then you don't have to deal with making your haproxy service HA :}
https://i.imgur.com/pjU1G61.png
https://trends.shodan.io/search?query=http+port%3A443#facet/...
I'm a bit surprised it didn't happen earlier as it feels like it's been the dominant choice for tech people.
I've founded and grew several webhosters, one specialised in WordPress. Our HTTP stack was varnish->nginx(loadbalancer)->nginx->phpfpm.
It was pain. Not even WordPress core could (can?) run all its features; e.g. the SEO-friendly-URL thing relied (relies?) heavily on - I kid you not - rewriting the .htaccess file from the CMS: really: the CMS rewriting webserver configuration files from the web.
Let alone all the plugins and themes. The community of plugin and theme devs is generally professional, but there is a staggering amount of stupidity found. Like a payment-processing plugin that would write all its payments into [bankaccount-number].txt files. Web-readable. Obviously a severe security breach for one of our clients. The plugin-devs reaction? "Not a bug: we include a .htaccess that denies access to those text-files. So no-one can read them but the plugin". I can't even...
Point being: WordPress is highly coupled to Apache. If you want smooth experience of hosting, just go for Apache. Or don't use WordPress. I'd advise the latter.
But I just looked, and the official lesson on "installing wordpress" mentions only Apache[0]. As does the "how to install WordPress"[1]. Though checking a recent download, I see that it no longer ships with .htaccess by default, so apparently things are changing.
[0] https://learn.wordpress.org/lesson-plan/local-install/ [1] https://wordpress.org/support/article/how-to-install-wordpre...
I also expect ngx_lua did a lot for adoption, the fact that you could always "shell out" to lua if you needed was a huge boon even just for peace of mind.
If I have one gripe about NGINX it's that its configuration is a still-half-baked DSL that has quirks you wouldn't expect and when they error you don't get great feedback.
Examples: You can have an if clause, but no else attached. You can't have an if clause with multiple conditions. Finally, "if [might be] evil." 1
You end up writing a bunch of partitioned control flow statements and you're never really sure at what level of config hierarchy they would best be applied.
I love the product but Apache's XML versus NGINX's semi-declarative, hierarchical blocks aren't night and day better.
1 https://www.nginx.com/resources/wiki/start/topics/depth/ifis...
My dream web server has Nginx's capabilities and Lighttpd's Lua configuration files/scripts. Is that what ngx_lua does? I've heard of it before but never really gave it a look.
I've seen these manifest in the wild as stuff like:
if ($thing ~* (match)) { $setWeirdVar = "Y"; } if ($otherThing = "value") { set $setValue "${setWeirdVar}E"; } if ($thirdCondition ~ (another|match)) { set $setValue "${setWeirdVar}S"; } if ($setValue = YES) { # do a thing here }
As clunky as that is, I've found it recommended in SO threads.
I would prefer a simple JSON file any day. Or some Lispy S-expressions. Or some TOML or well structured XML and XSD even.
NGINX makes you learn another lang only for one tool and for a config, which mostly (always?) does not need anything more than being declarative config.
<Perl>
# dynamic perl config goes here..
</Perl>The exact same argument can be made to explain why nginx is undercounted. A lot of setups will run nginx behind proxies, so you'll count a proxy: a Varnish, a single nginx, cloudfront servers (are they running nginx?) while in reality there may be many nginx-es running.
Nonetheless: nginx is a gift and thanks go out to Igor, regardless of how good the spiders can count the number nginx instances.
(Unless you don't mean Apache webserver but rather some other Apache product)
However, for better or worse, a lot of the software people want to run on shared hosting come with a .htaccess file and documentation for how to configure it otherwise. So we gave customers a choice to put Apache behind nginx.
Unfortunately I left too early to learn what %age of customers ended up enabling Apache but they‘re still running this architecture today.
In my case we scaled Drupal and Wordpress sites by using Varnish as a reverse proxy cache in front of Apache. But then we wanted to go HTTPS across the board, which Varnish does not handle. So we terminated HTTPS in Nginx and then passed the connection back to the existing Varnish/Apache stack. I know other folks just skipped or ripped out the Varnish layer and used Nginx for both HTTPS and caching.
At the time both Drupal and Wordpress (and other popular PHP projects) depended on Apache-specific features for things like pretty URLs and even security. Over time, the community engineered away from those so there was little reason to prefer Apache anymore.
Then everyone moved to ruby and python (and also perl) and mod_php stopped being an advantage.
Also the Apache that was beaten was Apache 1, which was fork-only, and that was the whole reason Nginx was written in the first place.
Then Apache did Apache2 with mpm modules and badly missed the mark. After that Apache was doomed. No async support == dead. It was that simple.
And post-FCGI's adoption, you didn't need to use Apache, so... why use it?
I've always felt like Nginx "just works" by default and creating configurations is relatively easy.
I used lighttpd for this, mentioned in another thread, rather than nginx, which was a similar breath of fresh air coming from Apache -- not only for the event loop model built around epoll and friends, but also the configuration and general deployment.
The syntax to configure is clear enough while not being super verbose…
This is why email is now more or less the domain of a couple of very large companies.
I think it was like Microsoft.WebMatrix.Data
It essentially was a micro ORM written using dynamic but had no caching so it performed terribly with all the reflection. It was a drop in replacement to use Dapper. But dapper was dismissed due to it being “Demoware” despite it running stackoverflow. I left that place 2 weeks later.
Don't get me wrong, I am an nginx user now for the past decade at least but when it first came out I was very skeptical. People were saying apache was too bloated but you could already run apache with as few modules as possible so that was a false argument.
Then there was the c10k challenge of course. Basically, a lot of hype for nginx but it came out on top in the end so I guess it doesn't matter.
Your approach might have led you to invest heavily in lighttpd at some point in time.
It takes years to to tell if serious vulnerabilities are being found often or not.
Arguing that it wouldn't have provided enough benefit to justify the switch is different than saying it was unproven by that point.
If Apache did everything they needed I can imagine a company to completely forgo investigating Nginx and this might have been cause of that kind of statement. Or maybe this was just a way to explain it to younger devs who could not understand "don't break it if it works". We don't know.
The correct way to decide this kind of decision (and many other) is to look at the RoI and your available bandwidth to run multiple projects.
I am still keeping some very old (but still actively developed) products. I am busy with other projects and there just have not been any pressure to update. When I have some time available I prefer to choose a project with highest RoI rather than update stuff because of peer pressure.
That said, by that time Nginx was a proven performance upgrade over Apache 1.x and 2.x. Quantifying that value is tough but it certainly had value attached to it.
Many software projects fail by facing delays due to excessive complexity and tech churn. Moving carefully helps.
Absolutely - but again, that's apparently not why NGINX was dismissed as an option.
N.B. From Nginx company history on Wikipedia:
> On 12 December 2019, it was reported that the Moscow offices of Nginx Inc. had been raided by police, and that Sysoev and Konovalov had been detained. The raid was conducted under a search warrant connected to a copyright claim over Nginx by Rambler—which asserts that it owns all rights to the code because it was written while Sysoev was an employee of the company. On 16 December 2019, Russian state lender Sberbank, which owns 46.5 percent of Rambler, called an extraordinary meeting of Rambler's board of directors asking Rambler's management team to request Russian law enforcement agencies cease pursuit of the criminal case, and begin talks with Nginx and with F5.[2]
[0] https://www.opennet.ru/opennews/art.shtml?num=56535
Anyways, https://tadviser.com/index.php/Company:Nginx everything is dropped in Russia, there's a lawsuit in the US but at first the court dismissed the whole thing in 2021, I expect that one go exactly nowhere.
Not sure when it happened, but Wikipedia has long been a collection of fiefdoms, jealously guarded by power users and their sycophants.
The lesson here is that, open source or not, you always need real documents to demarkate your IP, otherwise you're asking for trouble later down the line.
In typical US or UK companies software written would just go to the company, period. Here's a good article from Spolsky on how this works:
https://www.joelonsoftware.com/2016/12/09/developers-side-pr...
However, your reference to Spolsky is not correct as nginx was not a side project, but a core work project that powered all of Rambler's properties. The situation is similar to a Yahoo employee open-sourcing the Apache Traffic Server (very similar project with similar timelines, by the way; Rambler was once the "Russian Yahoo", while Yandex is the "Russian Google") and then Yahoo 10 years later claiming the open-sourcing was illegal. I understand that something may have been done wrong (and that's why I appreciate Eclipse and Apache legal team support and due diligence), but I have a hard time believing that Rambler didn't notice its core internal project being open-sourced for 10 years.
TL;DR: the Russian investigators closed the case of Rambler Group against Nginx/T5 in 2020 "for the absence of a crime event". Another company co-owned by the same owner of Rambler Group started a case in the USA but it was dismissed by a court in California in 2021.
Bravo
Dos Vidaniya
instead of (the correct)
Do svidanyia
My Russian studies is limited to listening to Sean Connery in The Russia House, and I guess I took Dos from the latin languages. Odd.
I've just counted: only on the 13th paragraph I could get the answer.
which would seem to imply "not dead". but given the tone of the first three paragraphs i think even that is a bit too late in the post to clarify.
I know hardly any Russian, only about enough to recognise "da svidanja" as "goodbye", so I'm not sure "in what language" I digested the headline (=link here on HN) -- probably a bit of all of my eclectic blend of European ones... But to me it certainly felt fifty-fifty whether it was a "changed jobs" or a "dearly departed" post. Checking which it was probably constituted my main reason for clicking through.
Same thing, my first reaction was "oh my god, no, please no" and I rushed to see if he's alive.
I imagine a situation: EN copywriter asks a RU colleague how to say "Goodbye", gets "Do svidaniya" as a transliteration without a context, and just puts it there. Which sounds like farewell.
Svidaniye (Свидание) has several meanings:
- most common modern single-word usage is for date as in “romantic date”
- archaic is for “meeting” that remained in this goodbye form.
So “do svidaniya” is literally for “till we meet again” :-)
As the preposition is so small, it's considered together with the following word, which in the genitive has its stress on the "а".
vid: videt' = to see, vid as in video
anie: just a suffix like "ing" in english
"till together-seeing"
Colloquialise that from the formal exact "Til we meet again" to be a bit more informal (because that can still be read as "...in Heaven"), and you'd get something like
"Do svidaniya (=See you later), Igor, and thank you for Nginx"
...which probably would have been much less likely to make half the readers start to tink he'd died.Is this simply referring to event-driven I/O (using select, epoll, or the like), or something else? I'm pretty sure event-driven, as opposed to forking or thread-per-connection, web servers were well established by 2002, though perhaps primarily in commercial products like Zeus.
> In particular, Igor sought to solve the C10k problem – handling 10,000 concurrent connections on a single server – by building a web server that not only handled massive concurrency but could also serve bandwidth‑hogging elements such as photos or music files more quickly and efficiently.
...I'd love to hear more details
> Igor came from humble beginnings. The son of a military officer, he was born in a small town in Kazakhstan (then a Soviet republic). His family moved to the capital Almaty when he was a year old.
I wonder what this is really about.
Either way Nginx is the reason myself and many others were able to survive without raising venture capital because we didn’t need a massive horizontal cluster of Apache servers consuming 20 to 100Mb per concurrent connection. Personally I scaled above 100k current connections on a single front end nginx box with 6 Apache application servers on the back end in 2007 thanks to Igor’s incredible work. He really has made a massive contribution to the fundamental plumbing of the Web and should be recognized for it.
Maybe just that? That's pretty much what retirement is about, also. Doesn't say that Igor won't work on personal or even non-personal projects at all, just that more time will be available for, well, friends and family.
I left due to burnout and failed negotiations. I did share the burnout with my team individually.
At least in my personal experience, when this happens to a senior leader it's usually because they had been informed by others that they WOULD be resigning.
> a high schooler in the mid‑1980s
Seems like a good time to spend with family to me.
Usually not, but that's the nice part of this kind of letter; it's always plausible.
I'm not saying "usually" like it's 98%... more like 70% odds.
There are three things I think stood out (not tied to C10K):
1. The configuration format is light-weight. Compared to Apache, lighttpd and others at the time, you could build a static file server or a reverse proxy in just 3-4 lines of configuration. It lowered the bar of entry, and is probably what led to wide adoption.
2. The core of Nginx was (is?) an async data pipeline. The individual modules (proxy, file system) defined how the pipes tie together, but the actual pumping of data was done in a kernel. You never had to care about epoll(2) and the like; you just defined the DAG. And that was easy to do correctly even in bare-bones C. This was a good architecture.
3. Single-threaded IIRC, which might be the C10K answer you were looking for. Apache had the complicated configuration where you had to decided to use prefork, or threads, or...
Lastly, it was fast. Probably because of (2), and a prerequisite for (3).
If someone is interested in reading more, "Flash: An Efficient and Portable Web Server" is a good read on the topic: https://www.usenix.org/legacy/events/usenix99/full_papers/pa.... It has no relation to Adobe Flash.
epoll has the advantage of operating in O(1) time rather than O(n) time as well which becomes important when you have a lot of file descriptors.
I'd also note that epoll landed with Linux 2.6 so it wasn't really available before 2004. Apache Server was created in 1995 long before epoll and Nginx was initially released in 2004. It's one of those situations where you introduce new capabilities like epoll being able to handle lots of FDs in O(1) time and someone finds a way to use that capability to make something great.
This is a very good article which goes into details, highly recommended
I hope I'm wrong but this could be an indicator of some changes F5 is about to introduce.
My interpretation of the history is that Igor first solved the scalability problems for a direct need (IIRC he was working for a large Russian website at the time[3]), while doing that probably realized that the Apache code base could be replaced whole-sale to do more than just HTTP proxying, and introduced the async approach to make it scalable itself, too.
[1] IIRC I saw the public NGINX announcement a few months after starting to use mod_accel. [2] Amazingly the page is still up: http://sysoev.ru/en/apache_modules.html (and it is still linking to the "Babelfish English translation" that I made by auto-translating and manually cleaning up the docs and that I hosted on a DynDNS domain that I've long since lost). [3] Rambler, from reading the other comments here.
(More seriously though, his work is impressive and I hope his next adventure is at least as fulfilling).
so much of the NGINX product that aligns with F5 as a competitive element is essentially already implemented and free by people who are already completely competent in load balancing. unless companies seek to reduce risk by bolting on a support contract...why F5 at all?
can someone from the biz side of the HN house chime in perhaps?
For any large company, the easiest way to enter a new market is to just buy some of the competition. Of Nginx's competitors, most are either not "enterprise-y" enough (Caddy) or are already part of the CNCF (Traefik, Envoy). Really, I think the only other option could have been HaProxy.
[0] https://www.geekwire.com/2017/amazon-web-services-secret-wea...
So natural question, how long until they start squeezing more money out of users and how severe will it be for hobbyists and small companies?
* arriVeDerci (Italian)
* auf WieDersehen (German)
* ¡hasta la Vista! (Spanish)
* do WiDzenia (Polish)
* do sViDaniya (Russian)
* la reVeDere (Romanian, (because I'm Romanian and it seems like an important language to mention))
[1]: https://en.wiktionary.org/wiki/Reconstruction:Proto-Indo-Eur...
sehen means "to see" and does not have your PIE root.
s-vid... - means completed action, as in "to spot".
...vid-anie - a noun version of the same.
s-vid-anie - an event of managing to see someone/something.
do ... - until ...
Pretty logical, actually.
Often used ironically by movie villains. In English it might almost be taken as a threat.
Why did Apache never become a real competitor? I didn't A/B test with Apache and Nginx - I just read slashdot and later HN, and I trusted people who ran much bigger sites. But how could Nginx take such a lead that Apache could never catch up to?
If you're pre-forking, you really shouldn't scale the number of children up and down, it should always run the maximum number you want to run (whatever that is). Because a connection ties up a child, you need to do a bunch of stuff to limit the time you need apache to be touching the request; you really should run an os with accept filters, and not touch the connection until the request is ready; you need a large socket buffer so you can write the whole response and close the socket and let the OS finish sending it while Apache works on the next request; you also need to disable http-keepalive (or do something crazy; Yahoo had a 'cheapalive' daemon that would pass client sockets back and forth with (y)apache --- when the connection was idle, pass to cheapalived which puts it into a select (or kqueue/epoll, I don't remember) loop; when a socket had data to read, it would be sent back to (y)apache to process the request.
But the apache documentation wouldn't guide you into any of this, really. You'd try a normal seeming config, get things that worked, until it got busy, then spun up too many children and ground to a halt, probably swapping excessively on the way. Or just had too many people trying to do keep-alive and have 0% cpu and doing nothing. Or maybe spinning your wheels trying to get threaded mpm's to work (but they don't work with most of the popular mod_X's anyway). The market seems to be telling us that a big kqueue/epoll is the solution we want, but well tuned pre-fork can also do a lot; it kind of depends on if your bottleneck is the http server or if your bottleneck is your application code. If you've written your application code well enough that the http server is the bottleneck; congratulations! (or you might be a static content server, but then your bottleneck might well be your NICs or your OS TCP stack)
I read that in the last 10 years or so, this is what has happened to other successes like Slack etc : The users are becoming the decision makers as opposed to CXO handing down tools. I think developer advocacy was one of the major reasons.
I remember when I saw the nginx code for the first time - I was so impressed that I wanted to build libnginx.a (of core data structures) for my own projects. Never happened.
The only comparable story I know is Rob Pike - similar principles and obsessions of doing just right, which, in turn, is related to good mathematics of finding and using just right abstractions by generalising from actual pattern.
If you want to learn C programming (and programming in general) read nginx and unit(nxt). Look how systematic, minimal and just right is everything.
I like to than Igor for teaching me and being an example.
Why are the nginx workers implemented as processes sharing memory, rather than threads? Is that so they can have different privileges in the Linux permissions/ownership model?
Is it easy to create multiple processes sharing memory in Linux? How do I go about doing that?
Vow, for a rare occasion that one translates rather nicely.
The reason being that (unless my information is stale), NodeJS will happily accept all the connections thrown at it, eventually causing each connection to be starved of compute capacity and finally falling over. HAProxy is able to keep a connection queue and feed a maximum of (for example) 4 concurrent requests to the backend(s), thus providing back-pressure to incoming requests. Makes it a lot easier if you need to eventually scale your app horizontally, too.
NGINX can do this as well, either with the "max_conns" parameter for upstreams, or (trickier, but perhaps more effective when the upstream is async) in combination with rate limiting:
limit_req_zone $server_name zone=root:10m rate=100r/s;
limit_req_status 429;
location / {
limit_req zone=root burst=100 delay=4;
}Let's Encrypt can automatically add lines to the nginx config that enable SSL, but in some cases it doesn't work properly and the config is malformed. In any case not hard to fix.
I wonder if using English letters to write Russian phrases is acceptable practice for native Russians.
Does it sound respectful, neutral or like a mockery?
I don't mean in context of that post, which obviously is respectful, but in general. Especially when unicode is a thing and you could just write до свидания
Flip note: the letters are not 'English', they are Latin (or Roman).
Back on topic, as a speaker of another language using Cyrillic, for me romanisation is perfectly normal/expected in this context. I don't expect English speakers to have to learn a new alphabet just to be able to read the title of a blog post which is otherwise in English.
Back when texting (SMS) was still a big thing, you had a choice to either write in English letters and enjoy 140 char limit per message or write in Cyrillic and have it reduced to 70 chars. Many were doing the former. I assume many other countries with non-latin alphabet had the same.
Glad to see everything's fine.
If you run with a lot of "identity fuzzers" (browsing through Tor, JavaScript off, cookies banned), Cloudflare can't build its trust heuristics and needs to challenge-response more often. I suspect there's overlap between HN readers and use of those sorts of tools, so I think there is a disproportionate number of people around here who run into this issue (whereas most "regular" folk almost never see a Cloudflare challenge / response).
(To be fair, consecutive requests don't get this treatment, just the one in which I jump there from eg. a search result.)
The wording "heuristic trust model [...] trust signals from the client", would not be out of place in the context of a sigint discussion.