Skip to main content

VS Code Memory Tool: Local Memory meets GitHub Copilot Memory

A few weeks ago I wrote about Copilot Memory in VS Code - the GitHub-hosted system that lets Copilot learn repository-specific insights across agents. Since then, VS Code has shipped a second, complementary memory system: the Memory tool. These two systems solve related but distinct problems, and understanding both helps you get the most out of Copilot in your daily workflow.

What is the Memory Tool?

The Memory tool is a built-in agent capability that stores notes locally on your machine. Unlike Copilot Memory, which lives on GitHub's servers and requires a GitHub repo to function, the Memory tool writes plain files to your local filesystem and reads them back at the start of each session.

You enable or disable it with the github.copilot.chat.tools.memory.enabled setting. It's on by default.


Three memory scopes

VSCode organizes memories into three scopes:

Scope Persists across sessions Persists across workspaces Good for
User Personal preferences, habits
Repository Project conventions, architecture
Session In-progress task context

User memory is the most broadly applicable. The first 200 lines load automatically into the agent's context at the start of every session, across every workspace. Ask the agent something like:

Remember that I like to use XUnit as my preferred testing framework.

...and it will apply that preference every time, regardless of which project you open.

Repository memory is scoped to the current workspace. This is the right place to capture things like "this project uses the repository pattern for data access" or "all API endpoints require authentication." That context persists across sessions in that workspace but doesn't bleed into other projects.

Session memory clears when the conversation ends. The planning agent uses this to store its plan.md file — useful for multi-step tasks within a single session, but intentionally ephemeral.

Using the memory tool in practice

Storing a memory is just natural language:

Remember that our teams use XUnit as our preferred testing framework.

Retrieving it in a new session is equally straightforward:

What testing framework is used?

The agent checks the memory files and surfaces the relevant information. References to memory files in chat responses are clickable, so you can inspect the raw content directly.

Two commands help you manage what's stored:

  • Chat: Show Memory Files — opens a list of all memory files across scopes
  • Chat: Clear All Memory Files — wipes everything

 


Memory Tool vs. Copilot Memory: side by side

This is the comparison that matters if you've already been using Copilot Memory (also see the documentation):

  Memory Tool Copilot Memory
Storage Local (your machine) GitHub-hosted
Scopes User, repository, session Repository only
Shared across Copilot surfaces No (VS Code only) Yes (coding agent, code review, CLI)
Who creates memories You or the agent during chat Copilot agents automatically
Enabled by default Yes No (opt-in)
Expiration Manual Automatic (28 days)
Requires GitHub repo No Yes

The practical split: use the Memory tool for personal preferences and anything workspace- or session-specific that you control. Use Copilot Memory for repository knowledge that should propagate across GitHub's Copilot surfaces — coding agent, code review, CLI.

Also worth remembering from my previous post: Copilot Memory currently only works when your repository is hosted on GitHub. If you're on Azure DevOps or a local-only repo, the Memory tool is your only option.

Where does this leave us?

When I wrote about Copilot Memory back in February, one of the things I hoped for was better support for non-GitHub sources. The Memory tool partially addresses that gap — it's source-agnostic and works entirely offline. But it's also more manual; you drive what gets remembered, rather than agents picking it up automatically.

The two systems aren't competing — they're designed to be complementary. What's still missing is a unified view across both, and better tooling for organizing and reviewing what's been stored over time. That's probably where the feature evolves next.

More information

Memory in VS Code agents

Enabling and curating Copilot Memory

Copilot Memory in VS Code: Your AI assistant just got smarter

Popular posts from this blog

Podman– Command execution failed with exit code 125

After updating WSL on one of the developer machines, Podman failed to work. When we took a look through Podman Desktop, we noticed that Podman had stopped running and returned the following error message: Error: Command execution failed with exit code 125 Here are the steps we tried to fix the issue: We started by running podman info to get some extra details on what could be wrong: >podman info OS: windows/amd64 provider: wsl version: 5.3.1 Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM Error: unable to connect to Podman socket: failed to connect: dial tcp 127.0.0.1:2655: connectex: No connection could be made because the target machine actively refused it. That makes sense as the podman VM was not running. Let’s check the VM: >podman machine list NAME         ...

Cache stampede: when our cache turned against us

While investigating some performance issues, we ran into an ASP.NET Core API that cached a fairly expensive aggregation query for 60 seconds. Under normal load, that was fine: one request rebuilds the cache, everyone else reads from it. Under peak load, dozens of requests would arrive in that same expiry window, all see a cache miss, and all fire the same expensive query in parallel. The database didn't like that. That was the moment when our caching layer stopped helping and started hurting. A burst of requests comes in at the same time, all miss the cache, and all go hammer the database or the downstream API at once. That's a cache stampede . The cache was supposed to protect our backend, and for a few hundred milliseconds it did the opposite. Why this happens IMemoryCache.GetOrCreate (and its async sibling) looks like it protects you, but it doesn't add any locking on its own. Look at the naive version: public async Task<Report> GetReportAsync(string key) ...

A complex system designed from scratch never works

A few years ago, I worked as an architect on a big mainframe rewrite. I still count it as one of my failures. Not because the technology was wrong, but because I couldn't convince the management team to simplify the approach. Years later, the organization is still struggling to get the new system up and running. I left the project at the time, because I couldn't put my name behind an approach that would take very long and cost a lot of money without a working system to show for it along the way. Gall’s Law That memory keeps coming back to me, because it's a textbook case of Gall's Law playing out in real life. Gall's Law , from John Gall's Systemantics , states it plainly: A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works, and it cannot be patched to make it work. You have to start over with a simple system that works. What does that mean in practice,...