AlgoInsight

Free lesson · Git Mastery

Maintenance Overview

Hard6 min readgit

Maintenance Overview

A note from Deepika Nair, Staff Software Engineer at Meta AI Infrastructure.

The Operations That Keep Repositories Fast

Git repositories accumulate state. Loose objects, pack files, reflogs, working tree caches. Without maintenance, the accumulation degrades performance - operations that should be instant become slow, clones take longer, disk usage grows beyond what's necessary. Maintenance is the set of operations that periodically clean up and reorganize the state to keep things fast.

For typical small repositories, maintenance happens invisibly. Auto-gc runs occasionally; loose objects get packed; reflogs expire. The user never notices. For large repositories - monorepos, AI artifact repositories, anything that grows to substantial size - maintenance becomes a deliberate engineering activity. Performance regressions can be costly; proper maintenance is what prevents them.

At Meta, I work with repositories that span many gigabytes and have millions of objects. Maintenance for these is part of operations - scheduled, monitored, and tuned. The lessons transfer to smaller repositories too; understanding what maintenance does helps you keep any repository performant.

What Maintenance Operations Do

The core maintenance operations:

Garbage collection (git gc). Topic 14.7 covered this in depth. Removes unreachable objects, packs loose objects, prunes stale refs.

Packing (git repack). Consolidates loose objects into pack files. Recompresses existing packs with better delta selection.

Commit-graph generation. Builds a cache file that speeds up history traversal operations. Without it, walking commits requires reading each commit object individually; with it, the cache provides commit metadata for the entire history.

Loose object pruning. Removes loose objects that have been packed (or that are unreachable past the grace period).

Reflog expiration. Removes old reflog entries past their retention window.

Pack file optimization. Larger, fewer pack files perform better than many small ones for most operations.

Each operation handles a different aspect of repository state. Garbage collection is the broadest. Packing affects storage efficiency. Commit-graph affects log and history performance. Reflog expiration affects how much recovery history is kept. Together they keep repositories in good shape.

When Maintenance Matters

For small repositories (under 1 GB, under 10,000 commits), maintenance rarely matters in practice. Auto-gc handles things adequately. You can ignore maintenance unless you notice performance issues.

For medium repositories (1 GB to 10 GB, 10,000 to 100,000 commits), maintenance starts to matter for some operations. Status and log may slow down. Pack consolidation helps.

For large repositories (10+ GB, 100,000+ commits, or monorepos with millions of files), maintenance is essential. Without it, operations that should be fast become unbearably slow. The investment in maintenance infrastructure pays back many times over.

At Meta, our largest repositories have millions of commits and tens of millions of files. Maintenance for these is sophisticated - scheduled background operations, careful pack optimization, custom commit-graph strategies. The patterns scale down to smaller repositories; understanding them at scale helps anywhere.

The Maintenance Cycle

A typical maintenance cycle for a repository:

flowchart LR
    A[Loose objects<br/>accumulate from work] --> B[Threshold reached]
    B --> C[Auto-gc or scheduled<br/>maintenance runs]
    C --> D[Repack loose objects<br/>into pack files]
    D --> E[Optimize existing<br/>pack files]
    E --> F[Update commit-graph<br/>cache]
    F --> G[Prune old refs<br/>and objects]
    G --> H[Repository in good state]
    H --> A
    
    style C fill:#dcfce7
    style H fill:#dbeafe
The cycle: work generates loose objects, maintenance packs and optimizes them, the repository returns to a clean state, work resumes generating new loose objects. The frequency depends on the repository's churn - high-churn repositories need more frequent maintenance.

The exact triggering and operations vary by Git version. Modern Git has git maintenance (Topic 16.2) which coordinates the whole cycle with scheduling.

Default Maintenance Behavior

Without explicit configuration, Git's defaults:

The defaults work for most users. They're designed to handle typical workflows without configuration. For atypical workflows - very large repositories, very high churn, very strict storage requirements - the defaults need tuning.

When Defaults Aren't Enough

Signs the defaults aren't handling your repository:

Slow git status. Often indicates many loose objects or many untracked files in .gitignore exemptions. Maintenance can help.

Slow git log. Often indicates missing commit-graph cache. Building one helps dramatically.

Slow clones. Indicates large pack files or many objects. Pack optimization and shallow clone options help.

Disk usage growing faster than expected. Indicates maintenance isn't keeping up with churn. More aggressive scheduling needed.

gc taking hours. Indicates the repository has accumulated too much without maintenance. One-time cleanup followed by regular scheduling.

