23 ms·
Case Study: Npm uses Rust for its CPU-bound bottlenecks [pdf]
- the_duke 8y agoA better title would be the subtitle of the article: "The npm Registry uses Rust for its CPU-bound bottlenecks". Note that only one service (authentication) was rewritten from node to Rust.
- steveklabnik 8y agoThat’s what I titled it when I submitted it after we first published this. There’s also a second service we know about in Rust, and that’s the one that renders package README pages.
- aboutruby 8y agoOr title could use "npm, Inc" as it's referring to the organization
- StreamBright 8y agoNo surprise here, good language design pays off for real world applications especially at scale like the NPM infra.
- hartator 8y agoDidn’t knew NPM had a speed issue.
- javagram 8y agoTitle could be improved, as I was wondering if the command line tool npm had itself been rewritten. It’s actually one of npm’s web services that was rewritten. FTA: “Java was excluded from consideration because of the requirement of deploying the JVM and associated libraries along with any program to their production servers. This was an amount of operational complexity and resource overhead that was as undesirable as the unsafety of C or C++.” I find this comparison a bit odd. Even if not using containers, the JVM isn’t hard to deploy as distro package managers include it. Unless a team is managing servers manually rather than an automated tool this doesn’t seem that complex. Am I missing something here?
- brazzledazzle 8y agoIf I have a choice between dealing with it and not I’ll choose not every time. It’s an annoying dependency that got even more annoying when Oracle decided to be a pain in the ass. Just because something is “easy” doesn’t mean it’s easier than the alternative.
- feikname 8y agoJVM tuning (especially the GC and memory allocation scaling) can be a huge PITA.
- simion314 8y agoBut having options is always good, isn't the same with compiled languages? you keep the defaults options but if you want extra performance you try different compiler flags or different compiler if the language has more then one.
- weberc2 8y agoHonestly I’d rather have good defaults than lots of options. If one tool meets requirements out of the box, then it’s preferable to a tool that requires a lot of tooling.
- simion314 8y agoBut if you do not have options then what is a "good default" , you have a default option if you have more then an option, so you prefer software with no options? Can you give examples of languages(compilers or VMs with bad defaults in your opinion?
- weberc2 8y agoYou can have options and have good default values for those options. Good default values are those that are reasonable for most people most of the time such that they don't need to be (or hire) domain experts to properly configure their tool. My opinion of a bad default would include a language toolchain which defaults to dynamic linking and requires one to opt into static linking (Java, Python, JS, etc, etc, etc). Worse than that is an anorexic toolchain that has no defaults whatsoever and requires you to pass every little detail directly to the compiler--bonus points if your language has a massive ecosystem of competing tools which are meant to manage these sorts of details for you but utterly and uniformly fail to do so (looking at you, C/C++).
- Tomte 8y agoEditorialized title. Don't do that.
- sctb 8y agoWe've updated the title from “Rust at NPM”. It's not so obvious how to extract a decent 80-character title from this one so we can cut the OP some slack.
- nothrabannosir 8y agoThis entire article is a pretty damning report on JavaScript in general, but this sentence takes the cake (emphasis mine): > The process of deploying the new Rust service was straight-forward, and soon they were able to forget about the Rust service because it caused so few operational issues. At npm, the usual experience of deploying a JavaScript service to production was that the service would need extensive monitoring for errors and excessive resource usage necessitating debugging and restarts. Is this satire?
- sheeshkebab 8y agoDeploying a service written in any language into production environment at scale of npmjs is far from straightforward. I think the satire here is that internet got so centralized lately that even a simple piece of code in JavaScript requires such a huge behemoth of an org running and maintaining all this monstrous infrastructure.
- curtis 8y agoYou've identified the problem, but I think you're wrong about the cause. It's not internet centralization that's the problem, it's the mundane fact that JavaScript does not have a large standard library. And JavaScript absolutely should have a large standard library, but it's not clear what organization would have the motivation to implement, support, and promote one. It's not impossible that a community-driven effort could accomplish the same thing, but nobody seems to be working on it.
- w0rd-driven 8y agoI think the biggest to a hurdle is the fact that there is no stdlib so nothing unused has to be shaken out. I think that’s a low barrier now though with more than adequate tooling. Another comment mentions a different stdlib for server vs browser but that’s also not a terribly hard problem. I think a good first pass would come from studying analytics from npm. What are the most used packages? The most stable? I know lodash makes a lot of sense but there’s also underscore. I think the biggest hurdles are really political over technology as everyone has been so entrenched now that a one-size-fits-all stdlib would be hard. Not impossible, just hard. I do wish someone were working on it and I hate to say it but Google probably has the most skin in the game with v8 and Chrome yet I don’t really trust them not to abandon it. So who else is there? It wouldn’t be a very ‘sexy project’ either but still seems worth it to at least try.
- adamnemecek 8y agoI’ve been playing around with rust since it came out but only recently did I decide to use it for a part of a project. It’s a very pleasant language. I didn’t fight the borrow checker much (maybe due to prior experience). The language is nuts. It’s true what they say cargo is even better than the language, it’s just so easy to add packages to your project or to split your project into packages. Cargo is an amazing investment as this will help people write non duplicated code. Like how many string implementations are there across c code bases. Each c project has so much code that’s the most boring, repetitive shit you can imagine. Cargo let’s you concentrate on writing your code without hassle. I have experience with a lot of package managers, gems, go, cocoapods, sbt, cabal, pip, spm, npm, you name it but cargo is on a different plane of existence. Cargo makes the whole internet your standard library. I also like cargo workspaces. Modern development needs a workflow where you pull in a dependency, and work on it in tandem with your code. Achieving a good workflow for this is surprisingly hard.
- lioeters 8y ago> Modern development needs a workflow where you pull in a dependency, and work on it in tandem with your code. Achieving a good workflow for this is surprisingly hard. Well put! I've struggled with this exact situation, and although I figured out a setup that works for me, it's still not ideal. In my experience, npm the package manager doesn't enable such workflows reliably (yet).
- adamnemecek 8y agoI agree. A lot of times I end up just pushing dependencies to github and pulling from github in the main codebase.
- c-smile 8y ago> write non duplicated code ... Like how many string implementations are there across c code bases. In one of projects I needed foo::string that can share data with foo::variant without copying the data each time. So foo::string was implemented as a COW string - smart pointer for foo::string_data. std::string simply does not work in such requirements. So I am not sure I understand how cargo will help in this case. Either Cargo source repository will contain implementations of any possible permutation of requirements of strings or people will just use standard std::string. The only feature that I need in C/C++ is unified ability to include libraries in code: #define PNG_APNG_REQUIRED #include source "libs/png/png-amalgamated.c" I am perfectly fine with downloading png.tar.gz manually and putting it in place where I need it. In any case decision to include library to a product requires quite a lot of reasonings and architectural investigations. For typical web front-end projects NPM or Cargo probably make sense. But for, say, NodeJs or Cargo itself they should not use any such automatic downloader.
- twiss 8y agoFor all this talk about performance, are there any benchmarks anywhere? Also, is there any blog post or anything by npm itself that this is sourced from?
- steveklabnik 8y agoIt was sourced by taking to npm directly; they signed off on the final text as well. They have spoken about this publicly before; it was in their newsletter when they first deployed it, and there’s been a couple of conference talks.
- detaro 8y agoat least a source from npm: 2017 talk by Ashley Williams, an engineer at npm, as they just started to use Rust: https://www.youtube.com/watch?v=GCsxYAxw3JQ https://www.youtube.com/watch?v=GCsxYAxw3JQ
- makkesk8 8y agoInterested to know why they didn't consider .net core.
- steveklabnik 8y agoThis stuff happened before, or at least around the time, that .NET Core was released. So it either didn’t exist or was an extremely new option, at least.
- makkesk8 8y agoAccording to the article they have been using rust in production for 1½ years, .net core 2 was released in 2017 so it definitely existed. If .net core was mature enough for their liking is however another matter.
- steveklabnik 8y ago.net core was released in August 2017. That’s basically one and a half years ago. Depending on how fuzzy the one and a half year time is, it may not have been released. Like it may not have literally been 18 months exactly. That’s all I’m saying.
- mlthoughts2018 8y ago> ““Java was excluded from consideration because of the requirement of deploying the JVM and associated libraries along with any program to their production servers. This was an amount of operational complexity and resource overhead that was as undesirable as the unsafety of C or C++.” To me this reads like someone has a chip on their shoulder to demand that Rust be viewed as generally superior instead of merely being another tool in the toolbox that has different trade-off properties. Referring to deploying the JVM as “operational complexity” or referring to C or C++ as “unsafe” both strike me as insecure, defensive attitudes. Rather, you pay a trade-off of deploying the JVM in order to gain access to language features, stability, maturity, greater coverage of third-party packages. When that trade-off is worth it for some reason, such as language standardization, you happen to already have many expert Java engineers on the team, or the library you need is not readily available in other languages, then you do it. But you would never start out in a vacuum where the mere fact of deploying the JVM is “operational complexity.” Complexity in comparison to what? It’s the same with C or C++. These languages support a type of low-level memory and data model that is permissive in ways that can lead to errors if not used properly. So you’ll ask: do I know how to properly use them for my particular use case? If not, then you might use a different language that is less permissive because you don’t need the permissiveness. But that is totally different fromthe language being “unsafe.” Safety is a property of a program, not a language. A language can offer different levels of tooling to control safety or conversely to let the programmer be free to make safety permissiveness trade-offs on their own, and each way of doing things will have use cases it’s good at or use cases it’s bad at. I do not know if Rust was a good choice or a bad choice for this targeted npm optimization. I assume the author knows the relevant trade-offs and why. Regardless though, these feel like non-sequitur, pejorative pot shots to characterize Java, C or C++ in some type generic bad light, as if those tools are a priori conceptually bad, which is a silly point of view.
- aaaaaaaaaaab 8y agoWell, this is a PR piece about Rust, hosted at rust-lang.org. What did you expect?
- mlthoughts2018 8y ago
- JamesClear99 8y agoIt's heartening to see the community being mentioned as a positive factor. > npm called out the Rust community as a positive factor in the decision-making process. Particular aspects they find valuable are the Rust community’s inclusivity, friendliness, and solid processes for making difficult technical decisions. These aspects made learning Rust and developing the Rust solution easier, and assured them that the language will continue to improve in a healthy, sustainable fashion.
- erichdongubler 8y agoPrevious submission here: https://news.ycombinator.com/item?id=19255639 https://news.ycombinator.com/item?id=19255639
- pushedx 8y agoWho wrote this? A whistleblower? One of the Rust "community" members who helped them out?
- steveklabnik 8y agoIt was authored by the Rust team in conjunction with npm, like all of our white papers. The process roughly goes: interview the user, write the paper, have them review it and fix anything they’re not happy with.
- faitswulff 8y agoI like how this whitepaper sidesteps the "but the rewrite is the real improvement!" by also rewriting the service in Node.js along with Go and Rust.
- steveklabnik 8y agoHey folks! This is part of our whitepaper series. This means that the audience is CTOs of larger organizations, and so the tone and content are geared for that, more than HN. Please keep that in mind!
- breatheoften 8y agoAre CTO's of largish organizations still not part of the hacker news audience ...? That seems a bit of a damning statement to be about the population of CTO's ...
- tejasmanohar 8y agoI'm sure some are on HN, but it's definitely not "the place" for them, and many have probably never heard of it
- shaklee3 8y agoI would be shocked if any CTOs of large organizations browse HN. Large orgs put people in those positions that are more about theory and future thinking over current knowledge.
- manigandham 8y agoIt's expected that high-level executives of large organizations deal with planning and strategy rather than low-level technical details. They're not following language features or implementations. However in that case, this whitepaper (and many others) are damning in how little they actually state and why so many technical decisions go wrong.
- phillipcarter 8y agoGood overall whitepaper and I like to see efforts like these. One are I felt was missing is some data here: "It keeps resource usage low without the possibility of compromising memory safety. " How did the resource usage compare with the Go and node rewrites? What metrics were used under which workload? Benchmarks are never perfect but I think a CTO-level person would like to see a table of results like that.
- BlackFly 8y ago> Java was excluded from consideration because of the requirement of deploying the JVM and associated libraries along with any program to their production servers. This was an amount of operational complexity and resource overhead that was as undesirable as the unsafety of C or C++. Just so everyone here is aware, this is by now an outdated complaint against Java. https://vertx.io/blog/eclipse-vert-x-goes-native/ https://vertx.io/blog/eclipse-vert-x-goes-native/ I'm choosing vertx as an example since it competes already with rust and c based applications over at https://www.techempower.com/benchmarks https://www.techempower.com/benchmarks but you ought to be able to compile general programs ahead of time.
- ricardobeat 8y agoAre there any companies using these native images in production?
- victor106 8y agoShared this in this same thread for another comment. The below videos show GraalVM based app loading up Spring framework, and flowable process engine and making a rest call to an external service all in 13 ms!!! Checkout https://youtu.be/9BQiDmvOnZw https://youtu.be/9BQiDmvOnZw https://youtu.be/yLvnkkRys2Y https://youtu.be/yLvnkkRys2Y
- pjmlp 8y agoTwitter uses GraalVM in production, you can find several talks from them. Beyond that, enterprises using PTC, Aicas, IBM, ExcelsiorJET JDKs have had the option to deploy AOT native code in production for the last 20 years or so.
- cle 8y agoThis is not at all outdated. GraalVM and SubstrateVM are still very new and only support a subset of JVM features. The Vert.x article itself mentions that, as well as this: https://github.com/oracle/graal/blob/master/substratevm/LIMITATIONS.md https://github.com/oracle/graal/blob/master/substratevm/LIMI...
- megous 8y agoThis is no study. It reads more like a conclusion to one.
- nikeee 8y agoAnyone knows if they considered .NET Core? It has dependency management, can be deployed as a self-contained binary and is memory safe. Seems to match the requirements for me.
- steveklabnik 8y agohttps://news.ycombinator.com/item?id=19295166 https://news.ycombinator.com/item?id=19295166
- colejohnson66 8y ago> This stuff happened before, or at least around the time, that .NET Core was released. So it either didn’t exist or was an extremely new option, at least.
- ilovecaching 8y agoI'd like to point out that even though it took them a week compared to an hour, a week is actually incredibly fast to learn Rust and build something useful with it. Learning C++ can take more than a month of training, and it's only because most people learn it over an entire semester at school that they learn it at all. This is also the time it takes to learn Rust, and presumably now that they've written one program, writing the next program will take them a fraction of a week. The amount of time it takes to learn something is often indicative of its power. Anyone who has learned a foreign language or a musical instrument knows that the time spent investing up front pays huge dividends down the road when you have the skills and tools to richly express yourself. The reason that Go takes two days to learn is because it artificially limits the amount of up front investment at the cost of limiting expressiveness over the lifetime of your use of the language.
- rujuladanh 8y agoLearning any of C, C++, Rust or other systems languages takes way, way more than a week or a month. For C, the simplest of the three, it is usually rated at 3 months. What happens is that if you are already proficient in one of them, one of the others takes way less time (specially in the case of C++, given it forces you to learn almost all paradigms). In addition, writing a small program does not mean you have learnt C, C++ or Rust.
- koyote 8y ago> I'd like to point out that even though it took them a week compared to an hour, a week is actually incredibly fast to learn Rust and build something useful with it. I would argue that something that takes even an experienced engineer a mere hour to write is very small and has little complexity (especially if unit tests are counted towards the hour it took them to re-write it). This means it's difficult to gauge how much Rust was 'learned' during that week.
- BooneJS 8y agoAs the yearly pace of processor improvements continues to dwindle, more and more problems will become CPU bound.
- z3t4 8y agoYou shouldn't be afraid to make independent micro services. Using a different language makes it more likely that it can be deleted, and more easily rewritten. If you are forced into a monolith usually means the architecture has a complexity problem.
- ramshanker 8y agoOK. Downloading Rust. :)
- truth_seeker 8y agoI have my doubts and confusion about this problem statement > Most of the operations npm performs are network-bound and JavaScript is able to underpin an implementation that meets the performance goals. However, looking at the authorization service that determines whether a user is allowed to, say, publish a particular package, they saw a CPUbound task that was projected to become a performance bottleneck. Oh, Really ??? So essentially Authorization service and I doubt the security algorithms computation are the main cause. What i dont understand here is why is it not possible to write lower level JS or asm code to craft a well optimized code which V8 can totally nail to minimum CPU instructions required?
- spricket 8y agoMy guess is that this uses public key cryptography. Generating a signature is rather expensive. We found this out the hard way a few years ago, when we tried to verify OAuth tokens using RSA rather than HMAC. The server was hammered at maybe 500 signatures a second, greatly slowing down token generation. I'm guessing they dropped to Rust so they could use native C libraries for signature generation.
- cryptica 8y agoThe idea that some programming languages can solve scalability issues is a myth. A language cannot solve scalability issues; all they can do is push the needle a tiny little bit further in terms of performance but this is completely meaningless. Scalability is an architectural concern which cannot be ignored by system developers. This is because scalability is not about speed or performance, it's all about figuring out which workloads can be split up and executed in parallel; in order to do this, you need to understand the real-world problem which the software is trying to solve; this is not something that you can delegate to a compiler. The best that a language can offer in terms of scalability is to make it easier to reason about parallel workloads and make the difference between serial and parallel workloads as explicit as possible. Whenever a language tries to hide the complexity of parallelization behind thread pools, they're not solving any real scalability issue; they're just delaying them some more.
- mavelikara 8y ago> The idea that some programming languages can solve scalability issues is a myth. True. > A language cannot solve scalability issues; all they can do is push the needle a tiny little bit further in terms of performance but this is completely meaningless. > Scalability is an architectural concern which cannot be ignored by system developers. A language can prevent or delay such architectural concerns from being addressed by not offering sufficient capabilities.
- imtringued 8y agoI don't understand the criticism of thread pools. Their only purpose is to avoid the expensive creation of threads. They don't do anything by themselves.
- spricket 8y agoWhile I'm a big fan of Rust, excluding Java because "JVM" is kinda laughable. It's not hard to run at all. You package everything into a jar then run a single command. As easy to get working as a JS backend. If their complaints are about GC tuning, is it not the same thing as tuning the GC in Js/Go? Java still had arguably the more mature GC of any language
- arhyth 8y agocan someone please give this outsider-noob an eli5 explanation why golang do not adopt a same policy/attitude/implementation towards package management?
- Corrado 8y agoGo is being developed by Google and as such is designed to meet their needs. Google's view of package management is to bring every package in-house and manage it themselves. So, if a Go program needs package "A" then Google will directly import that package into their workflow. This is actually one of the reasons that I don't think Go is a very good language for most people/organizations. It was conceived with a specific set of guidelines that Google needed; easy to learn, performant, etc. Go is also designed to be used by teams of thousands, so it's much easier to adopt misc packages into the fold and maintain them than it is to manage links to outside requirements.
- tekknik 8y agoThe statement about Go using global dependencies being the standard is just someone’s opinion on the Go team. I’ve written Go for a few years now and never once shared a dep across projects. Create a new folder, set your GOPATH (use direnv) and pull your deps. I very much doubt they’ll be more productive in rust vs Go had they actually given Go a chance.