Step 1 of 7

Introduction to Copilot Memory

5 minutes

GitHub Copilot's memory system lets you store preferences, project context, and in-progress work so that Copilot stays consistent and context-aware — across different conversations and across your entire team.

Why Memory Matters

By default, every Copilot Chat conversation starts fresh. There is no recollection of your preferred coding style, the framework your project uses, or the task you were working on yesterday. This statelessness is fine for quick one-off questions, but it becomes a friction point in longer-running workflows:

  • You re-explain your tech stack at the start of every chat
  • Copilot suggests patterns that conflict with your team's conventions
  • Context from a long earlier conversation is lost when you close VS Code
  • New team members get different suggestions than experienced ones

Copilot Memory solves this by giving you markdown files that Copilot reads automatically. You write your preferences and context once; Copilot applies them every time.

How Memory Works

Copilot memory is stored in plain markdown (.md) files. Copilot reads these files at the start of each chat and uses their contents as additional context. Because the files are plain text, you can edit them directly, commit them to version control, and share them with your team.

Memory files are just Markdown

There is no special syntax or schema to learn. Copilot reads the files as natural language context. Use headings, bullet lists, and code blocks to organise information in whatever way makes sense for your team.

Learning Objectives

By the end of this workshop activity you will be able to:

  • Explain the three memory scopes and when to use each one
  • Create and update user memory to persist personal coding preferences
  • Use session memory to track multi-step tasks within a single conversation
  • Create repository memory that captures project conventions shared across a team
  • Design a memory strategy that keeps files concise and actionable

Prerequisites

Before you begin, make sure you have:
  • Visual Studio Code — version 1.90 or later. Download from code.visualstudio.com
  • GitHub Copilot Chat extension — installed and signed in with a Copilot-enabled account
  • Copilot memory enabled — open VS Code Settings (Ctrl+, / Cmd+,), search for Copilot: Memory, and ensure the setting is turned on
  • A local workspace folder open in VS Code — any existing project or an empty folder works

To verify that memory is active, open Copilot Chat and type:

What do you know about my coding preferences?

If memory is enabled but no memory files exist yet, Copilot will say it has no stored preferences — that is the expected starting state.

Step 2 of 7

Exercise 1: Explore the Three Memory Scopes

10 minutes

Copilot memory is organised into three scopes, each serving a different purpose and persisting for a different length of time.

The Three Memory Scopes

Memory file locations
  • User scope~/.vscode/copilot/memories/ (macOS/Linux) or %APPDATA%\Code\User\copilot\memories\ (Windows). Applies to all your VS Code sessions across all projects.
  • Session scope.github/copilot/memories/session/ inside your workspace. Intended to track in-progress work within the current task.
  • Repository scope.github/copilot/memories/ inside your workspace. Committed to version control and shared with the whole team.

Scope Comparison

Scope Location Applies to Shared?
User ~/…/memories/ All projects, all sessions No — personal only
Session .github/copilot/memories/session/ Current task in progress Optional (add to .gitignore)
Repository .github/copilot/memories/ Entire codebase, all contributors Yes — committed to git

Exercise: Inspect the Memory Directories

  1. Open a terminal in VS Code (Terminal → New Terminal).
  2. Check whether any user-scope memory files already exist:
    # macOS / Linux
    ls ~/.vscode/copilot/memories/ 2>/dev/null || echo "No user memory files yet"
    
    # Windows (PowerShell)
    Get-ChildItem "$env:APPDATA\Code\User\copilot\memories" -ErrorAction SilentlyContinue
  3. Check whether repository-scope directories exist in your current workspace:
    ls .github/copilot/memories/ 2>/dev/null || echo "No repository memory files yet"
  4. In Copilot Chat, ask:
    What memory files do you currently have access to?
    Observe which files Copilot lists. If no files exist yet, that is expected — you will create them in the next exercises.
Tip: Ask Copilot to help manage memory

You can ask Copilot to create or update memory files on your behalf. For example: "Please save this preference to my user memory". Copilot will write or update the appropriate file for you.

Step 3 of 7

Exercise 2: Save a Coding Preference to User Memory

15 minutes

User memory stores your personal preferences — coding style, language choices, documentation habits — and applies them across every project you work on. Changes you make here influence every future Copilot Chat response in every workspace.

Part A: Create Your User Memory File

