1. 41

  2. 17


    43000 users making 100 hits per day is 500 requests per second, which should comfortably run on someone’s laptop.

    Just saw the end of the post where he says traffic is 10x lower than that! You should not need 40 cores to run this.

    Consider putting a tiny bit of effort into optimisation before burning money on your cloud provider. Consider using something other than rails so you don’t throw away 2 orders of magnitude from the first line of code.

    1. 12

      500 requests per second is pretty hard to serve if you do any real work

      Let’s assume 4 cores, so you get ~8 ms per request to keep up? That’s barely a couple postgres requests!

      Obviously you want to be caching things, and a lot of requests are going to be for static files. But if we’re talking about “real work”, IO’s going to chew into that pretty quick I think.

      1. 4

        It’s pretty hard if you build things following modern web development practices, which optimize for developer time & ease of operation rather than performance.

        A 5-year-old consumer desktop would be more than fast enough if you cared to optimize the code, but the author has (imo very reasonably) decided that his time is more valuable than that.

        1. 11

          Since I was interested in hosting my own node, I looked into it a bit, and one problem in particular is that there is no implementation of OStatus that exists as just a classic network-daemon style library, a libostatus or such. Instead the way it developed is that OStatus is a particular style of using a combination of various existing web protocols (PubSubHubbub, Salmon, webfinger, etc.), most of which are (separately) available as a library in high-level, web-oriented programming languages and frameworks. In the case of the two main maintained implementations, Mastadon and GNU Social, what people do then is just build a webapp, with the OStatus bits pervasively intertwined with the webapp code whenever some feature is needed, not factored out into server that “speaks” OStatus and just federates with other servers, stores the data, etc., without being oriented to the webapp as a specific UI interface to it. In addition to making it harder to just run a single-user node, I doubt this helps performance.

          Unfortunately, all the components of these protocols are relatively complicated and implementations mainly exist in the webtech space, so it’s hard to actually build such a thing (not impossible, but if you wanted to write a headless C daemon to “speak OStatus”, it’s non-trivial). There was an attempt to build one in Node.js a few years ago, since at least all the libraries exist in JS, but it seems unmaintained. There’s also a recent attempt in Go, which so far is read-only.

          1. [Comment removed by author]

            1. 1

              It’s a small app in my primary stack. I’m quite familiar with it since putting together a porting plan (which required reading most of the source).

              Scaling a text chat service to <10k users is absolutely a solved problem.

              All of which is beside the point, which is that you could absolutely get this running fast but it would not be economical to do so.

            2. -1

              So a laptop would be able to handle it if it wasn’t a SPA? Doesn’t surprise me.

              1. 8

                Less to do with being a SPA (more-or-less orthogonal to server performance) and more to do with:

                A) Having a single, vertically scaled storage host separate to the code.

                B) Using a high-level interpreted language with developer-convenient semantics which are hard to optimize

                Every pageload request makes multiple blocking network calls - each waits for a process on another machine to get scheduled.

                This is wasteful given you could comfortably fit all the metadata into RAM (and the actual data too with swap, since the kernel would happily page out infrequently accessed toots and seamlessly bring them back when needed).

                Baking everything into a single process fell out of fashion in the 90s when it became apparent that it’s incompatible with horizontal scaling. In 2017, when you can buy terabytes of RAM by the hour, I suspect it’s mostly inertia keeping us doing it.

            3. 2

              Actually since the load varies you have less than 8ms. That’s pretty much impossible with Python or Ruby. Very easy with Go, Elixir or Node though.

            4. 8

              Consider using something other than rails so you don’t throw away 2 orders of magnitude from the first line of code

              Given this was initially a hobby project, ‘use something fun’ is an entirely appropriate choice.

              Currently, hosting costs $1296 euro / year (about 1400 USD).

              That’s not pocket change for a working developer, but it’s certainly hobby-affordable.

              That said, I absolutely wish it’d been written with operational load in mind, because I’d love to run my own domain of this but am uninterested in the substantial work involved in keeping a modern rails app running.

              1. 2

                FYI, your last sentence is phrased in an ambiguous way. I first understood it as a recommendation of rails (as in, their custom self-written code could only be worse), but then noticed the article’s Ruby on Rails tag which implies they are already using it. (I know next to nothing about ruby and its frameworks)

                1. 1

                  Yeah that was no good, edited it to be more clear.

              2. 5

                I hate to sound so harsh, but… I feel like the author saved themselves about one hour of reading time (to read about the well-documented scaling pain points of a Twitter-like system) in exchange for weeks of discovering them first-hand.

                It’s very cool that they are learning, and have a drive to share what they learn. But it feels like this has as much externally useful information as the monthly “I just found out that Unicode exists” post.

                1. 3

                  Maybe the author didn’t plan on getting this much traffic and works on it in his spare time.

                2. 3

                  Given the proportion of servers devoted to sidekick processes, how well does this network scale? If all of those 43000 users started their own instance, how many sidekick processes would be required to federate with all of them?

                  1. 1

                    Hard to be sure without testing, but I’d expect federation to scale pretty linear to number of users rather than number of domains.

                    1. 1

                      Oh, I would expect the opposite. 1000 users on one machine, I can poll that with a single connection. To poll for updates for one user on each of a 1000 machines requires many more connections.

                      1. 1

                        If I read correctly, each foreign feed you want to import requires a separate HTTP request, which implies that scaling is a question of how many “follow” relationships the graph has. I’d expect “everyone run your own” to have a pretty sparsely connected graph.

                  2. 1

                    The Mastodon logo is awesome :)

                    I remember when I scaled my first social network. Went from a couple of thousand of users to 2 million in a couple of months. Crazy times.

                    getstream.io now powers the feeds for over 70 million end users. bit busy now, but eventually would be fun to write a post about how we’ve scaled it.

                    If you like Mastodon, you’ll also enjoy pump.io (similar idea)