Web Performance Profiling: Google.com
requestmetrics.com
requestmetrics.com
To me it feels like an oversight when answering the question “how the hell is Google so fast?” and not digging into how Google is able to return the results to your actual search query in a matter of milliseconds. That, to me, is the real miracle.
Them being able to take your query, discover the data that answers your query, then optimize that data down to a little html snippet that fast is significantly more impressive to me.
It's from 2010, but the fundamentals probably haven't changed.
Not discounting the other magic, but exposing read-only data, close to the end user, where freshness isn't a huge concern does simplify things.
By their own metric, page 10+ take several times longer to arrive, and most search terms only have a few hundred results at best, even when showing billions of results, you only see the real number when you hit the last page. For example, for me, the word "the" only has 445 actual results (instead of 25 billions), and page 45 takes 2 seconds to complete, compared to 0.7 seconds for page 1.
In my testing, I'd set a breakpoint on my server code to see when I'd get the "push" from Twitter's API and would use the Twitter App on my phone to create test tweets. Every single time, I'd create a tweet and my server breakpoint would be hit immediately. Not soon, but immediately. I'd see my breakpoint triggered well before the UI in the app even refreshed after submitting the tweet.
They make 5x+ the next highest IC, sure. But if they worked half as much and BS'ed 100x as much they'd make 500x.
Personally, that makes me wonder a lot more than a clever combination of memcache and map-reduce.
Sending message in Slack is:
- sent to Slack servers
- bot looked up and data sent to it
- bot (on a server in DO) figures out what to do with the message (working with an MQ server running locally :))) )
- sends message back to a server (slack/xmpp/etc.)
- that message gets processed and pushed to the corresponding client
I could never properly measure the time between the original message and the translated message. It was always way way subsecond.
Everything we have now: networks, servers, code is very fast.
[1] Badly written bot here: https://github.com/dmitriid/tetrad
All of that said, if the time is measured in more than triple digit nanoseconds, relative to the hardware capabilities that we have today, it’s slow.
Please do not take that as a reflection on you personally or your work, but rather a reflection on the layers and layers of abstraction we’ve collectively added, and keep adding. While we’ve made it easier for people (especially developers) to write code, we’ve made everything slower, and just continue to mask that with hardware improvements.
On the author's benchmark, a roundtrip seems to take on average 30ms, and the time to first byte for the main content is around 140ms. Which means that in less than 110ms Google is able to parse the search query, and build the HTTP response.
I'm sure they are heavily relying on caches and other optimizations, and for tail-end requests the result might not be as impressive. But compared to many other websites in 2020 this is still unfortunately not the norm.
Yep, it is possible to craft search queries that take multiple seconds to process. Example [1]:
the OR google OR a OR "supercalifragilisticexpialidocious" -the -google -a
[1] https://news.ycombinator.com/item?id=20605589They should be doing a timed release on that. If you stop entering text for N ms, then go for a result. Otherwise they need to have cached results for a huge number of common combinations of letters, very frequently updated, for every store. It's a resource intensive thing to do well at their scale, for such a seemingly simple feature. If they are in fact caching all of those drop-down search results properly, something is very wrong on serving up the cached content.
And for the full results pages, when you try to load them for a given grocery store - the only answer I can guess for that is again mediocre caching. There usually isn't any other culprit other than that for such simple pages. In an effort to match current inventory, my guess is their caching isn't very good (constantly invalidated or rarely put into cache, so they're doing something that isn't very performant; I'd be astounded if they weren't doing some amount of caching on the results).
I believe that is called debouncing and it's something any non-junior frontend developer should have in their toolkit.
It also looks like they might first do all the work to retrieve all the results for a query. The first request is to an endpoint `search_v3/{term}?cache_key={key}` then subsequent requests are to `asyncresultset_{n}?cache_key={key}` so seems like they might have the result set cached from the first query.
The response to the autocomplete endpoint, which is fast, contains an `elastic_id` so perhaps they do partially use a document store.
[0] - https://stackshare.io/posts/the-tech-behind-instacarts-groce... [1] - https://tech.instacart.com/the-story-behind-an-instacart-ord...
Just build a normal HTML+CSS+JS site with serverside rendering, route the assets through a CDN and voila! your site will be just as "fast" as Google.
Here's a handy rule of thumb about relative costs: the cost of a byte on magnetic_disk:flash:ram is about 1:10:100. I.e. the cost increases 10x when you go to the next level.
The article compares the speed to other websites like nike.com which have nothing to do with a search engine.
I just Googled: the OR google OR a OR badger -the -google -a
it took: 5.66 seconds.
This is probably cached now so don't try it yourself, replace badger with some other weird word. :)
Probably also the sheer frequency of the terms in the OR don't help. Normally "the" would be treated as a stopword (https://en.wikipedia.org/wiki/Stop_word). But I'm not sure if that logic applies when it appears alone in a sequence of terms (as when it's the child of an OR).
Perhaps cache evicted. :D Or probably my PoP is different.
Include a cache attribute to inline resources to mark the inline resource as cacheable. Whenever an empty element with the same attribute is encountered, use the cache. Could use a header with a serialized bloom filter to convey what has been cached to the server.
I can also see how this makes integration testing magnitude easier/effective.
There's also the statistical impact of many round-trips: imagine a network where 1% of connections take 1 second, while 99% take 1 milisecond. If you issue > 100 request then most page loads will be slow.
If you want to search on file contents, use “agent ransack.
That's why people invented the backup request.
>> Make Less Requests
From 130 requests, that's an odd takeaway.
I find that even more odd that inline data is counted as requests.
edit: stand corrected, thanks for pointing out
Then try to load https://cr.yp.to
Ok now try to do a google search for dog food.
Tell me which one executes in less than a second, and which one hangs forever
Just compare the google page load if you want to compare with that ?
Firstly, cr.yp.to is hosted on some really basic consumer grade hardware most likely and has to make an additional hop through Tonga of all places for DNS resolution.
Of course, the page size of cr.yp.to is very small and does not involve any other communication with other servers to deliver a request.
But Google has x million machines, x million miles of fiber, x million sticks of ram, and the page size on google also isn't terribly huge. And it's serving a cached result usually, the robot has already scraped it.
But still, because of the number of network pings that serving a single google search takes, it is extremely common on cell phones to lose service for a millisecond and completely destroy the bidirectional connection between you and Google, and your mobile browser will just sit there hanging forever until you force restart it.
That's because google has that amount of traffic. I am sure a hn hug would take the cypto site down.
(I ask as the owner of a .so site...)
DJB uses a custom nameserver for DNS, so only one of the lookups would have to go through Tonga. The web request wouldn't leave the US (assuming that's where you are).
It goes sort of like this:
1. You query 'cr.yp.to' which your DNS server will either have cached, or make a recursive query to '.' (root DNS), then to '.to.' The '.to.' server will have nameserver information for 'yp.to.' which gets queried next.
2. The nameserver for 'yp.to' is looked up. In this case, it's `uz5jmyqz3gz2bhnuzg0rr0cml9u8pntyhn2jhtqn04yt3sm5h235c1.yp.to.'
3. The A records for that NS record are '131.193.32.109' and '131.193.32.108', both of which belong to an IPv4 block owned by the University of Illinois at Chicago.
4. Your computer queries the A record(s) for the subdomain, 'cr.yp.to.' from the nameserver for 'yp.to.' which in this case points to the same two IPs as the nameserver.
5. Depending on your OS/Browser, you will make an HTTP or HTTPS connection with that server and begin to download site content.
So, no you don't "make a hop" through Tonga, but the '.to.' nameserver will receive a request (if it's not cached by your resolver) to resolve the 'yp.to.' server.
2000-11-16: The .to administrators destroy yp.to for reasons that have never been explained.
See more here: https://cr.yp.to/serverinfo.html
They had a recent outage after 3 years
> 2017.07.24 roughly 21:50 to 22:10: Unexplained network outage at UIC.
> 2020.04.20 roughly noon GMT: Power outage at UIC.
Google search is a huge dog
Autocomplete function, dropdown menu JS, 10kb max
Considering this page is viewed by millions, and doesn't even contain the logic to render search results
To people over 30 years ago, this is a literal example of magic.
It is not. At least not in the way the article is talking about. So while yes, requests are fast, it doesn't really feel that way when I can't click anything for a good second after hitting search.
My browser takes roughly half a second crunching JavaScript, doing layout, and drawing the result page AFTER doing a whole boatload of HTTP requests. Annoyingly half that JavaScript runs AFTER the page is rendered (150ms-200ms of JS functions when I can already see results, why?), making the page appear to lag if you immediately try to click/tap something.
If they would serve the page as static html and css instead, load times could easily be below 50ms with another 20ms for my browser to present me with something that is interactive right away.
The impressive part is how fast they generate results.
Possibly that 700kB of random crap is implicated :)
When they first launched the search-as-you-type, it did feel instant but then I don't search on google.com anymore but use the chrome url bar.
And subjectively, comparing side by side, Google is faster to display the result.
So your claim of 100x is not only inaccurate in quantity, it's opposite direction as well.