Create a new markdown file at the user-scope location:

# macOS / Linux
mkdir -p ~/.vscode/copilot/memories
code ~/.vscode/copilot/memories/preferences.md

# Windows (PowerShell)
New-Item -ItemType Directory -Force "$env:APPDATA\Code\User\copilot\memories"
code "$env:APPDATA\Code\User\copilot\memories\preferences.md"

Add a few concrete preferences. Here is a starter template — customise it to match your real preferences:

# My Copilot Preferences

## Coding Style
- I prefer TypeScript over JavaScript for all new projects
- Use `const` and `let` instead of `var`
- Always add explicit return types to functions
- Use 2-space indentation

## Testing Preferences
- Use Jest as the test framework
- Follow the AAA pattern: Arrange, Act, Assert
- Write tests in `__tests__` directories alongside source files

## Communication Style
- Explain the "why" behind suggestions, not just the "what"
- Keep responses concise — use bullet points for lists of steps
- If multiple approaches exist, briefly compare the trade-offs

Save the file.

Part B: Verify the Preference Takes Effect

  1. Open a new Copilot Chat conversation (Ctrl+Shift+I / Cmd+Shift+I).
  2. Without mentioning TypeScript, ask Copilot to generate a simple utility function:
    Write a function that takes an array of numbers and returns the sum.
  3. Observe whether Copilot uses TypeScript with explicit return types, matching your saved preference.
  4. Now ask:
    What do you know about my coding style preferences?
    Copilot should describe the preferences you saved in the memory file.
Reflection questions
  • Did Copilot apply your language preference without being asked explicitly?
  • Were there any preferences Copilot ignored or interpreted differently than you expected?
  • Which preferences had the biggest impact on the quality of the suggestion?

Part C: Update a Preference

Memory files are just text — edit them at any time. Try changing one preference:

  1. Open your preferences.md file and add a new section:
    ## Error Handling
    - Always use explicit error handling — never swallow exceptions silently
    - Prefer returning `Result` types over throwing exceptions in library code
    - Log errors with enough context to reproduce the problem
  2. Save the file, then open a new chat and ask:
    Write a function that reads a file and returns its contents as a string.
  3. Verify that Copilot includes explicit error handling in the generated code.

Sample User Memory File

A complete example is available in the workshop repository:

View sample user-preferences.md
Step 4 of 7

Exercise 3: Track a Multi-Step Task with Session Memory

20 minutes

Session memory is designed for tasks that span multiple prompts. Instead of re-explaining your progress at the start of every chat turn, you write a session file that Copilot reads automatically and keeps its context anchored to where you left off.

Why Session Memory?

Complex development tasks — refactoring a service, implementing a feature end-to-end, debugging a tricky issue — often require many back-and-forth exchanges with Copilot. Without session memory you have to:

  • Paste the same background context at the start of every new chat
  • Remember which decisions were already made and re-explain them
  • Risk losing the thread of a long investigation when you close VS Code

A session file acts as a living checklist and decision log that both you and Copilot can read and update throughout the task.

Part A: Set Up a Session File

  1. Create the session memory directory in your workspace:
    mkdir -p .github/copilot/memories/session
  2. Create a new session file for a realistic task — for example, refactoring a service to use the repository pattern:
    code .github/copilot/memories/session/current-task.md
  3. Paste in the following starter template and fill in the details for your actual task:
    # Session Context: [Your Task Name]
    
    ## Current Task
    [One or two sentences describing what you are trying to accomplish.]
    
    ## Progress So Far
    - [x] Completed step
    - [ ] Next step
    - [ ] Future step
    
    ## Key Decisions Made
    - [Decision 1 and the reasoning behind it]
    - [Decision 2 and the reasoning behind it]
    
    ## Files Modified
    - `path/to/file.ts` — brief description of change
    
    ## Files Still To Update
    - `path/to/other-file.ts` — brief description of planned change
    
    ## Notes
    - Any important constraints, gotchas, or context Copilot needs to know
  4. Save the file.

Part B: Use the Session File Across Multiple Prompts

