Four few known facts that are often ignored:

POSIX systems (Linux, BSD, macOS) use “file descriptors” for sockets.

These file descriptors are a numerical value that usually translates to a kernel array index linked to the process.

2. the select system call breaks when the file descriptor value is over 1023 (on some systems 2047). On Linux, this is a libc restriction rather than a kernel restriction:

POSIX allows an implementation to define an upper limit, advertised via the constant FD_SETSIZE, on the range of file descriptors that can be specified in a file descriptor set. The Linux kernel imposes no fixed limit, but the glibc implementation makes fd_set a fixed- size type, with FD_SETSIZE defined as 1024, and the FD_*() macros operating according to that limit. To monitor file descriptors greater than 1023, use poll(2) instead.

3. The Puma application server for Ruby uses select under the hood (I’m waiting for this to change).

This effectively limits each Puma process to 1023 open file descriptors, including sockets, database connections, etc’.

This is usually okay, assuming the number of concurrent connections isn’t too high or the server isn’t idle.

4. Using ActionCable drives the number of concurrent connections upwards, potentially breaking the select system call used by Puma.