KognitaKognita.

Blog

Vibe Coding Technical Debt: What Happens at 90 Days

12 min read

Vibe coding — building software by describing what you want to an AI and iterating until something works — is real, it is spreading, and the early velocity numbers are genuinely compelling. Teams that have adopted it fully report shipping features in hours that used to take days. Prototypes become products over a weekend. Non-technical founders launch MVPs without hiring an engineer.

The reckoning comes around the 90-day mark. Not always exactly 90 days, but consistently in that window. The codebase that felt like magic in the first month becomes the codebase nobody fully understands in the third month. Velocity drops. Bugs compound. Each new feature requires understanding what the previous features actually built — and that understanding is hard to acquire because nobody fully wrote the code and nobody documented the decisions.

This post is about what causes the 90-day reckoning, why it is structurally predictable rather than a fluke, and what it takes to maintain a codebase that was built primarily by AI.

The arc is consistent

Developer communities documented the pattern across enough real projects in 2025 to call it a pattern. The specific timelines vary — some teams hit the wall at 60 days, some at 120 — but the shape is consistent.

The 90-day vibe coding reckoning
The 90-day vibe coding reckoning — as described by teams across developer communities:

  Day 0–30:   shipping velocity is extraordinary
              features land in hours, not days
              the demo looks incredible

  Day 30–60:  each new feature takes noticeably longer
              changes in one area break behavior in three others
              the AI starts hallucinating implementations that "should exist"

  Day 60–90:  sprint velocity drops significantly
              20–30% of capacity goes to debugging AI-generated regressions
              nobody can confidently explain what the system does end-to-end
              new features require understanding code nobody fully wrote

The early velocity is real. This is not a case where the results are illusory. For greenfield development where requirements are clear and there is no existing system to integrate with, AI-first development genuinely delivers fast. Features that would take a week of careful implementation land in a day of prompt iteration.

The problem is that the debt accumulated during that fast early phase is not visible until the codebase gets large enough that every new change requires understanding what came before. At that point, the absence of human comprehension — of a developer who actually understood each decision and can explain the rationale — becomes a compounding liability.

Why vibe-coded codebases compound in complexity faster

Traditional technical debt accumulates because engineers made shortcuts under time pressure, made decisions that turned out to be wrong, or failed to anticipate future requirements. That debt is at least partially recoverable because the engineer who created it often knows where it is and why.

Vibe coding technical debt has a different character. It accumulates because AI tools, operating without persistent system understanding, make locally-reasonable decisions that are architecturally inconsistent at scale.

Why vibe-coded complexity compounds
Why vibe-coded codebases compound in complexity:
  -> implicit decisions: AI made architectural choices nobody documented
  -> naming drift: similar concepts get different names across sessions
  -> no canonical implementation: three versions of the same utility exist
  -> hidden coupling: files depend on each other in ways that are not obvious
  -> no rationale: there is no "why" attached to most of the decisions
  -> tribal knowledge gap: the only "memory" is the git history and the AI's training data

The canonical implementation problem is especially costly. When a developer builds a feature and then a similar feature, they use the same pattern, often literally reusing the same code. When an AI builds a feature in one session and then a similar feature in a later session — without access to the earlier session's context — it may build a second implementation that serves the same purpose but shares no code with the first. Two sessions later, there is a third. By month three, you have four implementations of notification sending, three approaches to error handling, and two user models — none of which the AI will automatically consolidate because it is not tracking what already exists.

This is the same fragmentation problem that makes codebases hard to navigate as graphs rather than file trees. The logical unit — "how we send notifications" — is scattered across multiple implementations with no canonical reference. The AI does not know which one to extend, so it builds another.

The maintenance wall: when adding features requires understanding features

The first month of vibe coding is fast because adding features does not require understanding the existing system. Everything is new, dependencies are simple, and the AI can generate each piece in relative isolation.

By month three, every new feature has dependencies. The new notification type depends on the notification system, which has three implementations. The new payment flow depends on the retry logic, which has a subtle difference between how the scheduled job and the webhook handler do it. The new user setting depends on a user model that has quietly grown to represent three different concepts depending on context.

Adding the new feature correctly requires understanding the existing system at a level of detail that nobody on the team has accumulated. The original developer did not fully write the existing system — they prompted it. The AI coding tool did not build a mental model of the system — it generated each piece independently. There is no human who carries the architectural knowledge. There is no document that faithfully describes it. There is only the code — and the code is dense, inconsistent, and underdocumented because consistency and documentation are not what vibe coding optimizes for.