Work through a realistic multi-step task using the session file as a shared scratchpad:

  1. Open Copilot Chat and start with:
    Read my session memory file and summarise where I am in my current task.
    Verify that Copilot accurately describes your current progress.
  2. Ask Copilot to help with the next step:
    Help me implement the next step in my current task.
  3. After completing a step, ask Copilot to update the session file:
    Update my session memory to mark "[step name]" as complete and add any key decisions we made.
  4. Close the chat, open a brand-new conversation, and ask:
    What was I working on? What are the remaining steps?
    Copilot should be able to resume from the updated session file without you re-explaining anything.
Tip: Keep session files out of version control

Session files track your personal in-progress state and are typically not useful to other contributors. Add the session directory to .gitignore to avoid committing them:

.github/copilot/memories/session/

Sample Session File

A worked example is available in the workshop repository:

View sample session/current-task.md
Step 5 of 7

Exercise 4: Create Repository Memory for Project Conventions

20 minutes

Repository memory is committed to version control and shared with everyone who works on the project. It gives Copilot a consistent understanding of your codebase — naming conventions, technology stack, build commands, and team norms — so every contributor gets context-aware suggestions from day one.

What to Capture in Repository Memory

  • Technology stack — language versions, frameworks, libraries the team has standardised on
  • Naming conventions — file names, class names, variable names, database tables, API routes
  • Project structure — where different types of code live (controllers, services, models, tests)
  • Build and test commands — how to build, run, lint, and test the project locally
  • Coding standards — patterns the team follows (e.g., always use the Result pattern for errors)
  • Git conventions — branch naming, commit message format, PR review requirements

