Ch. 16 · Git & CI/CD

Git LFS for Large Files

Track large binaries with Git LFS, keep pointer files in the repository, and plan for LFS storage and access.

~2 min readadvancedupdated Oct 5, 2026

Git stores every version of every file, so large binaries bloat the repository and slow every operation for everyone. Git LFS replaces tracked files with small pointer files and stores the actual content on a separate server, so the repository stays small.

Before you start

You should understand how Git stores objects. This article covers LFS tracking and its operational cost.

Step-by-step walkthrough

Step 1: Track large file patterns

git lfs track "*.psd" records the pattern in .gitattributes, so matching files are handled by LFS. The pattern must be committed before the files are added, or they go into the repository as normal blobs and remain there.

Step 2: The repo holds pointers, LFS holds content

After tracking, the file in the repository is a short pointer with a hash and size, and the content is fetched from the LFS server on checkout. Clones are small, but a checkout still downloads the real files, so the total data transferred is similar.

Step 3: Plan for storage, access and history

LFS content lives outside the normal history, so it needs its own storage and access controls, and older versions still count against the store. Existing large files already in history are not retroactively moved to LFS; migrating them requires rewriting history, which is disruptive.

Worked scenario

The pattern routes the file to LFS before it is added.

git lfs install
git lfs track "*.mp4"
git add .gitattributes
git add video.mp4      # stored as a pointer, content on the LFS server
git commit -m "Add demo video"
Terminal

Walk through the example

git lfs track writes the .gitattributes entry, so video.mp4 is committed as a pointer and its bytes go to the LFS server. A teammate clones the repo quickly, then fetches the video content when checking out. Committing the pattern first is what makes the routing apply.

Common mistake

Adding a large file before tracking it, so it lives in Git history and bloats the repo despite LFS being enabled later. Another is ignoring LFS storage quotas and access rules, so checkouts fail for teammates or CI.

Verify the behavior

Track a pattern, add a file, and confirm the committed object is a small pointer with git cat-file. Clone with and without LFS and compare sizes. Confirm checkout fetches the content and that an untracked large file is not stored as a pointer.

Interview exercise

Does Git LFS reduce the total data a full checkout transfers?

Answer and reasoning

Not necessarily. It shrinks the repository clone because the history holds pointers instead of blobs, but checking out the working files still downloads their content from the LFS server. The benefit is a small, fast repository and versioned large files, while the checkout cost remains roughly the size of the current files.

Continue learning

Compare repository hygiene in Image maintenance and history in Ignore tracked files. Read the Git LFS documentation and try the Git interview questions.

More in Git & CI/CD

read ✓Git & CI/CD · easy

Git Detached HEAD

What a detached HEAD is, when it happens, and how to keep commits made in that state.

~2 min readread →
read ✓Git & CI/CD · mid

Git Hooks and Local Automation

Automate checks with client and server hooks, share them through a framework, and enforce the same rules in CI where they cannot be bypassed.

~2 min readread →
read ✓Git & CI/CD · hard

Git Partial and Shallow Clones

Fetch less history and content with shallow and partial clones, and understand what you give up.

~2 min readread →
esc