In either case, I hope they announce a correction and move on to more important matters. If youre trying to shave another tiny bit of rps out of your boxes then thats an incredible success problem; not the kind 99.999 of companies will need.
In either case, I hope they announce a correction and move on to more important matters. If youre trying to shave another tiny bit of rps out of your boxes then thats an incredible success problem; not the kind 99.999 of companies will need.
Dino makers are well aware of this. An otherwise great Python framework (based on Starlette) is even named "FastAPI" in an attempt to use this to their advantage (it is great for other reasons, not because of its speed).
Unfortunately lots of devs are looking for silver bullets when it comes to speed, instead of detecting, determining, investigating and removing the bottlenecks.
/S
Take this example from their docs:
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
You are declaring the types of the parameters, and FastAPI parses and enforces them for you. This saves quite a bit of code, and lets you focus on your business logic. Writing the code this way also allows FastAPI to generate a meaningful description of your API, which can be schema (such as Swagger) that tools can use to generate clients, or it can be documentation pages for humans to read. Any good documentation will still require you to write things, but this gets you further, faster than using something like Flask.This example[0] takes these concepts even further.
Or just glance at the summary and see that it has nothing to do with @app.post.[1]
FastAPI has also properly supported async routes for longer than Flask, from what I understand.
(I've never personally used FastAPI for anything serious, since I have rarely used Python for anything other than machine learning for the past 5+ years, preferring to use Go, Rust, or TypeScript for most things, but I am aware of it, and seeing its claims misrepresented like that is mildly annoying. FastAPI is far more appealing to me than any other Python web framework I've ever seen, and I've only heard good things about it. Based on my experiences in other languages, their approach to writing APIs is absolutely a good one.)
Proper async support is decently important to me in any language or framework, but in the real world, I haven't often run into other developers who care much about that.
Typing is the base for many reasons I love FastAPI, so yes it is useful. And I speak as someone who has used it in production on multiple projects, and even converted some from Flask (but not because of speed).
Far from "fast to get going", starting with FastAPI is slower actually, but it takes you further (as you pointed out). The train of thought that "typing" leads to "fast to get going" which leads to "fast" in the name... Let's say I don't buy it.
The link to "performance" is difficult to miss, I don't think that is a coincidence. And it's OK. If this is what matters to devs that much, they would be stupid not to highlight it. I'm actually happy people are using it, even if for the "wrong" reasons.
- URL params, forms and query string parsing and validation
- (de)serialization format choice
- dependency injection for complex data retrieval (this one is very underrated and yet is amazing for identification, authentication, session and so on)
- output consistency guarantees
- API doc generation
Note that I don't hold this against them. They simply understand what makes the devs pick them and adjusted their market strategy accordingly. It would be nice if they didn't have to though.
And if your framework is faster, then of course you're going to mention it. Do you really think Flask or Django wouldn't point out that they were fast, if they were? I'm quite sure they would, since it's not shameful to educate the reader on what your framework offers compared to the competition, but they can't, because they're not.
Your link goes to the very bottom of that page, so is it really prominently featured compared to everything else they're trying to sell you on? It really doesn't seem like it. More convincing would be pointing to their list of "key features" at the top, which does mention performance first, but then quickly focuses back on "Fast to code" and "Fewer bugs".
I find the reason for using a tool often isn’t what they list first in their technical documentation.
I can understand why someone might think those really are the reasons to use that tool.
I agree that it’s harmful to distract from what actually matters: the core goal and competencies of the team.
But therefore we should hope devs look for silver bullets to address performance without having to be distracted by it. “It’s out of the box pretty good so I don’t have to think about caching or CDNs or load balancing until later” is deeply valuable.
I think that we as an industry don't have the best hindsight.
I'll use enterprise Java as an example of a few common situations:
- sometimes we go for Spring (or Spring Boot) as a framework, because that's what we know, but buy into a lot of complexity that actually slows us down
- other times we might look in the direction of something like Quarkus or Vert.X in the name of performance, but have to deal with a lack of maturity
- there's also something like Dropwizard which stitches together various idiomatic packages, yet doesn't have the popularity and tutorials we'd like
- people still end up being limited by ORMs, which can speed up development and make it convenient, but have hard to debug issues like over-eager fetching
- regardless of how fancy and "enterprise" your framework is, people still make data structure mistakes (e.g. iterating over a list instead of using a map)
- if you've written a singleton app (runs just on a single instance) that's monolithic, your background processes will still slow everything down
And then, people wonder why it's hard to change their enterprise codebase and wave around their hands helplessly when their app needs at least 2 GB of RAM to even run locally and answering some simple REST requests needs close to 20 seconds and the app does about 2000 database queries to return a relatively simple list with some data.When people should think about performance, they're instead busy "getting things done", when people should think about "getting things done" they're busy bikeshedding about which new framework would look best on their CV. And we even pick the wrong problems to solve, given that many (but not all) of the systems out there won't really have that stringent load requirements and just writing decent code should be our priority, regardless of the framework/technology/language.
I remember load testing a Ruby API that I wrote: on a small VPS (1 CPU core, 4 GB of RAM), it could consistently (over 30 minutes) serve around 200 requests/second with database interaction for each, which is probably enough for almost any smaller project out there. Doubling those resources by scaling horizontally almost doubled that number, with the database eventually being the limiting factor (which could have been scaled vertically as well). And that is even considering that Ruby is slow, when compared to other options. But even "slow" can be enough, when your code is decently written (and the scale at which you operate doesn't force your hand).
The idea was to see how performance intensive COVID contact tracking would be, if GPS positions were to be sent by all of the devices using an app, which would later allow generating heat maps from this data, instead of just contact tracing. Of course, I talked about the privacy implications of this as well (the repository was called "COVID 1984"), but it was a nice exercise to demonstrate horizontal scaling, the benefits of containerization and to compare the overhead of Docker Swarm with lightweight Kubernetes (K3s).
So yes, write heavy workloads are viable with Ruby on limited hardware, read heavy workloads can be even more easy (depending on who can access what data).
for projects of any significant size, that answer is a resounding "yes".
for anything that can plausibly grow in scope and team size (which, let's be honest here, is most complex projects), it almost never makes sense to go without an existing ecosystem. it becomes difficult to hire, difficult to train, difficult to pass off maintenance, slows down velocity of shipping, makes your team gradually re-invent a worse version of the framework/tooling you initially tried to avoid, etc.
i've been on both kinds of projects. when i build something solo it's a work of art in code size, API consistency, and performance...and that feels truly amazing. but unfortunately it's not something that is feasible with bigger and more diverse-skillset teams. ever-growing scope and shipping features quickly usually means giving up performance and well thought out design.
But if it's that JS execution is outright faster, it's a big deal.
People here handwave "oh, your business doesn't require more than 10rps". Sure. But rps is just half the story, latency is the other. I'll give you two examples
1) SSR with something like Material UI is slow, especially because of the CSS-in-JS. The server rendering the page can easily take 200ms or more.
2) Modern backend stacks. On an API I have I use Prisma + Apollo GraphQL. Some queries take 500ms. These same queries but using REST and knex are <10ms. There is no slow SQL queries here or N+1 issues, it's just prisma and graphql executing a lot of JS.
In either case, the user experience is impacted because the website becomes slower. And a faster runtime would make these JS run faster, thus the web/api load faster.
There is also overhead in passing structures and other communication required so that layer can change the number as well.
If you're relying on innovation to make your existing tech stack not behave like dogshit when proven and trivial solutions exist, you're valuing the wrong things when choosing your stack.
If you're an auto manufacturer and you discover something like fuel injection that will dramatically improve efficiency for your customers (the people paying that bill), not doing so makes you a terrible engineer. The 'developer velocity' argument is pure BS... there's absolutely no direct (or even really indirect) correlation there. If the ones you have need someone else to write 9 libraries so that they can build a REST API, you need better engineers.
For work of speculative value (most startups...), optimising for dev efficiency is IMHO the right thing to do.
StackOverflow peaks at about 6000 reqs/s and it's an extremely popular website.
also wondering what peak RPS is for HN. i feel like most (non consumer) startups would be like "ok if its good enough for HN its good enough for me"
It is [1] ( and should be ) pretty well known. 1.3 BILLION page view per month, 6K RPS with 9 ( Fairly Weak ) Servers, Sub 20ms response time with zero caching.
>also wondering what peak RPS is for HN.
Less than 100 RPS for logged in users. The number were pre 2020 but I doubt the current number is significantly higher.
I mean... to be clear, they do tons of caching[0], which is certainly critical for their ability to have a non-cached response time of 20ms. Most of their responses should be coming from a cache, given the type of site they run, otherwise they would need a lot more servers.
[0]: https://nickcraver.com/blog/2019/08/06/stack-overflow-how-we...
https://hanselminutes.com/847/engineering-stack-overflow-wit...
As for the error, I suspect it was an innocent mistake. I see no reason Deno would choose to mislead, when they’ve generally very publicly responded to performance deficits by acknowledging them and then actually improving real performance.
Performance is a very important thing in js world for a peace of mind of devs.
And I'm not even sure if the above is 100% accurate.
I benchmarked a hello world in .net and node/express, and the .net version was multiple orders of magnitude faster than the node/express version. That's a starting point, and as you add more logic, that gap only grows in my experience. Javascript may be fast _enough_ for many cases, and in a tight JIT loop it may be faster again, but by any measure, js is not quick.
One example is the techempower benchmarks Fortune section[0]. It's a fairly basic app, but it tests a full stack web app in multiple languages, and it's pretty clear that js is fimrly in the middle of the pack, far behind the compiled options. If you have any sources to the contrary, I'd love to see them.
[0] https://www.techempower.com/benchmarks/#section=data-r21&tes...
But a decent js implemention of 3D graphics-something would use one of the available tools for such applications. Making the difference considerably smaller.
Or is you experience different?
The three major blockers I remember were:
1. Render contexts are created on the main thread and the user of the library gets no control over this. This means all driver overhead and library function calls block the main thread, which matters a lot when trying to hit 8ms/frame.
2. Loading textures asynchronously (in another thread, not Javascript async/await) was straight up impossible due to poor architecture. This means app startup was 500ms instead of 5ms. Maybe not a big deal to you, but our use case necessitated quick (a few frames at worst) startup.
3. The renderer used a scene graph, which was hilariously slow to traverse for large numbers of objects. Impossible to optimize by anyone as far as I can tell. Scene graphs just don't work well in JS.
[0] https://www.techempower.com/benchmarks/#section=data-r21
4 ranks before .Net.
[0] https://github.com/TechEmpower/FrameworkBenchmarks/issues/72...
https://www.techempower.com/benchmarks/#section=test&runid=e...
the postgres driver was rewritten in JS because i spent so long benchmarking using the pg C driver and couldn't get the performance i needed from it. if you actually read the github thread you can see i even did a lot of work to verify the various frameworks were compliant with the requirements.
in round 21, postgres pipelining was disallowed for all frameworks and just-js/JavaScript is in first place. \o/
https://www.techempower.com/benchmarks/#section=data-r21&hw=...
https://github.com/TechEmpower/FrameworkBenchmarks/tree/mast...
More details in this thread: https://github.com/just-js/just/issues/5
Not that it is representative of actual use cases. Can't use just-js in production as it's hyper optimized for this benchmark rather than a work horse. But it does provide a better view of what is possible if the work is put in.
Just-js had spent a lot of resources optimizing the input and output gateways to the V8 engine and it obviously pays off nicely. It does serve requests with the JS.
Is the boundary in the same place? Not familiar enough with the others to say exactly. But does it really matter?
in techempower, the vast vast majority of code running in the just-js entry is JavaScript. all the core libraries for networking and interacting with the OS are js wrappers around C++/v8. the http server, though incomplete and not production rady, is written in javascript, with http parsing handed off to picohttpparser. the postgres wire protocol is completely written in javascript. in fact, one of the advantages JS and other JIT languages have is you can optimize away a lot of unnecessary logic at run time when you need to. e.g. https://github.com/just-js/libs/blob/main/pg/pg.js#L241
the whole point of doing this was to prove that JS can be as fast as any other language for most real world web serving scenarios.
if i had more time to work on it, i am sure i could improve the fortunes score where it would be at or very close to the top of that ranking too.
Where I think there’s more of a problem is cultural: similarly to Java, there’s a subset of programmers seemingly dedicated to layering abstractions faster than the JIT developers can optimize them.
Unfortunately, I don't have readily available data to back up my claim neither.
Again, not saying it never happens but I’ve rarely seen the kind of microbenchmark this story is about end up correlating with real application performance. I have seen developers get all fired up in some religious war and endanger their entire project trying to see benefits which never materialized, though, a common feature there was this focus on toy benchmarks rather than measuring the whole system or what they could do at the app level if they weren’t supporting some niche framework.
This sounds extremely accurate to me
For example, go can handle about the same amounts (be advised that this tests are for 4 cores, so results have to be divided): https://github.com/smallnest/go-web-framework-benchmark
The challenge I have with these positions is that unless you have very specific latency requirements, most of the time youre better off focusing on solving a business problem and then measuring what is slow. Starting off with “well it has to be fast so lets use this brand new thing” is the swan song of the eventually remorseful.
This is the point GP is making - they (the "junior-wannabe-senior") aren't even thinking of all else, and by focussing purely on the speed of operations are probably using the lesser optimal solution. Facetious example: A is faster than B, shaving a few cycles here and there. But nobody knows how to use A, it's support is lacklustre, and there are many known vulnerabilities that haven't been fixed. B is the most widely used in the industry, support and security is good. Junior-wannabe-senior is picking A because it's faster.
All else is never equal. The level of adoption and support is what drives decisions in the end. That's why everyone still uses Node when Bun is probably better in every way.
>segfault at runtime
Bun is far from better in every way
I think the benefit of deno or bun aren't as obvious when compared in the context of node on DX matter too.
Most of the tooling and standard library can be used without using the cli and switching runtime.
Tools like tsx simplifies running typescript code directly. It does pretty much what deno does internally using esbuild.
The modularity of runtime doesn't matter to consumers even if it's pretty cool.
FFI and security features are nice but I think the future is running sensitive code as a wasm module directly in separate isolated context.
The browser compatibility is an awesome boost but most bundler will polyfill that for you out of the box and you will use a bundler with either deno or node most of the time. I know polyfilling is not perfect but it's good enough for most.
I want to hear what strong reason people have for choosing to use either bun or deno in production.
I use deno for writing scripts because it's so easy to run them especially if they have any dependencies but outside of that, I haven't reached out for it.
https://dev.to/builderio/a-first-look-at-bun-is-it-really-3x...
Developers should focus more about time spent getting an application up and running (and to market) rather than how much time is spent serving an http request.