Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the default Puma configuration #50669

Merged
merged 1 commit into from
Jan 10, 2024
Merged

Conversation

byroot
Copy link
Member

@byroot byroot commented Jan 9, 2024

Fix: #50450

The main change is the default number of threads
is reduced from 5 to 3 as discussed in #50450

Pending a potential future "Rails tuning" guide, I tried to include in comments the gist of the tradeoffs involved.

I also removed the pidfile except for development. It's useful to prevent booting the server twice there but I don't think it makes much sense in production, especially since Puma no longer supports daemonization and instead recommend using a process
monitor
. And it makes even less sense in a PaaS or containerized world.

Copy link
Contributor

@fractaledmind fractaledmind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small text tweaks for improved readability

@byroot
Copy link
Member Author

byroot commented Jan 9, 2024

@fractaledmind thanks.

# Global VM Lock (GVL) it has diminishing returns, and will degrade the
# response time (latency) of the application.
#
# The ideal number of threads per worker depends both on how much time the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd just lay out the tradeoff:

"Increasing threads per worker increases throughput for applications which spend significant time waiting on I/O, but can also increase latency. Decreasing threads per worker keeps latency consistent and low for all applications, at the cost of maximum throughput."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like it's very similar to the "rule of thumb" I describe above.

The main change is the default number of threads
is reduced from 5 to 3 as discussed in rails#50450

Pending a potential future "Rails tuning" guide, I tried
to include in comments the gist of the tradeoffs involved.

I also removed the pidfile except for development.
It's useful to prevent booting the server twice there
but I don't think it makes much sense in production,
especially [since Puma no longer supports daemonization
and instead recommend using a process
monitor](https://github.com/puma/puma/blob/99f83c50fbb712b0987667f3533cce4ea925b2da/docs/deployment.md#should-i-daemonize).
And it makes even less sense in a PaaS or containerized
world.
@byroot
Copy link
Member Author

byroot commented Jan 10, 2024

Ok, thanks everyone for the comments and suggestions, I think it's in a good enough state now, we can always do touch up later if there are things people feel strongly about.

@byroot byroot closed this Jan 10, 2024
@byroot byroot reopened this Jan 10, 2024
@byroot byroot merged commit eac48e9 into rails:main Jan 10, 2024
4 checks passed
@byroot byroot deleted the update-puma-defaults branch January 10, 2024 10:16
rossta added a commit to joyofrails/joyofrails.com that referenced this pull request Jan 11, 2024
Lengthy discussion on default thread count, web concurrency, and pid
files in

Set new default for the Puma thread count
rails/rails#50450

Update the default Puma configuration
rails/rails#50669
@schneems
Copy link
Member

Thanks for fixing the process detection 06d614a.

Which I found out about https://justin.searls.co/posts/brand-new-rails-7-apps-exceed-heroku-s-memory-quotas/.

if processors_count > 1
workers worker_count
else
preload_app!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why preloading the app if processors count is not > 1?

The previous given instructions were

# Use the preload_app! method when specifying a workers number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preload_app! is always preferable. The I don't set it when processor_count > 1 is because it's the default there: https://www.rubydoc.info/gems/puma/Puma%2FDSL:preload_app!

Preload the application before starting the workers; this conflicts with phased restart feature. On by default if your app uses more than 1 worker.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That won't be fully true until Puma v7 puma/puma#3044

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, so with the current config preload_app! is needed regardless of the number of workers?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/puma/puma/blob/master/5.0-Upgrade.md#upgrade
(without looking at the code) I think its only if WEB_CONCURRENCY is used

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@santib santib Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was checking the history a bit to understand how this file evolved in the last time and I found the following:

  1. 471ab23 - Remove workers and preload_app!. Let Puma take care of the defaults
  2. 839ac1e - Try to use all CPU cores by default (when WEB_CONCURRENCY not set)
  3. 06d614a - Go back to a default of 1 for WEB_CONCURRENCY

So maybe all of this is unnecessary and we should go back to 1. ? (at least for the workers part)

noahgibbs added a commit to noahgibbs/rails that referenced this pull request Feb 2, 2024
This guide explains major concurrency and performance principles
for Puma and CRuby, when to possibly not use Puma, and how to
do basic load testing for tuning production performance settings.
Incorporates comments from Rails issue rails#50450, PR rails#50669 and
feedback from Jean Boussier.

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
noahgibbs added a commit to noahgibbs/rails that referenced this pull request Feb 2, 2024
This guide explains major concurrency and performance principles
for Puma and CRuby, when to possibly not use Puma, and how to
do basic load testing for tuning production performance settings.
Incorporates comments from Rails issue rails#50450, PR rails#50669 and
feedback from Jean Boussier.

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
noahgibbs added a commit to noahgibbs/rails that referenced this pull request Feb 7, 2024
This guide explains major concurrency and performance principles
for Puma and CRuby, when to possibly not use Puma, and how to
do basic load testing for tuning production performance settings.
Incorporates comments from Rails issue rails#50450, PR rails#50669 and
feedback from Jean Boussier.

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
@zzak zzak mentioned this pull request Feb 15, 2024
4 tasks
noahgibbs added a commit to noahgibbs/rails that referenced this pull request May 24, 2024
This guide explains major concurrency and performance principles
for Puma and CRuby, when to possibly not use Puma, and how to
do basic load testing for tuning production performance settings.
Incorporates comments from Rails issue rails#50450, PR rails#50669 and
feedback from Jean Boussier.

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
noahgibbs added a commit to noahgibbs/rails that referenced this pull request May 24, 2024
This guide explains major concurrency and performance principles
for Puma and CRuby, when to possibly not use Puma, and how to
do basic load testing for tuning production performance settings.
Incorporates comments from Rails issue rails#50450, PR rails#50669 and
feedback from Jean Boussier.

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Set a new default for the Puma thread count