
Falcon: A high-performance web server for Ruby, supporting HTTP/2 and HTTPS - ksec
https://github.com/socketry/falcon
======
decentrality
As the previous maintainer of Reel ( High-performance Web Server based on
Celluloid ) alongside the author of Falcon ( Samuel Williams ) I am proud to
see this release get some attention, and heartily congratulate the author on
work well done, both in the release itself, and in progress within the Ruby
language.

Samuel is one of Ruby's best. He wrote RubyDNS as well, which was one of the
best implementations of Celluloid, the asynchrony / concurrency / parallelism
/ distributed computing library written in Ruby, which has since come to EOL
or hit a ceiling as trends shifted.

I am happy to see Samuel ( ioquatix ) continue his momentum personally, and
contribute so much.

~~~
ksec
Yes, I don't know Samuel, but form his blog he has been using Ruby for 10+
years. And he is only been in a more active role in Ruby VM over the past few
years.

I think it was his Fibre[1] works that caught my attention. No idea why it
hasn't committed yet.

[1][https://bugs.ruby-lang.org/issues/14739](https://bugs.ruby-
lang.org/issues/14739)

Edit: Wow He is now a member of Ruby Core !!!

~~~
ioquatix
It will be soon.

~~~
ksec
Congrats for being on Ruby Core, we really need more people to push Ruby
forward. And thanks for the work on Fibre and Falcon, I hope I will have time
to test it out and see if it could fully replace Nginx + PUMA / Unicorn.