For each, the response is more deliberate maintenance - scheduled operations rather than relying on auto-gc.

A Pattern at Meta AI Infrastructure

For our model artifact repositories, the pattern:

# Disable auto-gc to prevent unpredictable blocking
git config gc.auto 0

# Schedule maintenance via git maintenance (Topic 16.2)
git maintenance start

# This sets up cron/systemd timers for:
# - Hourly: fetch and incremental commit-graph
# - Daily: loose-objects packing
# - Weekly: full gc and pack file optimization
The pattern: explicit scheduling instead of automatic triggering. Auto-gc can fire at unpredictable times, which can block urgent work. Scheduled maintenance fires at known low-activity times, which is much safer for production-critical repositories.

The configuration matters. Auto-gc behavior that's fine for a developer's laptop can be disastrous for a build server processing critical jobs. Tuning maintenance to match the repository's role is part of operating it well.

Monitoring Maintenance

For repositories where maintenance matters, monitoring is part of the operation:

# Repository size
du -sh .git/

# Object counts
git count-objects -v

# Pack file inspection
ls -la .git/objects/pack/

# Status overview
git status

# What gc would do
git gc --auto --no-prune --quiet
The monitoring is straightforward - these are all standard commands. The discipline is running them periodically and noting trends. A repository growing 100 MB per week without obvious cause is signaling that maintenance isn't keeping up.

At Meta, our monitoring includes alerts on repository size, pack file count, and object count. Anomalies prompt investigation. The visibility is what makes maintenance issues catchable before they become user-facing problems.

A Specific Story From My Freshworks Days

Around 2018 at Freshworks, I was on-call for a service whose Git repository had degraded performance. Engineers reported that simple operations like git status took 30 seconds. The repository was about 8 GB; the .git/objects directory contained over 250,000 loose object files.

Investigation showed auto-gc had been disabled years earlier by a previous engineer "because it was slow," with no replacement scheduled. The repository had accumulated loose objects continuously since then.

The recovery:

# Pack the loose objects
git repack -ad

# Run garbage collection
git gc

# Verify
git count-objects -v

After running, the repository was 2 GB. Operations were fast. The team set up scheduled maintenance to prevent recurrence.

The lesson: disabling automatic maintenance without replacing it is a slow-motion failure. The cost isn't visible for months or years; then suddenly it's. The investment in proper maintenance infrastructure is small relative to the cost of emergency fixes.

A Useful Diagnostic Command

When something seems wrong with a repository's performance:

# Comprehensive repository statistics
git count-objects -v

# Output:
# count: <loose objects>
# size: <KB of loose objects>
# in-pack: <objects in packs>
# packs: <number of pack files>
# size-pack: <KB of pack files>
# prune-packable: <objects that could be pruned>
# garbage: <unreachable garbage>
# size-garbage: <KB of garbage>
The output is a complete snapshot of the repository's storage state. The numbers tell the maintenance story. Many loose objects means packing is overdue. Many pack files means consolidation is overdue. Large garbage indicates pruning is overdue. Each number suggests a different maintenance operation.

I run this regularly on repositories I work with. The numbers establish baselines; deviations from baseline prompt investigation.

What Comes Next

Topic 16.2 covers the git maintenance command in depth - modern Git's coordinated maintenance scheduling. Topics 16.3 and 16.4 cover Git LFS for large files. Topic 16.5 covers partial clone. Topic 16.6 covers sparse checkout. Topic 16.7 covers shallow clones. Topic 16.8 covers performance diagnostics.

What Goes Wrong

Warning: Common maintenance mistakes:

Disabling auto-gc without replacement. Slow-motion failure; repository bloats.

Ignoring slow operations. They're warning signs; investigate before they worsen.

Running maintenance without monitoring. Hard to know if it's working or if issues remain.

One-size-fits-all maintenance. Different repositories need different schedules.

Manual maintenance for routine cases. Schedule it; humans forget.

Aggressive cleanup without grace periods. Removes safety nets for recovery.

Try It

Exercise: Inspect your repositories:

  1. Run git count-objects -v on a repository you work with. Note the numbers.
  2. Run du -sh .git/ to see the size on disk.
  3. Check the auto-gc settings: git config --get gc.auto.
  4. Look at the most recent gc activity (timestamps on pack files).
  5. If you've never run explicit gc, try git gc and observe the time and result.
  6. For repositories where maintenance matters: consider setting up git maintenance start (covered in Topic 16.2).

Back to Git Mastery