Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uZx7b-00BHoq-Ec for pgsql-general@arkaria.postgresql.org; Thu, 10 Jul 2025 19:39:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1uZx7X-00GYxc-EL for pgsql-general@arkaria.postgresql.org; Thu, 10 Jul 2025 19:39:52 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uZx7W-00GYxU-Sq for pgsql-general@lists.postgresql.org; Thu, 10 Jul 2025 19:39:51 +0000 Received: from mail-lj1-x235.google.com ([2a00:1450:4864:20::235]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uZx7V-006csk-2I for pgsql-general@lists.postgresql.org; Thu, 10 Jul 2025 19:39:50 +0000 Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-32b3a3a8201so12040611fa.0 for ; Thu, 10 Jul 2025 12:39:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1752176385; x=1752781185; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=xW+AnrnSJytcL+acQl+lotPO4vS5hDRgrgOSo2XZvSE=; b=O7zfhVf3m1Hx++47yFDu/vln3MYq7awtQTpj0sREHJ4h27CAe5HFf0WKUe50btC8Wx yKu7x+mrPsmmTv9omVW1szAS46rGRpo0yTUMgRw43U5eENPrYzYGs8wV5qRcRciCuvEB gVyZ6vT+AHFLs6VdCtun3+I5vArRmtcovpblHRwoXmAY5hNlNebcsHSRnAyP8/mdyVp8 pEi1XVDflK5KG+NNlmU0RGjhuY4dORrp5FTSOaVL3OE5v8uY6zm6w4BqFLgD7yMZ0aNH DY8hhySPIuaE1Kcq+f/KvCPwue0juWbR/xqF5Hv6CG46H+nn2lmPsTIDt1q4E7kpYsF1 hU+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752176385; x=1752781185; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=xW+AnrnSJytcL+acQl+lotPO4vS5hDRgrgOSo2XZvSE=; b=NUU4Vkgiv3/yVyIzfbVlGssXfzzrhnsE4AngOT0/VjayqhRZ1OAwTVuoMa2hrQ6onW LR5GKAM5cG2BdMDOAoK657+ZGLd679kbYYDdTRRnmQnWELK20bXgWBDss5qmjVt+WhK3 5iJKGwlq+UQWhdn+dc01dzWERnurSLivFbds3SafIQRvodC52Ly0hHSPwSzlpxyCGRte Gg6UxHYekloHL2U0JirXqrgXkn8NJfl7qhjrCg+WgBmZ77KCXSYsXSckM/08kGDjqlk4 DvE9Cb9rNDl6jJpfrPxHakfD0vO5C7mrU8Qi5bZPJE5vxBE+4yAouaEtTtyxOh5QYJBH i6LA== X-Gm-Message-State: AOJu0YzcJ9DbbyyF5TfNw5E3fwkYtLltRVAMTvstg1F78K279hFAxaIo qdMmJhy2ccq0aAm3gNQQb6u8vp/SNUP8Rcw4Y5h4dl+FtNDiyI8wPpQnKu0y4L7zE7tTPA8cChG UE2+QForPhMdJJolXaUDVQW1BINILp6hQ70Bd X-Gm-Gg: ASbGncvwn+PrfAVKRbYqGocrzbFls2baEYJQpfNALYyukZ9/sLs7wat5f8UYOKt2/U1 WmbFBIveAGv1JEigaF0z3JH/hMkdoFZAQxAHOXxsCDg7NcUEYBkO2SqAz1OOmST8SCPcW3SXlbD JpxccxX0mHwTRxtQARiD7RWyNUKElSGt9oJF/284tNEw== X-Google-Smtp-Source: AGHT+IG+KaxoIhBKwCGaZ4qH8JwZ6M7tAbOhAH1dD1GZIH53lRziMxLfzUBwERCDdAdrxvf1tGjw7vGq10mzQfJojYA= X-Received: by 2002:a05:651c:220d:b0:32a:8062:69b1 with SMTP id 38308e7fff4ca-33053279426mr523201fa.8.1752176385213; Thu, 10 Jul 2025 12:39:45 -0700 (PDT) MIME-Version: 1.0 From: Greg Hennessy Date: Thu, 10 Jul 2025 15:39:12 -0400 X-Gm-Features: Ac12FXzXBFkoYE63voXQqc0VNBxjRHTK2LC81u_NvDTPBqluVkGV0Kq2VEVv9tc Message-ID: Subject: optimizing number of workers To: pgsql-general@lists.postgresql.org Content-Type: multipart/alternative; boundary="0000000000000649c90639985bf0" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000000649c90639985bf0 Content-Type: text/plain; charset="UTF-8" Having just received a shiny new dual CPU machine to use as a postgresql server, I'm trying to do some reasonable efforts to configure it correctly. The hard ware has 128 cores, and I am running a VM with Redhat 9 and Postgresql 16.9. In postgresql.conf I have: max_worker_processes = 90 # (change requires restart) max_parallel_workers_per_gather = 72 # gsh 26 oct 2022 max_parallel_maintenance_workers = 72 # gsh 12 jun 2025 max_parallel_workers = 72 # gsh 12 jun 2025 max_logical_replication_workers = 72 # gsh 12 jun 2025 max_sync_workers_per_subscription = 72 # gsh 12 jun 2025 autovacuum_max_workers = 12 # max number of autovacuum subprocesses When I do a simple count of a large (large being 1.8 Billion entries), I get about 10 workers used. prod_v1_0_0_rc1=# explain (analyze, buffers) select count(*) from gaiadr3.gaia_source; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=14379796.81..14379796.82 rows=1 width=8) (actual time=16702.806..16705.479 rows=1 loops=1) Buffers: shared hit=2507481 -> Gather (cost=14379795.78..14379796.79 rows=10 width=8) (actual time=16702.513..16705.470 rows=11 loops=1) Workers Planned: 10 Workers Launched: 10 Buffers: shared hit=2507481 -> Partial Aggregate (cost=14379785.78..14379785.79 rows=1 width=8) (actual time=16691.820..16691.821 rows=1 loops=11) Buffers: shared hit=2507481 -> Parallel Index Only Scan using gaia_source_nest128 on gaia_source (cost=0.58..13926632.85 rows=181261171 width=0) (actual time=0.025..9559.644 rows=164700888 loops=11) Heap Fetches: 0 Buffers: shared hit=2507481 Planning: Buffers: shared hit=163 Planning Time: 14.898 ms Execution Time: 16705.592 ms Postgres has chosen to use only a small fraction of the CPU's I have on my machine. Given the query returns an answer in about 8 seconds, it may be that Postgresql has allocated the proper number of works. But if I wanted to try to tweak some config parameters to see if using more workers would give me an answer faster, I don't seem to see any obvious knobs to turn. Are there parameters that I can adjust to see if I can increase throughput? Would adjusting parallel_setup_cost or parallel_tuple_cost likely to be of help? --0000000000000649c90639985bf0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Having just received a shiny new dual CPU machine=C2=A0to = use as a postgresql
server, I'm trying to do some reasonable effort= s to configure it correctly. The hard
ware has 128 cores, and I a= m running a VM with Redhat 9 and Postgresql=C2=A0 16.9.

In postgresql.conf I have:
max_worker_processes =3D 90 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # (change requires restart)max_parallel_workers_per_gather =3D 72 =C2=A0 =C2=A0# gsh 26 oct 2022
= max_parallel_maintenance_workers =3D 72 =C2=A0 # gsh 12 jun 2025
max_par= allel_workers =3D =C2=A072 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= # gsh 12 jun 2025
max_logical_replication_workers =3D 72 =C2=A0 =C2=A0# = gsh 12 jun 2025
max_sync_workers_per_subscription =3D 72 =C2=A0 # gsh 12= jun 2025
autovacuum_max_workers =3D 12 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 # max number of autovacuum subprocesses

=
When I do a simple count of a large (large being 1.8 Billion entries),= I get
about 10 workers used.

prod_v1_0_= 0_rc1=3D# explain (analyze, buffers) select count(*) from gaiadr3.gaia_sour= ce;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0QUERY PLAN
----------------------------------= ---------------------------------------------------------------------------= ---------------------------------------------------------------------------= ----
=C2=A0Finalize Aggregate =C2=A0(cost=3D14379796.81..14379796.82 row= s=3D1 width=3D8) (actual time=3D16702.806..16705.479 rows=3D1 loops=3D1)=C2=A0 =C2=A0Buffers: shared hit=3D2507481
=C2=A0 =C2=A0-> =C2=A0Gat= her =C2=A0(cost=3D14379795.78..14379796.79 rows=3D10 width=3D8) (actual tim= e=3D16702.513..16705.470 rows=3D11 loops=3D1)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0Workers Planned: 10
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Workers = Launched: 10
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Buffers: shared hit=3D250= 7481
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0-> =C2=A0Partial Aggregate =C2= =A0(cost=3D14379785.78..14379785.79 rows=3D1 width=3D8) (actual time=3D1669= 1.820..16691.821 rows=3D1 loops=3D11)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0Buffers: shared hit=3D2507481
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0-> =C2=A0Parallel Index Only Scan usin= g gaia_source_nest128 on gaia_source =C2=A0(cost=3D0.58..13926632.85 rows= =3D181261171 width=3D0) (actual time=3D0.025..9559.644 rows=3D164700888 loo= ps=3D11)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0Heap Fetches: 0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Buffers: shared hit=3D2507481
=C2=A0Pl= anning:
=C2=A0 =C2=A0Buffers: shared hit=3D163
=C2=A0Planning Time: 1= 4.898 ms
=C2=A0Execution Time: 16705.592 ms

Postgres h= as chosen to use only a small fraction of the CPU's I have on
my machine. Given the query returns an answer in about 8 seconds, it may b= e
that Postgresql has allocated the proper number of works. But i= f I wanted
to try to tweak some config parameters to see if using= more workers
would give me an answer faster, I don't seem to= see any obvious knobs
to turn. Are there parameters that I can a= djust to see if I can increase
throughput? Would adjusting parall= el_setup_cost or parallel_tuple_cost
likely to be of help?=C2=A0<= /div>
--0000000000000649c90639985bf0--