Thread: sensible configuration of max_connections
Hi All, What's a sensible way to pick the number to use for max_connections? I'm looking after a reasonable size multi-tenant cluster, where the master handles all the load and there's a slave in case of hardware failure in the master. The machine is used to host what I suspect are mainly django applications, so lots of short web requests, not sure how much, if any, django's orm does connection pooling. I arbitrarily picked 1000 for max_connections and haven't had any problems, but onboarding another app that handles a few million requests per day on Monday and thinking about potential problems related to the number of available connections. What's "too much" for max_connections? What happens when you set it to high? What factors affect that number? cheers, Chris
Hi All,
What's a sensible way to pick the number to use for max_connections?
I'm looking after a reasonable size multi-tenant cluster, where the
master handles all the load and there's a slave in case of hardware
failure in the master.
The machine is used to host what I suspect are mainly django
applications, so lots of short web requests, not sure how much, if any,
django's orm does connection pooling.
I arbitrarily picked 1000 for max_connections and haven't had any
problems, but onboarding another app that handles a few million requests
per day on Monday and thinking about potential problems related to the
number of available connections.
What's "too much" for max_connections? What happens when you set it to
high? What factors affect that number?
cheers,
Chris
Sure, but that's where I'm trying to find out what's sensible. The box has 196GB memory, most of that in hugepages, 18 core Intel Skylake with HT on giving 36 cores and tonnes of SSD for storage. How would I turn that spec into a sensible number for max_connections? As that number grows, what contention points in postgres will start creaking (shared memory where the IPC happens?)What's "too much" for max_connections? What happens when you set it tohigh? What factors affect that number?When sizing max_connections you need to trade off how many connections your application will use at peak vs how much RAM and CPU you have.Each connection is capable of allocating work_mem and has a stack etc.As such you don't want max_connections to be able to run your system out of RAM.
In case I forgot to say, this is PostgreSQL 11...
Chris
PS: definitely thinking of pg_bouncer, but still trying to figure out what to sensibly set for max_connections.
Hi ChrisOn Fri, 7 Feb 2020, 08:36 Chris Withers, <chris@withers.org> wrote:Hi All,
What's a sensible way to pick the number to use for max_connections?Sensible in this context is some what variable. Each connection in PostgreSQL will be allocated a backend process. These are not the lightest weight of things.Each connection takes up space in shared memory, as mentioned in the manual.
I'm looking after a reasonable size multi-tenant cluster, where the
master handles all the load and there's a slave in case of hardware
failure in the master.
The machine is used to host what I suspect are mainly django
applications, so lots of short web requests, not sure how much, if any,
django's orm does connection pooling.
I arbitrarily picked 1000 for max_connections and haven't had any
problems, but onboarding another app that handles a few million requests
per day on Monday and thinking about potential problems related to the
number of available connections.
What's "too much" for max_connections? What happens when you set it to
high? What factors affect that number?When sizing max_connections you need to trade off how many connections your application will use at peak vs how much RAM and CPU you have.Each connection is capable of allocating work_mem and has a stack etc.As such you don't want max_connections to be able to run your system out of RAM.Given your situation I'd very seriously look at connection pooling using PgBouncer or similar. That way you can run with a far smaller max_connections and still cope with applications configured with large usually idle connection pools.
cheers,
ChrisRegards,Chris Ellis
On 07/02/2020 12:49, Chris Ellis wrote:Sure, but that's where I'm trying to find out what's sensible. The box has 196GB memory, most of that in hugepages, 18 core Intel Skylake with HT on giving 36 cores and tonnes of SSD for storage. How would I turn that spec into a sensible number for max_connections? As that number grows, what contention points in postgres will start creaking (shared memory where the IPC happens?)What's "too much" for max_connections? What happens when you set it tohigh? What factors affect that number?When sizing max_connections you need to trade off how many connections your application will use at peak vs how much RAM and CPU you have.Each connection is capable of allocating work_mem and has a stack etc.As such you don't want max_connections to be able to run your system out of RAM.
The max_connections setting is an upper limit after which postgresql will reject connections. You don't really want to hit that limit, rather you want to keep the number of concurrent connections to a reasonable number (and have max_connections somewhere above that).
Each connection is a postgresql process, so active connections are competing for resources and even idle connections take up some RAM. Creating a new connection is launching a new process (and doing some setup) so it's relatively expensive.
Doing some sort of connection pooling is a good idea, especially for web-apps that connect, do a few short queries and disconnect. Django is probably doing a passable job at pooling already, so you might want to see how many connections it's using under normal load. Adding a dedicated pooler in between Django and PostgreSQL would give you more flexibility and might be a good idea, but if what Django is already doing is reasonable you may not need it.
What's a good number of active connections to aim for? It probably depends on whether they tend to be CPU-bound or IO-bound, but I've seen the rule of thumb of "around twice the number of CPU cores" tossed around, and it's probably a decent place to start, then run it under normal load and see how it behaves - cpu usage, RAM, IO, request latency and throughput.
Cheers,
Steve
WorkMem is the biggest consumer of resources lets say its set to 5 megs per connection at 1000 connections that 5,000 megs that can be allocated.
What's a good number of active connections to aim for? It probably depends on whether they tend to be CPU-bound or IO-bound, but I've seen the rule of thumb of "around twice the number of CPU cores" tossed around, and it's probably a decent place to start, then run it under normal load and see how it behaves - cpu usage, RAM, IO, request latency and throughput.
Benchmarks, at the time, showed that performance started to fall off due to contention if the number of processes got much larger. I imagine that the speed of storage today would maybe make 3 or 4x core count a pretty reasonable place to start. There will be a point of diminishing returns somewhere, but you can probably construct your own benchmarks to determine where that point is likely to be for your workload.
On Fri, Feb 7, 2020 at 1:56 PM Sam Gendler <sgendler@ideasculptor.com> wrote:Benchmarks, at the time, showed that performance started to fall off due to contention if the number of processes got much larger. I imagine that the speed of storage today would maybe make 3 or 4x core count a pretty reasonable place to start. There will be a point of diminishing returns somewhere, but you can probably construct your own benchmarks to determine where that point is likely to be for your workload.I wonder if anyone has run benchmark like that lately? Doing such a benchmark maybe worth while given that so much is now running either in the cloud or running in a VM or some other kind of Container. all this abstraction from the hardware layer surely has had to have an impact on the numbers and rules of thumb...I still run on real hardware and spinning disk.