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 sizeAnswer rateAnswers acceptedFailedAccept time p50 / p95 / p99
30025/sec300017 / 31 / 46 ms
1,50050/sec1,500016 / 35 / 66 ms
2,500100/sec2,500020 / 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.

ParticipantsConnectedFailedSlowest connect (p99)
1,0001,00009 ms
3,0003,00008 ms
5,0005,00007 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 gateway
  • scripts/load-test/realtime-load.mjsconcurrent WebSocket participants
  • scripts/load-test/sse-flood.mjsconcurrent live-results viewers
  • scripts/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 testdocs/LOAD_TEST_CAPACITY_2026-07.md2026-07-11
  • Live-path regression testdocs/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.