Every vibe-coded app works with one user. The question is what happens with 100. Or 500. We ramped traffic from 10 to 1,000 simultaneous users and measured where each platform starts dropping requests, spiking latency, or returning errors.
This is where most vibe-coded apps fall apart. The demo works because the demo has one user: you. Production has spikes, crawlers, background jobs, and the occasional Hacker News front page. We used k6 to simulate sustained load at each concurrency level for 5 minutes, then measured error rates, p95 latency, and throughput (requests per second).
Percentage of requests that returned errors (5xx, timeouts, connection refused). Lower is better.
95th percentile latency at each concurrency level. Null values mean the platform was fully unresponsive.
Sustained request throughput at each concurrency level. Higher is better. Zero means complete failure.
The concurrency level at which error rate exceeds 25%. This is roughly where the platform stops being usable.
| Platform | Breaks at | Err @ 100 | Err @ 200 | Err @ 500 | Err @ 1000 | Peak RPS |
|---|
The answer is infrastructure, not code. Platforms running on shared VMs or single-tenant containers hit a hard ceiling when concurrent connections exceed what one machine can handle. There's no horizontal scaling — the app runs on a single node, and when that node is saturated, requests queue or fail.
Platforms built on serverless infrastructure (Lambda, Edge Functions) scale by design. Each request gets its own execution context. At 1,000 concurrent users, Lambda spins up 1,000 instances. There's a cost for this — cold starts, as we measured separately — but the error rate stays low.
The throughput chart tells the real story. Peak RPS is the platform's ceiling under ideal conditions. Platforms that max out at 400-600 RPS can handle a blog. Platforms that sustain 3,000+ RPS can handle a product launch.
Load tests used k6 with a step-up profile: each concurrency level sustained for 5 minutes before ramping to the next. The test application performed an authenticated read (GET) and a write (POST with DB insert) in a 70/30 mix. Full methodology →