The velocity math inverts

The 20–30% sprint capacity loss at the 90-day mark is not from working on the wrong things. It is from debugging regressions that trace back to the AI-generated implementation. A change in one service breaks behavior in a second service because of a coupling that was never made explicit. A new feature triggers an edge case in the payment flow because nobody knew the edge case existed. A performance issue emerges in production because the AI chose an approach that looks clean but scales poorly on real data volumes.

Each of these debugging cycles requires the same thing: someone has to understand what the system actually does, not just what it was prompted to do. That understanding is the asset that vibe coding does not naturally produce. The code exists. The rationale, the connections, the canonical implementations — those are implicit in the structure of the code, not documented anywhere accessible.

What maintaining a vibe-coded codebase actually requires

The mistake most teams make after hitting the 90-day wall is concluding that vibe coding was the wrong approach. That conclusion is usually wrong. The approach that got them to a working product fast is not the problem. The missing piece is a way to understand what that approach produced.

Specifically, maintaining a vibe-coded codebase requires the ability to answer questions the code does not answer for itself: What is the canonical implementation of this pattern? Where does this workflow actually start? What will break if we modify this? Is there already an implementation of what we are about to build?

What semantic indexing surfaces in a vibe-coded codebase
What semantic indexing surfaces in a vibe-coded codebase:
  -> which implementation of "retry" is the canonical one (vs the two duplicates)
  -> where the payment flow actually starts and ends, across all services
  -> what the three versions of the user model represent and where each is used
  -> which database tables have grown beyond their original purpose
  -> what workflows are triggered by an event the AI just proposed to modify
  -> where the same concept has been named differently across the codebase

These are not questions that can be answered by reading the code carefully, at least not within the time budget of a sprint. They require a layer above the code that has already done the structural analysis, identified the canonical implementations, mapped the dependencies, and reconstructed the logical workflows from the fragmented files.

Grounded context prevents the debt from accumulating in the first place

There is a forward-looking version of this problem that matters as much as the retrospective one. The reason AI-first codebases accumulate duplicate implementations and inconsistent patterns is that each session starts without knowledge of what the previous sessions built. The model does not know about the NotificationOrchestrator that already exists, so it builds a new one.

A semantic codebase layer changes this before the duplication happens. When the AI coding tool has access to an indexed, current understanding of what already exists in the system, it can find the canonical implementation before generating a new one. The question "does this already exist?" gets answered before the duplicate is written, not after it has been shipped and is being discovered during a debugging session three months later.

How grounded context changes the duplication pattern
Without semantic context:
  "Add a notification when a subscription renews."
  → AI builds a new notification path from scratch
  → ignores the existing NotificationOrchestrator
  → creates a fourth implementation of the notification pattern

With semantic context:
  "Add a notification when a subscription renews."
  → AI finds NotificationOrchestrator immediately
  → extends the existing implementation correctly
  → the codebase gets one implementation, not four

This is the structural fix for vibe coding technical debt. Not fewer AI sessions, not more human review — better context delivery to each session, so the AI builds on what already exists rather than alongside it.

For teams past the 90-day mark already

If your team is already in the maintenance wall, the semantic index is also the fastest way to get out of it. Rather than spending sprint capacity on human code archaeology — reading through the AI-generated codebase, documenting what it does, tracing dependencies manually — an indexed semantic layer does that analysis automatically. The canonical implementations surface. The workflows become traceable. The cross-service dependencies become visible.

That indexed understanding then becomes the context that future AI sessions operate from. New features start from an accurate picture of the existing system rather than from scratch. Debt stops compounding. Velocity recovers — and this time it recovers with a foundation that does not need to be re-learned every time a new engineer joins the team or a new feature touches an unfamiliar part of the system.

Final take

Vibe coding is not a mistake. It is a genuinely new development modality that delivers real velocity for teams willing to adopt it. The 90-day reckoning is not inevitable — it is the consequence of treating AI-generated code as something that explains itself, when it does not.

Every codebase needs a way to answer "what does this system actually do?" Vibe-coded codebases need it more urgently, not less — because nobody fully wrote them and nobody has accumulated the architectural intuition that traditional codebases build up over time. Semantic codebase intelligence is not optional for AI-first development. It is the infrastructure that makes AI-first development maintainable at scale.