Handling Large Binary Files with LFS
In a hurry? Watch our brief 1-minute vertical video that summarizes the info below.
Large binary files are a tough problem for version control systems — including Git. The reason is that Git is optimized for text files: when a text file changes, delta compression produces a tiny diff because only a few bytes changed. Binary files (images, PSD files, videos, audio, compiled artifacts) compress much less efficiently — a small semantic edit (like saving a PSD) rewrites bytes throughout the file, resulting in a delta almost as large as the full file:
Text file change: → tiny delta (a few bytes)
Binary file change: → near-full copy (still ~50 MB)
After 10 edits to a 50 MB PSD file, your repository holds ~500 MB of binary data — even if each edit was a minor tweak.
Git LFS (Large File Storage) solves this by replacing large binary files with a tiny pointer in your repository, while the actual file content is stored separately in a dedicated LFS store:
Git repository LFS store (remote)
┌───────────────┐ ┌──────────────────────────────┐
│ pointer (1 KB)│ ─────▶ │ design.psd v1 (50 MB) │
└───────────────┘ │ design.psd v2 (50 MB) │
│ design.psd v3 (50 MB) │
└──────────────────────────────┘
Your Git repository stays small. At checkout time, LFS fetches only the version you actually need.
Tracking Files with LFS
After installing LFS on your local computer once, you'll be able to "track" files (or file patterns) via LFS.
As a result, these files will not be stored in your local repository, but in a dedicated LFS cache (locally) and store (remotely). In the end, you'll have smaller local Git repositories because LFS manages data storage very efficiently - saving only the data you need on your local computer.
To tell LFS to handle a certain file, use the "track" command:
$ git lfs track "assets/design.psd"
Of course, you can also have LFS manage all files of a certain type:
$ git lfs track "*.psd"
Pattern Reference
| What to track | Command |
|---|---|
| A specific file | git lfs track "assets/design.psd" |
| All files of a type | git lfs track "*.psd" |
| Multiple types at once | git lfs track "*.psd" "*.ai" "*.sketch" |
| All files in a folder | git lfs track "assets/**" |
Always quote your patterns — without quotes, your shell expands wildcards before Git LFS sees them, creating individual file entries instead of a reusable pattern.
To list all currently tracked patterns, run git lfs track with no arguments. To stop tracking a pattern:
$ git lfs untrack "*.psd"
The .gitattributes File
After executing the "track" command, you'll notice that a file named ".gitattributes" (located in the root of your repository) was changed. This is because LFS notes the files and file patterns you want to track in exactly this ".gitattributes" file.

Each tracked pattern appears in .gitattributes as a single line — for example:
*.psd filter=lfs diff=lfs merge=lfs -text
filter=lfs— LFS handles converting the file to/from a pointer on commit and checkoutdiff=lfs— LFS handles diffsmerge=lfs— LFS handles merges-text— disables line-ending conversion (binary content must not be modified)
You can edit .gitattributes manually instead of using git lfs track — the result is identical.
Just like with the ".gitignore" file that you might already know (and if you do, you'll like this tool), you should keep in mind that changes in ".gitattributes" should be staged and committed to the repository like any other change, too.
Where Does Git LFS Store Your Files?
Git LFS uses a two-tier storage model:
Your machine Remote server
┌──────────────────────┐ ┌──────────────────────────────┐
│ .git/lfs/objects/ │ ◀───▶ │ LFS store (GitHub, GitLab, │
│ (local cache) │ │ Bitbucket, or self-hosted) │
└──────────────────────┘ └──────────────────────────────┘
- On
git add: LFS caches the file locally and writes a tiny pointer into Git. - On
git push: cached LFS objects are uploaded to the remote store. - On
git checkout: LFS checks your local cache first, downloading from the remote only if needed.
To free up local disk space by removing cached versions you no longer need:
$ git lfs prune
Limitations to Keep in Mind
Git LFS is the right tool for large individual binary files (images, video, compiled binaries). A few things to consider before adopting it:
- LFS must be installed on every developer's machine before they can work with the actual file content. Cloning without LFS installed technically succeeds, but Git replaces each tracked file with its small pointer file — so the files will appear in your working directory but be unusable.
- Hosted platforms (GitHub, GitLab, Bitbucket) include limited LFS storage and bandwidth; heavy use may require a paid plan.
- If your problem is a repository bloated with many small tracked files rather than a few large ones, LFS won't help. To stop tracking files going forward, use
.gitignore; to scrub them from history entirely, usegit filter-repo.
Tip
Working with LFS in Tower
In case you are using the Tower Git client, you can work with Git LFS very easily: simply right-click a file in the _Working Copy_ view and choose from the various options in the "LFS" submenu.

Learn More
- Check out the chapter Handling Large Files with LFS in our free online book
Get our popular Git Cheat Sheet for free!
You'll find the most important commands on the front and helpful best practice tips on the back. Over 100,000 developers have downloaded it to make Git a little bit easier.
About Us
As the makers of Tower, the best Git client for Mac and Windows, we help over 100,000 users in companies like Apple, Google, Amazon, Twitter, and Ebay get the most out of Git.
Just like with Tower, our mission with this platform is to help people become better professionals.
That's why we provide our guides, videos, and cheat sheets (about version control with Git and lots of other topics) for free.