Part A: Create the Repository Memory File

  1. Create the repository memory directory:
    mkdir -p .github/copilot/memories
  2. Create a conventions file:
    code .github/copilot/memories/conventions.md
  3. Document your project's conventions. Here is a template to get you started:
    # Repository Conventions
    
    ## Project Overview
    [One paragraph describing the project and its purpose.]
    
    ## Technology Stack
    - **Runtime**: [e.g., Node.js 20 LTS]
    - **Language**: [e.g., TypeScript 5.x with strict mode]
    - **Framework**: [e.g., Express 4]
    - **Database**: [e.g., PostgreSQL 16 with `pg` driver]
    - **Testing**: [e.g., Jest + React Testing Library]
    - **Linting**: [e.g., ESLint with @typescript-eslint]
    
    ## Naming Conventions
    - **Files**: `kebab-case.ts`
    - **Classes**: `PascalCase`
    - **Functions and variables**: `camelCase`
    - **Constants**: `SCREAMING_SNAKE_CASE`
    - **Database tables**: `snake_case`
    - **API routes**: `kebab-case` (e.g., `/api/user-profile`)
    
    ## Project Structure
    [Describe the directory layout and what each folder contains.]
    
    ## Build Commands
    \`\`\`bash
    npm run build   # compile TypeScript
    npm run dev     # start with hot-reload
    npm test        # run all tests
    npm run lint    # lint all files
    \`\`\`
    
    ## Coding Standards
    - [Standard 1]
    - [Standard 2]
    
    ## Git Conventions
    - Branch naming: `feature/`, `fix/`, `chore/`
    - Commit messages: imperative mood, present tense
    - PRs require one approval and passing CI
  4. Fill in the template with your project's actual details, then save the file.

Part B: Verify Repository Memory Is Applied

  1. Open Copilot Chat and ask:
    What are the naming conventions for this project?
    Copilot should describe the conventions you just documented.
  2. Ask Copilot to generate a new file using the project conventions:
    Create a new service class for managing user notifications, following our project conventions.
    Check whether the generated file name, class name, and structure match your documented conventions.
  3. Ask about build commands:
    How do I run the tests for this project?
    Copilot should answer using the commands from your conventions file.

Part C: Commit the Memory File

Repository memory is only useful when it is committed to version control:

git add .github/copilot/memories/conventions.md
git commit -m "Add Copilot repository memory with project conventions"
git push

Once merged, every contributor who opens this repository will have Copilot automatically reading the conventions file — no manual setup required.

Sample Repository Memory File

A complete example is available in the workshop repository:

View sample repo/conventions.md
Step 6 of 7

Challenge: Design Your Personal Memory Schema

20 minutes

Now that you have worked with all three memory scopes, design a memory strategy tailored to your day-to-day development workflow. The goal is a schema that is practical, maintainable, and genuinely improves the quality of Copilot's suggestions over time.

Challenge Brief

Design a complete memory schema — a set of memory files across the appropriate scopes — for one of the following scenarios (or your own real project):

Choose a scenario
  • Scenario A — Solo developer: You work across several personal projects in different languages. Design a user memory schema that applies useful defaults everywhere while letting each project override them.
  • Scenario B — Team project: You are a tech lead on a team of five engineers. Design a repository memory schema that onboards new contributors and keeps Copilot consistent across the team.
  • Scenario C — Long-running migration: You are migrating a large codebase from REST to GraphQL. Design a session memory schema that tracks migration progress across weeks of work.

Your Design Should Answer

  1. What files will you create? — List each file and which scope it belongs to.
  2. What content goes in each file? — Write the actual content, not just a description of it.
  3. How will you keep the files up to date? — What is your process for updating memory as the project evolves?
  4. What will you deliberately leave out? — Identify one or two things that might be tempting to add but would make the files too long or too noisy.

Implementation Steps

  1. Draft the memory files for your chosen scenario. Create the actual files in the right locations — do not just plan them.
  2. Open Copilot Chat and ask it a question that the memory should answer without prompting:
    What testing framework should I use for a new module in this project?
  3. If the answer is wrong or incomplete, refine the memory file and try again.
  4. Share your schema with a peer and ask them to review it. Would it help them get productive on the project quickly?

Reflection

After completing the challenge, consider:

  • Which scope did you use most? Was that what you expected?
  • What was the hardest information to capture clearly in a memory file?
  • How would you introduce memory files to your team without adding maintenance overhead?
Step 7 of 7

Best Practices

10 minutes

Memory files are most valuable when they are concise, accurate, and actively maintained. The following guidelines will help you get the most out of the memory system without creating a maintenance burden.

What to Store

  • Stable preferences and conventions — things that change infrequently and apply broadly (e.g., "we use camelCase for function names")
  • Non-obvious decisions — choices that a reasonable developer might not make by default (e.g., "we prefer returning Result types over throwing exceptions")
  • Build and test commands — reduces the need to look up or re-explain how to run the project
  • Technology constraints — libraries or patterns the team has agreed to use or avoid (e.g., "do not add new ORM dependencies")
  • In-progress task state — completed steps, key decisions, and remaining work for multi-day tasks (session scope)

What Not to Store

  • Large amounts of code — memory files are for context, not for pasting entire implementations. Use #file references in Copilot Chat to include specific code
  • Frequently changing details — version numbers, API responses, configuration values that change often will go stale quickly and confuse Copilot
  • Sensitive information — never store credentials, API keys, tokens, or private data in memory files (they may be committed to version control)
  • Redundant information — if something is already captured well in a README.md or .github/copilot-instructions.md, do not duplicate it in a memory file
  • Everything you know about a topic — the goal is to provide decision-making context, not to reproduce your entire knowledge base

Keeping Memory Files Concise

  • Use bullet points — short, declarative statements are easier for Copilot to act on than paragraphs of prose
  • One topic per file — split large files into focused files (e.g., coding-style.md, testing.md, git-conventions.md) rather than one monolithic document
  • Review quarterly — schedule a regular review to remove outdated preferences and update anything that has changed
  • Start small — add preferences gradually as you notice Copilot making suggestions that do not match your style, rather than writing an exhaustive document upfront

Memory vs. Copilot Instructions

VS Code also supports a .github/copilot-instructions.md file that provides persistent instructions for Copilot across a workspace. Here is how to decide which to use:

Feature Copilot Instructions Memory Files
Location .github/copilot-instructions.md Multiple files across scopes
Best for Immutable rules and constraints Evolving context and preferences
Personal preferences No (applies to whole repo) Yes (user scope)
In-progress task state No Yes (session scope)

Use both together: copilot-instructions.md for team-wide rules, and memory files for personal preferences and evolving project context.

🎉 Congratulations!

You have completed the Copilot Memory workshop activity! You can now:

  • Explain the three memory scopes (user, session, repository) and when to use each
  • Create and update user memory to persist personal coding preferences across all projects
  • Use session memory files to track multi-step tasks without re-explaining context
  • Design repository memory that keeps Copilot consistent across an entire team
  • Apply best practices to keep memory files concise, accurate, and maintainable

Additional Resources

Next Steps

Continue your Path 3 journey or revisit earlier topics: