Legal AI infrastructure for firms
AI RFP discovery and response drafting
Automatic.coBusiness process automation
Secure AI virtual data rooms
What Breaks When AI-Generated Applications Scale to 100,000 Users
The usual story about AI-generated applications is that they ship fast and then quietly rot. The more useful story is more specific: they ship fast, hold up through the demo and the first few hundred users, and then break in a predictable sequence as traffic climbs. A quarter of YC's Winter 2025 batch reportedly runs on codebases that are roughly 95% AI-generated, and a growing number of those products are now meeting real traffic for the first time.
What follows is the triage list. Not a philosophical take on vibe coding, not another audit checklist. The concrete things that break between 1,000 and 100,000 users in applications generated by Cursor, Lovable, Bolt, Claude Code, and the long tail of agent frameworks, in roughly the order they tend to break.
The Failure Pattern Is Repeatable, Not Random
The industry data lines up with what shows up in triage. New Relic's 2026 State of AI Coding report found that 78% of organizations report a measurable spike in production incidents directly tied to AI code, and that AI-generated code introduces roughly 1.7 times more critical runtime issues than human-authored code. Qodo's 2026 State of AI Code Quality report puts the share of organizations that have experienced an AI-related production incident at 89%, with only 3.7% of engineering leaders saying their existing processes are sufficient to govern the work.
Confidence is not the problem. SmartBear's 2026 State of Software Quality and Testing found that 46% of software professionals have shipped AI-generated code that later failed in production, while 69% of those teams still have a lot or complete confidence in the output. The failures are not exotic. They are the same handful of patterns, repeated.
N+1 Queries Hide Until the Table Grows
The single most common scaling failure in AI-generated backends is the N+1 query. The agent writes the straightforward loop: fetch a list of orders, then for each order fetch the customer, then for each customer fetch the plan. In Django that is .all() without select_related; in Rails it is a missing includes; in Prisma it is a nested read without include. On a demo dataset of 50 rows nobody notices. At 50,000 rows per tenant you are issuing 50,001 queries per request.
The fix is boring and known: eager loading, batched IN queries, DataLoader on the GraphQL layer, and query logging in staging with a hard ceiling (fail the test if a request issues more than, say, 15 queries). None of this is in the generated code because none of it is in the prompt.
Missing Indexes and the Flat Module Graph
Right behind N+1 is the missing index. AI-generated migrations tend to declare foreign keys without indexing them, and tend to skip composite indexes on the exact (tenant_id, status, created_at) tuple every list view filters on. Postgres will sequential-scan a million-row table happily for a while. It will not do it under concurrent load.
The structural companion to the missing index is the flat module graph. Generated code tends to grow outward from a single api/ or routes/ folder, with business logic inlined into handlers and no clear seam between domain, persistence, and transport. GitClear's 2025 AI Copilot Code Quality report, based on 211 million lines of changes, found an eight-fold rise in duplicated blocks in 2024 and a drop in refactored (moved) code from 24.1% of changed lines in 2021 to 9.5% in 2024. Two-week churn climbed from 3.1% to 5.7%. The practical consequence is that the thing you need to extract to scale, there is no seam to extract along. Replatforming becomes the only option, which is a different kind of project with a different budget.

