Live data from Hacker News

12 requests per second: A realistic look at Python web frameworks

suade.org

41–50 of 239 posts

Re: 12 requests per second: A realistic look at Python web frameworks

#41

I think it’s been bog standard practice to run flask via uwsgi or gunicorn with async workers and use multiple process based workers per deployed server unit (eg per pod in Kubernetes). What matters is that the cumulative latency & throughput solve your problem, not how fast you can make one singular async worker thread. I figure most people running complex web services in production would just do an eye roll at this…

Could you share your company’s website?

Re: 12 requests per second: A realistic look at Python web frameworks

#42
post #7

Use of ORMs is often a performance choke point. Raw DB queries are often much, much faster. Almost always, the more you abstract, the worse you perform. It's great as a developer but not so great as a user.

I haven't touched an ORM in over 6 years, but unless they've improved since then, I honestly can't think of a single reason why anyone would choose to use one. They're clunky monstrosities that act only as guard-rails for inexperienced developers. Far better to invest a few days (which is realistically all you need) to improve their SQL skills and/or code-review practices.

I am by no means an experienced developer--but the issue I always seem to have without using an ORM is that there are string literals containing different bits of SQL scattered all throughout my code. In addition to being hard to refactor when the database model changes, I think there is a fairly high performance cost to doing so many string concatenations every time the code runs. Is there a better way to manage the SQL command strings when you are sending the queries by hand?

Re: 12 requests per second: A realistic look at Python web frameworks

#43
post #25

Earlier quoted context omitted.

I increasingly lean towards plain SQL over ORMs. It requires greater familiarity with SQL but I prefer that over greater familiarity with ORM-specific syntax that doesn’t translate across frameworks or languages. In addition, you can prototype new queries and profile existing queries in the database and copy-paste directly into your code.

for me the value of an ORM is not so much query synthesis as serialisation of object fields to db columns and vice versa

Same here.

I'd love to have a tool that just generates an object type for a given SQL query's result rows, and a function signature for its query parameters.

Re: 12 requests per second: A realistic look at Python web frameworks

#44

Earlier quoted context omitted.

If you're not paying attention it would look that way, yes. If you pay attention you'll notice that just.js is using postgres as their DB, while all of the node benchmarks are handicapped by either using mongoose/mongodb or MySQL. There is no node benchmark with postgres, but all of the fastest benchmarks used it. "lithium" is a good example to show how much of an impact switching to postgres has. All of the 4 lithiu…

What makes postgres special in these cases?

I would like to know as well. All I know is that for this specific workload there appears to be a strong correlation between the chosen DB and performance. Depending on the benchmark you're looking at on that site, the top 30-60 results are exclusively postgres.

Further, for every framework/language that was tested with both MySQL and postgres (there's quite a few of them), the postgres one always ranks higher.

Re: 12 requests per second: A realistic look at Python web frameworks

#45

Earlier quoted context omitted.

If you're not paying attention it would look that way, yes. If you pay attention you'll notice that just.js is using postgres as their DB, while all of the node benchmarks are handicapped by either using mongoose/mongodb or MySQL. There is no node benchmark with postgres, but all of the fastest benchmarks used it. "lithium" is a good example to show how much of an impact switching to postgres has. All of the 4 lithiu…

What makes postgres special in these cases?

Likely it's the better/faster support for multi-step transactions. (That's a big point for PG, since at least 2004)

Re: 12 requests per second: A realistic look at Python web frameworks

#46
post #8
post #4

In my benchmark testing, SSL appears to be the bottleneck; e.g., Apache vs. Nginx does not really matter. I assume the benchmarks above 10,000 RPS are not using SSL and regular HTTP? How are people doing benchmarks at 10k-100k RPS?

Where is SSL the bottleneck? Wondering if terminating earlier and just relying on HTTP after would help.

Signing, verification, and key exchange are quite expensive. ECC doesn't help server-side; it mostly reduces client-side verification costs. Session caching can be an important optimization that can significantly reduce those costs, but scaling session caching has its own problems.

But IME real-world bottlenecks have more to do with overall architecture. People tend to heavily focus on technical details, such as concurrency architecture--the how. But the biggest opportunities for improved performance usually involve functional aspects of an architecture--the what. (Note that these aren't fixed categories; they're relative positions. A technical detail often becomes a functional model as development progresses.)

12 RPS is a long way from implicating SSL. If you get to the point where SSL is an identifiable bottleneck, you've either made a series of tremendously good decisions or exceptionally poor decisions.

Re: 12 requests per second: A realistic look at Python web frameworks

#47
post #43
post #25

Earlier quoted context omitted.

for me the value of an ORM is not so much query synthesis as serialisation of object fields to db columns and vice versa

Same here. I'd love to have a tool that just generates an object type for a given SQL query's result rows, and a function signature for its query parameters.

This!

We don't need ORM, we need OQM (object-query mapping)!

Re: 12 requests per second: A realistic look at Python web frameworks

#48
post #43
post #25

Earlier quoted context omitted.

for me the value of an ORM is not so much query synthesis as serialisation of object fields to db columns and vice versa

Same here. I'd love to have a tool that just generates an object type for a given SQL query's result rows, and a function signature for its query parameters.

F# has this + static SQL query string checking at compile time using type providers

Re: 12 requests per second: A realistic look at Python web frameworks

#49

My experience doing perf optimizations in real world systems with many many people writing code to the same app is a lot of inefficiencies happen due to over fetching data, inefficiencies caused by naively using the ORM without understanding the underlying cost of the query, and lack of actual profiling to find where the actual bottlenecks are (usually people writing dumb code without realizing it's expensive). Sure,…

I increasingly lean towards plain SQL over ORMs. It requires greater familiarity with SQL but I prefer that over greater familiarity with ORM-specific syntax that doesn’t translate across frameworks or languages. In addition, you can prototype new queries and profile existing queries in the database and copy-paste directly into your code.

In the java-world there are libraries like JDBI, which makes it possible to write interfaces with SQL-annotations and have serialization, connection setup etc. done for you:

    public interface UserDao {
        @SqlUpdate("CREATE TABLE user (id INTEGER PRIMARY KEY, name VARCHAR)")
        void createTable();

        @SqlUpdate("INSERT INTO user(id, name) VALUES (?, ?)")
        void insertPositional(int id, String name);

        @SqlQuery("SELECT * FROM user ORDER BY name")
        @RegisterBeanMapper(User.class)
        List listUsers();
    }
This is great because it's explicit. No hidden queries.
Post reply on HN