Why Git struggles with large files
Git stores complete object snapshots. When you commit a 100 MB binary, the entire 100 MB is added to the repo. Edit it ten times and your .git directory has a gigabyte of binary content that diff and pack badly. Clones become slow, GitHub rejects pushes over its 100 MB limit, and CI grinds to a halt.
What LFS does
Git Large File Storage (LFS) replaces large files in your working tree with small text pointer files. The actual content lives on a separate LFS server, fetched on demand. Your repository stays small; large files version normally to the user.
Installing
# macOS / Homebrew
brew install git-lfs
# Debian / Ubuntu
sudo apt install git-lfs
# One-time per user
git lfs install
Tracking files
git lfs track "*.psd"
git lfs track "*.mp4"
git lfs track "assets/raw/**"
git add .gitattributes
git commit -m "Track binaries with LFS"
git lfs track writes patterns to .gitattributes. Commit that file - it tells every collaborator's Git to use LFS for matching paths.
Verifying tracking
git lfs ls-files
git lfs status
Migrating existing files
If you already committed large files, rewrite history:
git lfs migrate import --include="*.psd,*.mp4" --everything
This rewrites every commit so matching files become LFS pointers. Force-push afterwards; coordinate with the team because SHAs change.
Quotas and pricing
LFS storage and bandwidth are billed by most hosts. GitHub gives 1 GB storage and 1 GB monthly bandwidth free; pay-as-you-go beyond. Self-hosting LFS (e.g. with Gitea, GitLab, or a generic LFS server) sidesteps quotas at the cost of running infrastructure.
Cloning with LFS
git clone https://git.example.com/repo.git
# LFS files download automatically if git lfs is installed
git lfs pull
# Skip LFS download for fast clone:
GIT_LFS_SKIP_SMUDGE=1 git clone <url>
Common pitfalls
- Forgetting to commit
.gitattributes- other clones do not know to use LFS. - Tracking after committing - the file is still large in history. Use
migrate. - LFS objects are not in
.git/objects; they live in.git/lfs. git lfs pruneremoves old local LFS files; the remote keeps them.
When LFS is the right answer
LFS shines when binaries are essential to the project - design files, audio, datasets, signed artefacts. It is overkill for occasional large files (use S3 or similar). It is the wrong tool for source code, no matter how large.