Session State in Memory Fails on the Second Instance
Below roughly 5,000 users, one application instance is usually enough and nobody notices that session state, rate-limit counters, feature flags, and cached user profiles are all stored in process memory. Autoscale to two instances behind a load balancer and users get randomly logged out, idempotency keys stop working, and rate limits reset every time a request hops nodes.
The fix is Redis or an equivalent out-of-process store for anything stateful, sticky sessions only as a bridge, and JWTs with short expiries for auth. Agents do not reach for this by default because the single-process version runs locally and passes the generated tests.
Synchronous Fan-Out Blocks the Request Thread
AI-generated endpoints routinely do work inline that belongs in a queue. The checkout handler charges Stripe, writes to the orders table, sends a confirmation email, calls the shipping API, posts to Slack, and triggers a webhook, all before returning 200. On a laptop this is 400 ms. Under load, every slow downstream becomes your p99.
The pattern that holds is well-worn: return 202 fast, enqueue the fan-out, process it in background workers or concurrent workers with retries, and make every step idempotent on a shared key. Without idempotency, your retry logic double-charges customers. The agent did not write the idempotency key because you did not ask it to.
Connection Pools, Or the Database Falls Over First
The database usually fails before the application does, and usually not from query volume. It fails from connections. Each PostgreSQL connection consumes 5-10 MB of RAM, spawns a dedicated backend process, and takes 20-100 ms to establish. Default max_connections is 100. A serverless deployment that opens a fresh connection per request, or four services each holding a 25-connection pool, will saturate a default Postgres instance before user traffic matters.
PgBouncer in transaction mode, RDS Proxy, or Supavisor in front of the database, with an application-side pool sized to the number of CPU cores (not the number of expected users), is the default. Generated code almost never configures this because the local dev database has no pool pressure.
Over-Permissive IAM and the Shared Secret
Security failures in AI-generated applications are not subtle. A critical vulnerability (CVE-2025-48757) in applications generated by the Lovable platform exposed 303 vulnerable endpoints across 170 projects, roughly 10.3% of the 1,645 analyzed, through missing or misconfigured Row Level Security, leaking emails, API keys, home addresses, and personal debt amounts. A separate April 2026 flaw in Lovable's own API verified authentication tokens but failed to check project ownership, exposing every project created before November 2025, including source code, database credentials, and Stripe IDs, through five API calls.
At the application layer this shows up as service accounts with full database rights, API keys committed to the repo, S3 buckets with public read, and no row-level isolation between tenants. For anything multi-tenant, secure data isolation has to be designed in; it is not emergent. For agents touching real systems, approvals, audits, and role-based controls have to exist before the agent ships, not after.
The Triage Order That Actually Works
| Failure mode | First shows up | Root cause in generated code | Standard fix |
|---|---|---|---|
| N+1 ORM queries | 5k-20k users | Loops over related records | Eager loading, query ceiling in CI |
| Missing indexes | 10k-30k users | FKs not indexed, no composites | Composite indexes on filter tuples |
| In-memory session state | Second instance | Agent built single-process | Redis, JWT, sticky as bridge |
| Synchronous fan-out | 20k+ users | Third-party calls in request path | Queues, idempotency keys, 202 |
| Connection exhaustion | Autoscale event | No pooler, per-request connects | PgBouncer or RDS Proxy |
| Over-permissive IAM | First audit or incident | Default admin creds, no RLS | Least privilege, tenant isolation |
| Flat module graph | First refactor attempt | Logic inlined into handlers | Extract domain, strangler-fig |
Google's 2024 DORA report found that a 25% increase in AI adoption was associated with an estimated 1.5% decrease in software delivery throughput and a 7.2% decrease in delivery stability, even though 75.9% of respondents used AI for at least part of their work. The gains are real at the keystroke level and partially undone at the system level. That gap is what triage closes.
In order, before you add features: turn on query logging and kill the top ten N+1s; add the composite indexes the load tests reveal; move session state and rate limits to Redis; put a connection pooler in front of Postgres; move anything that calls a third party out of the request path and into a queue with idempotency keys; audit IAM, secrets, and tenant isolation; and only then start carving seams into the module graph. This is the same list for a codebase being audited before launch and for one already losing users at 20,000 MAU.
What This Means for the Build Decision
AI-generated applications are not uniquely bad. They are uniquely consistent: they fail in the same places, for the same reasons, on roughly the same schedule. Which means they are triageable rather than mysterious. The founders who get through this phase treat the generated codebase as a prototype that happens to be in production, and spend the next engineering budget on the seven items above rather than on the next feature.
The honest version of the AI-assisted versus traditional comparison is not that one is better. It is that AI gets you to 1,000 users faster and leaves the 100,000-user work undone. Someone still has to do it. Whether that is an in-house senior hire, a dedicated pod, or a staged modernization depends on how much of the original architecture is worth keeping. Usually more than the audit's first pass suggests, and less than the founder hopes.
