diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 3057665bbec567331ad5ea03d31af707f5e91b4c..7a54638db191982d538cabf007d82715fa254b6a 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -62,6 +62,7 @@
 #include "common/string.h"
 #include "fe_utils/cancel.h"
 #include "fe_utils/conditional.h"
+#include "fe_utils/socket_utils.h"
 #include "getopt_long.h"
 #include "libpq-fe.h"
 #include "pgbench.h"
@@ -6698,7 +6699,7 @@ clear_socket_set(socket_set *sa)
 static void
 add_socket_to_set(socket_set *sa, int fd, int idx)
 {
-	if (fd < 0 || fd >= FD_SETSIZE)
+	if (fd < 0 || !check_fd_set_size(fd, &sa->fds))
 	{
 		/*
 		 * Doing a hard exit here is a bit grotty, but it doesn't seem worth
diff --git a/src/bin/scripts/scripts_parallel.c b/src/bin/scripts/scripts_parallel.c
index ec264a269a7d7a506c347112af6be183b2aec9ce..61977741c7c5f76b1966ab8e59792a1d2b53b934 100644
--- a/src/bin/scripts/scripts_parallel.c
+++ b/src/bin/scripts/scripts_parallel.c
@@ -25,6 +25,7 @@
 #include "common.h"
 #include "common/logging.h"
 #include "fe_utils/cancel.h"
+#include "fe_utils/socket_utils.h"
 #include "scripts_parallel.h"
 
 static void init_slot(ParallelSlot *slot, PGconn *conn);
@@ -144,6 +145,16 @@ ParallelSlotsGetIdle(ParallelSlot *slots, int numslots)
 			if (sock < 0)
 				continue;
 
+			/*
+			 * Fail and exit immediately if trying to use a socket in an
+			 * unsupported range.
+			 */
+			if (!check_fd_set_size(sock, &slotset))
+			{
+				pg_log_fatal("too many jobs for this platform -- try %d", i);
+				exit(1);
+			}
+
 			FD_SET(sock, &slotset);
 			if (sock > maxFd)
 				maxFd = sock;
@@ -221,18 +232,6 @@ ParallelSlotsSetup(const ConnParams *cparams,
 		for (i = 1; i < numslots; i++)
 		{
 			conn = connectDatabase(cparams, progname, echo, false, true);
-
-			/*
-			 * Fail and exit immediately if trying to use a socket in an
-			 * unsupported range.  POSIX requires open(2) to use the lowest
-			 * unused file descriptor and the hint given relies on that.
-			 */
-			if (PQsocket(conn) >= FD_SETSIZE)
-			{
-				pg_log_fatal("too many jobs for this platform -- try %d", i);
-				exit(1);
-			}
-
 			init_slot(slots + i, conn);
 		}
 	}
diff --git a/src/include/fe_utils/socket_utils.h b/src/include/fe_utils/socket_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..31f00c869631a8845823d99c74045557d6272e19
--- /dev/null
+++ b/src/include/fe_utils/socket_utils.h
@@ -0,0 +1,38 @@
+/*-------------------------------------------------------------------------
+ *
+ * Socket-processing utility routines for frontend code
+ *
+ *
+ * Portions Copyright (c) 2020, PostgreSQL Global Development Group
+ *
+ * src/include/fe_utils/socket_utils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SOCKET_UTILS_H
+#define SOCKET_UTILS_H
+
+/*
+ * Return true if the file descriptor can be added to the set with the size
+ * FD_SETSIZE and false otherwise.
+ */
+static inline bool
+check_fd_set_size(int fd, const fd_set *fds)
+{
+#ifdef WIN32
+	/*
+	 * We cannot check the socket value at runtime because on Windows it can be
+	 * greater than or equal to FD_SETSIZE.
+	 */
+	Assert(fds != NULL);
+	return (fds->fd_count < FD_SETSIZE);
+#else							/* !WIN32 */
+	/*
+	 * POSIX: the behavior of the macro FD_SET is undefined if the fd argument
+	 * is less than 0 or greater than or equal to FD_SETSIZE.
+	 */
+	return (fd < FD_SETSIZE);
+#endif							/* !WIN32 */
+}
+
+#endif							/* SOCKET_UTILS_H */
