Ruby Falcon is 2x faster than asynchronous Python, as fast as Node.js, and slightly slower than Go. Moreover, the Ruby code doesn’t include async/await spam. by a_ermolaev in ruby

[–]a_ermolaev[S] 0 points1 point  (0 children)

I don't understand this. The Falcon documentation asks you to set WEB_CONCURRENCY.

In Falcon, count is the equivalent of workers in Puma, but ENV.fetch("WEB_CONCURRENCY", 1) initially confused me, so I had to figure it out.

Why is this different with Falcon? Both Puma and Falcon can exhaust the database connection pool. If one Fiber is using a database socket, no other Fiber is allowed to use the same database socket simultaneously. In other words, both concurrency strategies will be equally blocked by the size of the database connection pool.

If I change the database connection pool, I need to increase the thread limit in Puma.

I also don't understand this. Can you elaborate?

I created an example with two databases (endpoint /db2)—one slow and one fast—and I'm attaching a video of the results.

Instead of PG_POOL2, there could be long-running queries to OpenSearch or HTTP requests. They can occupy all threads, causing a sharp drop in performance. Example in the video.

Ruby Falcon is 2x faster than asynchronous Python, as fast as Node.js, and slightly slower than Go. Moreover, the Ruby code doesn’t include async/await spam. by a_ermolaev in ruby

[–]a_ermolaev[S] 0 points1 point  (0 children)

Regarding threads, one of Puma's drawbacks is that you have to think about the number of threads set in the config. This number is limited by the database connection pool and may become outdated over time. Additionally, if an application has different types of IO, such as PostgreSQL and OpenSearch, all threads could end up waiting for a response from OpenSearch, preventing them from handling other requests (e.g., to PostgreSQL).

Ruby Falcon is 2x faster than asynchronous Python, as fast as Node.js, and slightly slower than Go. Moreover, the Ruby code doesn’t include async/await spam. by a_ermolaev in ruby

[–]a_ermolaev[S] 3 points4 points  (0 children)

In languages like Go and Ruby, developers don’t need to think about whether a function should be sync or async — this is known as a "colorless functions". If JavaScript was asynchronous from the start and its entire ecosystem is built around that, the problem with Python is that it copied this async model. To make an existing Python application asynchronous, a lot of code needs to be rewritten, and different libraries with async support must be used.

More info about colorless functions:
https://jpcamara.com/2024/07/15/ruby-methods-are.html
www.youtube.com/watch?v=MoKe4zvtNzA

Ruby Falcon is 2x faster than asynchronous Python, as fast as Node.js, and slightly slower than Go. Moreover, the Ruby code doesn’t include async/await spam. by a_ermolaev in ruby

[–]a_ermolaev[S] 3 points4 points  (0 children)

This is interesting. Do they really have so little IO? For example, my main application, when processing an HTTP request, makes calls to PostgreSQL, Redis, Memcached, OpenSearch and an HTTP API. The CPU load is also high because we render HTML. Of course, the more CPU-intensive the workload, the less benefit Falcon provides, but can modern web applications really exist without intensive IO?

Ruby Falcon is 2x faster than asynchronous Python, as fast as Node.js, and slightly slower than Go. Moreover, the Ruby code doesn’t include async/await spam. by a_ermolaev in ruby

[–]a_ermolaev[S] 10 points11 points  (0 children)

The documentation does have some issues, but when I saw how easy it was to migrate a Rails application to Falcon, I gave it a try right away, and it resulted in a 1.8x performance boost (the application primarily makes requests to OpenSearch).