Connections are the currency
Held connections are the currency you are spending here.
Every parked request pins a socket, a file handle, and whatever state your framework keeps per request. Plan capacity by connections at once, not by requests a second.
On an event loop the cost per connection is small, a few tens of kilobytes, and one machine comfortably parks 50,000 requests. Raise your file handle limits before anything else, because the default of 1,024 on many Linux images is your first outage.
Solve fan-out second. With one server, waking a parked request is a lookup inside the process. With ten servers behind a balancer, the event for Anna might be created by a request that landed on server 3 while Anna's poll is parked on server 7.
Put a pub/sub backbone underneath. Every server subscribes to channels for the users it is currently holding, and whatever produces events publishes without caring who holds whom.
Take comfort that this is the same architecture server-sent events and WebSocket fleets need, so the work transfers if you migrate later.
Stampedes
Expect stampedes third, and expect them to page you. A deploy or a crash drops tens of thousands of parked requests at once, and every one of those clients reconnects immediately, each doing a handshake and an auth check.
Your balancer sends that herd at the surviving servers, which can take those down too.
Defend on three fronts. Drain servers slowly before restarting them. Add a few seconds of randomness to client reconnects. And make reconnect auth cheap, a token check instead of a database lookup.
Know your exit as well. When each client is getting close to a message a second, the overhead of reconnecting per message means you are running a worse version of server-sent events. Switch then, rather than tuning.
Worked example
A quiz app runs live game updates over long polling: 4 servers, about 45,000 parked requests at peak on a Sunday night. A routine deploy restarts servers one at a time with a 5 second pause between them, which drops roughly 11,000 clients per restart. Every one reconnects within a second, the auth middleware does a Postgres session lookup per request, and the database hits max connections, which fails health checks on the remaining servers and turns a rolling deploy into a 9 minute full outage. The postmortem produces three fixes: reconnect jitter of 0 to 4 seconds in the client, session tokens validated from Redis, an in-memory store, instead of the main database, and a 60 second drain per server during deploys. The next Sunday deploy goes completely unnoticed, which is the point.