diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 08a5947a9e..23f357315f 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -6698,10 +6698,22 @@ clear_socket_set(socket_set *sa)
 	sa->maxfd = -1;
 }
 
+#ifndef WIN32
+#define FD_IS_VALID(fd, set) ((fd) >= 0 && (fd) < FD_SETSIZE)
+#else
+/*
+ * Windows implementation is bogus: it does not allocate fd with the lowest
+ * possible number, and FD_SET is implemented as a simple array.
+ *
+ * Filling the set is in O(N^2).
+ */
+#define FD_IS_VALID(fd, set) ((fd) >= 0 && (set)->fd_count < FD_SETSIZE)
+#endif /* WIN32 */
+
 static void
 add_socket_to_set(socket_set *sa, int fd, int idx)
 {
-	if (fd < 0 || fd >= FD_SETSIZE)
+	if (!FD_IS_VALID(fd, &sa->fds))
 	{
 		/*
 		 * Doing a hard exit here is a bit grotty, but it doesn't seem worth
