diff --git a/pseudo_server.c b/pseudo_server.c
index fc5c2c1..77d1c39 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -626,6 +626,7 @@ static void pseudo_server_loop_epoll(void)
 	struct sigaction eat_usr2 = {
 		.sa_handler = set_do_list_clients
 	};
+	int hitmaxfiles = 0;
 
 	clients = malloc(16 * sizeof(*clients));
 	if (!clients) {
@@ -724,8 +725,8 @@ static void pseudo_server_loop_epoll(void)
 								exit(PSEUDO_EXIT_EPOLL_CTL);
 							}
 						} else if (errno == EMFILE) {
-							// select() loop would drop a client here, we do nothing (for now)
-							pseudo_debug(PDBGF_SERVER, "Hit max open files.\n");
+							hitmaxfiles = 1;
+							pseudo_debug(PDBGF_SERVER, "Hit max open files, dropping a client.\n");
 						}
 					}
 				} else if (clients[client_id].fd != -1) {
@@ -742,6 +743,27 @@ static void pseudo_server_loop_epoll(void)
 				if (die_forcefully)
 					break;
 			}
+			/* The listening socket stays readable while accept()
+			 * fails, so make room by dropping one client that had
+			 * no event in this batch, and so can't have one pending
+			 * in it either.
+			 */
+			if (hitmaxfiles && !die_forcefully) {
+				hitmaxfiles = 0;
+				for (i = 1; i <= highest_client; ++i) {
+					int j;
+					if (clients[i].fd == -1)
+						continue;
+					for (j = 0; j < rc; ++j) {
+						if ((int) events[j].data.u64 == i)
+							break;
+					}
+					if (j == rc) {
+						close_client(i);
+						break;
+					}
+				}
+			}
 			pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);
 		} else {
 			pseudo_error("epoll_wait failed: %s\n", strerror(errno));
