Context Windows, Memory, and Why Your AI Keeps "Forgetting" the Project

Discover why your AI loses track of your project mid-session and how context windows, memory files, and smart prompting keep conversations on track.

Author:
Codapress Publishing
Date:

You are ten messages deep into a vibe coding session. The first few responses were spot on — the model understood your stack, your folder structure, and your design preferences. Then something shifted. It started reusing old patterns, suggesting changes you already rejected, or generating code that ignored a constraint you set in message three. It looks like the AI “forgot”. It did not. It ran out of context.

What is a context window, really?

A context window is the amount of text a language model can “see” at once — measured in tokens, where one token is roughly 0.75 words of English. Every model has a fixed maximum, and everything in the conversation counts toward it: your initial prompt, every file the model reads, every response it generates, every error message you paste in.

ModelContext windowApproximate words
Claude 3.5 Sonnet200K tokens~150,000
GPT-4o128K tokens~96,000
Gemini 2.0 Flash1M tokens~750,000
DeepSeek-V3128K tokens~96,000

Those numbers sound generous until you do the arithmetic. A single 2,000-line source file can consume 60,000 tokens — nearly half of GPT-4o’s entire window before you have written a single instruction. The model still responds, but it has less room to hold your requirements, earlier decisions, and the constraints you established in the first few messages.

Why the AI “forgets”

Models do not have memory in the human sense. Each response is generated from the entire context window at that moment — the model re-reads everything from scratch every time you send a message. Nothing carries over between sessions. Nothing is “learned” across conversations.

The forgetting happens for three reasons:

  1. The sliding window. When the conversation exceeds the context limit, the oldest messages are dropped. Some providers summarise them; most simply truncate. The brief where you specified your stack, constraints, and architecture decisions? Gone.
  2. The attention bottleneck. Even within the window, models pay more attention to tokens near the start and end of the input. Research on the lost-in-the-middle phenomenon shows that information placed in the middle of a long context is significantly more likely to be missed. The constraint you set in message seven sits right in the blind spot.
  3. Token pressure. Long files compete with instructions for space in the same budget. Every line of a 500-line configuration file is a line that could have been a reminder about your architectural decisions or business rules.

How context limits show up in practice

The symptoms are predictable once you know what to look for.

SymptomWhat is happeningWhat to do
Suggests code you already rejectedThe earlier rejection scrolled out of contextRestate key decisions in each major request
Forgets your stack or frameworkThe setup brief was truncatedOpen every session with a short project summary
Reuses patterns from unrelated parts of the conversationRecent messages skew the model’s attentionMake your latest message the best-written brief
Generates code that breaks integrationIt lost sight of the full project structurePaste only the files relevant to the current task
Responses get shorter or more genericThe model is compressing to fit the remaining windowStart a new session with accumulated knowledge

Strategy one: be surgical with context

The single most effective technique is also the simplest: do not paste your entire project into the prompt. Select only the files that are relevant to the current task.

We are building a React dashboard with a Flask backend. I need to add
a real-time notifications endpoint. Here is the relevant context:

Backend route file: routes/notifications.py
Frontend component: components/NotificationBell.tsx
The existing API response format (from our health check endpoint):
  GET /api/health -> { "status": "ok", "uptime": 12345 }

Requirements:
- Add a GET /api/notifications endpoint returning unread notifications
  from PostgreSQL
- The NotificationBell component should poll this endpoint every 30
  seconds
- Show a red badge with the unread count on the bell icon
- Handle loading and error states in the component

Do not touch any other files. Follow the patterns used in the health
check endpoint.

This prompt restates the stack and architecture so it survives a fresh session, includes only the files that need changing, and defines scope precisely. The model knows exactly what to produce and what to leave alone.

Strategy two: use project-level memory

Every major AI coding tool supports some form of persistent instructions. Treat these as your project’s long-term memory.

  • Cursor.cursorrules in the project root. Write your stack, preferred patterns, and testing conventions once. The model reads them at the start of every session.
  • Claude CodeCLAUDE.md or architectural notes in a docs/ folder.
  • GitHub Copilot.github/copilot-instructions.md with repository-level guidelines.
  • ChatGPT and similar — A local notes file with a project brief you paste into every new conversation.

A good memory file covers what does not change:

SectionExample
StackReact 18, Vite, Tailwind CSS, Express 4, PostgreSQL
ConventionsDefault exports for components, named exports for utilities
Architecture/components/ for UI, /pages/ for routes, /lib/ for shared logic
TestingVitest for unit tests, Playwright for E2E
DeploymentFly.io for backend, Vercel for frontend

For a deeper walkthrough of setting up Cursor rules and project memory files, see Cursor Pro. It covers everything from rule syntax to multi-project configurations.

Strategy three: start fresh — deliberately

Long conversations have diminishing returns. When the model starts repeating itself or ignoring earlier decisions, do not fight it — start a new session with a clear reset prompt.

This is a fresh session. I am continuing a project with:

Stack: React 18, Vite, Tailwind CSS, Express 4, PostgreSQL
Architecture: Frontend in /client, backend in /server
Key decisions already made:
- Auth via Supabase with magic links
- All API responses follow { data, error } format
- Components use default exports
- Using Vitest for tests

The current task is to add a file upload feature to the profile page.
Relevant files: components/ProfilePage.tsx, lib/upload.ts,
server/routes/profile.js

Please review the files I am about to paste and propose an
implementation plan before writing code.

This approach costs a minute of typing and saves ten minutes of correction. The model starts with a complete, accurate picture rather than reconstructing it from fragments that survived in a long conversation’s shrinking context window.

The truth about AI “memory”

Context windows are short-term buffers, not persistent memory. Every message you send will eventually scroll out of view. Plan for that. Restate decisions that matter. Trim files to only what is relevant. Use project-level instructions for the things that should never be forgotten.

The difference between a vibe coding session that ships and one that spirals into fifty messages is not the model’s capability — it is how well you manage its attention. Treat the context window as a scarce resource, and you will get better results without switching tools or changing models.

For a complete system of session templates, project memory setups, and debugging workflows for long-running AI conversations, see Vibe Coding Pro.

More insights

All Articles