Capacity, measured on production
20,000 people. Zero dropped connections.
Every number on this page came from a load test against the real pollslive.com - not a staging clone, not a projection on a spreadsheet. Below is the method, the full results, and the ceiling we have not crossed.
Last measured July 20, 2026
What we measured
Four numbers, each from a named run against production. Every one carries its caveat.
2,500
people answering the same question at once
All 2,500 answers accepted, none dropped, at a sustained 100 answers per second.
2026-07-20
20 ms
median time to accept an answer
p95 77 ms, p99 104 ms, slowest single answer 140 ms - in that same 2,500-person room.
2026-07-20
20,000
concurrent live participants
All 20,000 connected and received the state fan-out. Zero failures, p99 connect 34 ms.
2026-07-11
8,000
people watching results update live
Zero failures. A later run held 4,000 viewers while the answer storm was still running.
2026-07-11
The moment that actually matters
Nobody worries about whether people can join. They worry about the second you reveal the question and the entire room answers at once. That is a burst of database writes, and it is where audience tools fall over. So we drove it deliberately: a real room, real joins, real answers through the real gateway.
| Room size | Answer rate | Answers accepted | Failed | Accept time p50 / p95 / p99 |
|---|---|---|---|---|
| 300 | 25/sec | 300 | 0 | 17 / 31 / 46 ms |
| 1,500 | 50/sec | 1,500 | 0 | 16 / 35 / 66 ms |
| 2,500 | 100/sec | 2,500 | 0 | 20 / 77 / 104 ms |
Read the last column downward. The room grows eight times over and the answer rate four times over, and the median barely moves. That is the point: response time does not degrade as the room gets bigger.
Why it stays flat
The live tally used to be recalculated from every response on the slide, so each new answer cost a little more than the last - fine at 200 people, ugly at 2,000. It is now an incremental counter, which makes the cost of an answer independent of how many came before it.
Getting everyone into the room
Before anyone can answer, they have to join. Each participant holds an open WebSocket for the whole session, so this is about how many connections one box will carry - and how long the slowest person waits to get in.
| Participants | Connected | Failed | Slowest connect (p99) |
|---|---|---|---|
| 1,000 | 1,000 | 0 | 9 ms |
| 3,000 | 3,000 | 0 | 8 ms |
| 5,000 | 5,000 | 0 | 7 ms |
The July run pushed this dimension to 20,000 concurrent participants with zero failures and a p99 connect of 34 ms, on the same hardware.
Where it stops
Publishing a limit is more useful than hiding one, so here is ours. Writes are the crash surface: about 100 answers per second runs clean across the whole platform, and around 180 per second is where the box gives up. The binding resource is CPU on a shared 4-core host - not the database, whose connection pool never came close to exhausting in either run.
This is where the plan limits come from
A room of N people answering within about ten seconds produces N/10 writes per second. Work backwards from the ceiling and you get the live-participant caps we actually enforce: 50 on Free, 1,000 on Pro, 1,500 on Team, 2,500 on an Event Pass, 5,000 on Enterprise. They are not arbitrary, and they are not a paywall dressed up as engineering.
We do not claim unlimited scale. If your room is bigger than the numbers above, tell us before the event and we will say yes or no honestly.
How we tested
Against real production
Not a clone. The generators drove the same edge proxy, app containers, database and realtime gateway that serve pollslive.com, off-peak, with a kill switch on the first sign of a 5xx or a failed health check.
With the rate limiters bypassed
Each synthetic request carried a unique forged client IP so the per-IP limiters could not mask capacity. We wanted to measure the server, not our own front door.
And cleaned up afterwards
Every run used a throwaway workspace, poll and session, deleted at the end and verified at zero residual rows. Production stayed green throughout, and so did the unrelated site sharing the box.
Conservatively
The load generators ran on the same box they were testing and consumed about a core of it. Real-world ceilings with external clients are modestly higher than what we published.
The tools that produced these numbers
All four are in the repository. Nothing here was measured with a script you cannot read.
scripts/load-test/answer-storm.mjslive answers through the gatewayscripts/load-test/realtime-load.mjsconcurrent WebSocket participantsscripts/load-test/sse-flood.mjsconcurrent live-results viewersscripts/load-test/vote-storm.mjsasync vote write throughput
The full reports
Both write-ups, including the runs that failed and the bottlenecks we have not fixed yet, are committed alongside the code.
- Capacity and stress test
docs/LOAD_TEST_CAPACITY_2026-07.md2026-07-11 - Live-path regression test
docs/LOAD_TEST_REGRESSION_2026-07-20.md2026-07-20
Bring your biggest room
Free to start, no card, no account needed to make one. If it holds 2,500 people answering at once, it will hold your all-hands.