------
frankwiles
It’s a shame this has the same name as a high performance Python web framework
as well. [https://falconframework.org/](https://falconframework.org/)

~~~
xaduha
It's a shame neither of those Falcons made it here

[https://www.techempower.com/benchmarks/](https://www.techempower.com/benchmarks/)

~~~
DrJosiah
They list the Python Falcon variant in their filters, and it used to be up
there in previous editions.

------
netghost
There's some more interesting information on his blog around fibers, ruby, and
perf as well. Great to see more approaches being tried here.

[https://www.codeotaku.com/journal/2018-06/improving-ruby-
fib...](https://www.codeotaku.com/journal/2018-06/improving-ruby-fibers/index)

------
nathan_f77
This sounds great! Are there any things I need to watch out for before
switching from Puma to Falcon? And is it production-ready now, or does it
still need some time to mature and have feature parity with other web servers?

This is a great article about the different Ruby web servers (from 2015):
[https://www.speedshop.co/2015/07/29/scaling-ruby-apps-
to-100...](https://www.speedshop.co/2015/07/29/scaling-ruby-apps-
to-1000-rpm.html)

Would be great to have a comparison with Falcon. Also, speaking of
performance, I still need to set up jemalloc. Have heard lots of good things
about that.

~~~
ioquatix
I really think it depends on your use-case. The surface area of HTTP is huge.
I'd like to think it's production ready, but I'm only just beginning to dog-
food Falcon in production on my end.

Pragmatically speaking, it will be production ready when it reaches 1.0 -
until then, make sure you test it well and keep an eye on how it behaves. I've
literally run millions of requests against test servers, but... it's pretty
wild out there!

------
gigatexal
Kudos to this project for having a funding model. At 120USD / year / per
production instance many teams could convince management to pay it and help
fund the project but also have the maintainers as support staff if needed.

------
schappim
It is great to see people continually optimising Ruby and the experience of
working with Ruby.

------
Lio
I love stuff like this thanks. It's really interesting to see that Falcon is
based on the
[https://github.com/socketry/async](https://github.com/socketry/async)
library.

I've previously been looking at [https://github.com/ruby-
concurrency/concurrent-ruby](https://github.com/ruby-concurrency/concurrent-
ruby) based on its use in Rails and was wondering if there's a comparison of
the two approaches anywhere that would be newbie friendly?

I was also wondering will Falcon run on JRuby? (I see that nio4r does so
hopefully that also means that things like Async-Container will.)

~~~
dcchambers
Would also love to know if it will support JRuby.

~~~
ioquatix
I've been doing my best to try and support JRuby but in actual fact, JRuby
simply isn't that compatible with MRI where it matters. I hope we can fix this
but honestly I can only do so much. I tend to focus my efforts on MRI since
that's what I use day-to-day.

~~~
Lio
No worries Samuel, this is still really great work.

I'm guessing this is because process forking generally isn't supported on the
JVM, is that correct?

------
tibbon
I was just about a month ago trying to figure out if Rails and HTTP/2 could
work together; and it seems this is about the only answer out there currently
(or did I miss one?)

~~~
matt4077
Well, you missed the obvious one: Puma

Writeup: [http://eileencodes.com/posts/http2-early-
hints/](http://eileencodes.com/posts/http2-early-hints/) PR:
[https://github.com/puma/puma/pull/1403](https://github.com/puma/puma/pull/1403)

~~~
ioquatix
This is a long way from native bi-directional HTTP/2.

------
desireco42
First, thank you! It looks like really solid work.

This project must be fairly new as I was not able to find it mentioned and
compared with other ruby servers. Does anyone know some comparison running
puma vs falcon or passenger vs falcon?

~~~
ioquatix
There is a rake task in the source which performs benchmarks. Feel free to try
it out and propose more benchmarks.

------
jordanthoms
Wow, this looks great! We had problems with p99 response times on Puma, so
currently running nginx+unicorn.

~~~
ioquatix
I’m really interested in these use cases so let me know if I can help in any
way.

~~~
jordanthoms
Would be interesting to chat more about this - would like to learn more about
how the request queuing works (that was where we ran into problems with puma).
My email is in profile

~~~
ioquatix
I will email you, but I've also created a chat room specifically for
discussing falcon.

[https://gitter.im/socketry/falcon](https://gitter.im/socketry/falcon)

------
Red_Robot
Every language should have a framework named Falcon/Phalcon.

------
sudhirj
ioquatix, just I'm clear, if this is an evented server it will use just one
core? Or does it create one process per core? If not do you recommend we use
[https://github.com/stripe/einhorn](https://github.com/stripe/einhorn) to
split the work across N falcon processes (one for each core)?

And do you have advice / recommendations on database pool sizes when using
Rails? I assume that each process will have access to as many connections as
specified in the DB_POOL config? Does falcon need any pre/post fork re-
creation of all connections?

~~~
sudhirj
Someone more knowledgeable about Rails can pitch in, but I believe in the
absence of any connection management code, Rails will check out one connection
per request the first time it is used? And checkin after the request
terminates? If that is the case, wouldn't the number of simultaneous requests
effectively be capped at the database pool size for DB heavy applications?

~~~
ioquatix
I don't know that but it would make sense.

------
sp0ck
There is more than 9000 bird species and yet we have two web frameworks with
the same name. Naming projects proves the-letter-agencies theory that people
passwords are chose from very limited word space :)
([https://falconframework.org](https://falconframework.org)) was there
already.

~~~
ioquatix
This is unfortunate, but at the time I only checked RubyGems.org and didn't
think to check another language or package repository. So, I apologies, but
there was no bad intentions, perhaps just a little bit of bad luck and
ignorance.

That being said, it's actually named after the Peregrine Falcon, which is the
fastest bird in the animal kingdom, and it was a friendly poke at Puma :)

------
emmanueloga_
WEBrick was ruby’s standard library httpd back in the day... I remember it
being mostly unusable in production for different reasons. But every now and
then a new httpd would appear: mongrel, unicorn, passenger, puma, etc…

Sometimes the new implementation was not only “faster” under certain
benchmarks, but deemed superior for “philosophical” reasons… I think it was
the case for unicorn that load balanced over a pool of unix processes.

Eventually I left the ruby/rails world behind. Not the main reason, but I
remember performance problems being very frustrating.

To quote [an old, 2011 blog post from] antirez: “it is not ok that by default
[ruby] is so damn slow”. [1]

I was expecting to find ruby state of affairs to be the same these days, but
looking at TechEmpower’s recent benchmarks [2] (benchmark reading caveats
apply), seems like ruby implementations are reasonably speedy nowadays:
benchmarks reflect results within the same order of magnitude to the fastest
ones, except for the plaintext benchamark. I extracted some interesting
metrics below.

Still, Ruby consistently comes after the 100th entry for all benchmarks.

A lot of people will say that the reasons to use ruby are the gains in
productivity and the expresibility, DSL capabilities, etc. If that’s the
evaluation metric, maybe Clojure could be a good alternative. Also, it
performs very well! (thanks to the JVM, no doutbts). I believe immutable by
default is a better way to build apps, and in Clojure, the whole language is
built around this concept. Ruby is the other way around: even parts of the
language that shouldn't are open for modification!

I wonder if jRuby would be a good contender for performance.... but...

* I’m not sure why there are no jRuby implementations on the techempower benchmarks.. evidently, not a very popular technology?

* I’m guessing that startup time for tools like IRB must the one of the turnoffs for ruby people.

1: [http://oldblog.antirez.com/post/scalability-and-speed-of-
web...](http://oldblog.antirez.com/post/scalability-and-speed-of-web-
apps.html)

2:
[https://www.techempower.com/benchmarks/](https://www.techempower.com/benchmarks/)

\--

Numbers: max requests per second for an specific implementation in
TechEmpower's benchmarks

JSON serialization.

1st Java: 1,197,864 20th Rust: 1,135,647 (1.05X slower) 21st Clojure,
1,126,256 (1.06X slower) 141st Ruby 173,905 (6.9X slower)

Single query:

1st Java: 656,262 20th Go: 309,728 (2.12X slower) 54th Clojure: 209,466 (3.13X
slower) 120th Ruby: 96,174 (6.82X slower)

Multiple Queries

1st Java: 43,245 20th Kotlin: 22,643 (1.91X slower) 21st Clojure: 22,536
(1.92X slower) 100th: Ruby: 11,216 (3.86X slower)

Fortunes

1st C: 424,712 20th Go: 193,079 (2.2X slower) 78th Clojure: 98,056 (4.33X
slower) 131st Ruby: 51,043 (8.32X slower)

Data Updates

1st Java: 18,152 20th Dart: 6,785 (2.68X slower) 65th Clojure: 3,707 (4.9X
slower) 95th Ruby: 2,839 (6.39X slower)

Plaintext

1st: Rust: 7,040,642 18th Clojure: 4,178,241(1.69X slower) 20th Java:
3,858,510 (1.82X slower) 134th Ruby: 239,652 (29.38X slower)

~~~
ioquatix
The tech empower benchmarks for Ruby are a bit foobar, I tried to fix it but
ran out of time. I wouldn't trust it completely. I'm not saying it's wrong, I
just don't think it's the complete picture.

