# Performance Implications of Using `actions/checkout`: Optimizing GitHub Actions Speed

> Explore performance implications of actions/checkout. Learn how fetch-depth, LFS, and sparse checkout impact GitHub Actions speed and optimize your workflows for efficiency.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: performance
- Published: 2026-07-03

---

**The performance of `actions/checkout` is determined by how much data it transfers and writes to disk, with the default shallow clone (`fetch-depth: 1`) optimized for speed while options like full history, LFS, or sparse checkout allow trading speed for completeness.**

The `actions/checkout` action is the de facto standard for retrieving repository code in GitHub Actions workflows. Understanding the performance implications of using `actions/checkout` helps you optimize CI/CD pipelines by minimizing unnecessary network traffic and disk I/O. The action's behavior is controlled through several inputs defined in [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) and executed via the core logic in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts).

## Shallow Cloning with fetch-depth

By default, `actions/checkout` performs a shallow clone that fetches only the single commit triggering the workflow. In [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 174‑202), the action passes `--depth=1` to the fetch command when `fetch-depth` defaults to `1`, minimizing network traffic and disk I/O.

Setting `fetch-depth: 0` instructs the action to fetch the entire history for all branches and tags. This can add seconds to the checkout step and significantly increase storage use on the runner, making it suitable only for tools that require full Git history or semantic version calculations.

```yaml

# Fast default checkout (shallow clone)

- uses: actions/checkout@v7

# Full history for tools requiring complete Git log

- uses: actions/checkout@v7
  with:
    fetch-depth: 0

```

## Partial Clone Filtering

When a `filter` input is supplied, the action implements partial clone semantics. As implemented in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 182‑188), the action passes `--filter=blob:none` to the fetch command, performing a **partial clone** that transfers only tree objects initially.

This dramatically reduces data transfer for large repositories containing substantial binary assets or extensive histories, deferring blob downloads until files are actually checked out. However, subsequent Git operations that access file contents may trigger additional network requests.

```yaml
- uses: actions/checkout@v7
  with:
    filter: blob:none
    fetch-depth: 1

```

## Sparse Checkout Patterns

The **sparse checkout** feature limits I/O by writing only matching files to the working tree. In [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 52‑69, 60‑66), the action configures sparse-checkout patterns using `git sparse-checkout set` when you provide the `sparse-checkout` input.

By specifying paths and optionally enabling `sparse-checkout-cone-mode` (the default), you can restrict the checkout to specific directories like `src/` or `docs/`, drastically reducing disk writes and speeding up subsequent steps that only need a subset of the repository.

```yaml
- uses: actions/checkout@v7
  with:
    sparse-checkout: |
      src/
    sparse-checkout-cone-mode: true

```

## Git LFS Network Overhead

Enabling **Git Large File Storage (LFS)** introduces additional network requests. According to the implementation in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 70‑78), when `lfs: true` is set, the action runs `git lfs fetch` after the initial checkout to download large binary assets.

For repositories containing many large files, this can noticeably increase checkout time. If your workflow does not require LFS files, explicitly setting `lfs: false` avoids this overhead. Note that LFS operations may be skipped automatically in certain sparse checkout configurations.

```yaml

# Enable LFS (adds network request for large files)

- uses: actions/checkout@v7
  with:
    lfs: true

```

## Fallback to REST API

When the runner lacks Git 2.18 or later, the action falls back to the GitHub REST API. In [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (lines 78‑92), the code detects the Git version and, if insufficient, invokes `github-api-helper.downloadRepository` to fetch a tarball.

This fallback is slower for large repositories because the entire tarball must be unpacked, and it lacks support for submodules and LFS. The [`src/github-api-helper.ts`](https://github.com/actions/checkout/blob/main/src/github-api-helper.ts) file implements this alternative download mechanism, making it a viable but performance-degraded option when Git is unavailable.

## Background Configuration Optimizations

Several background behaviors in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) affect long-term performance:

- **Garbage Collection Disabling** (lines 135‑141): The action sets `git config gc.auto 0` to prevent automatic garbage collection during the fetch operation. While this avoids unexpected mid-run pauses, repositories may accumulate loose objects over time, potentially slowing future runs if not managed.

- **Safe Directory Configuration** (lines 46‑63): The action adds the checkout directory to Git’s `safe.directory` list via `git config` calls. This adds negligible overhead but ensures compatibility with container jobs.

- **Authentication Handling**: In [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), the `configureAuth` method writes tokens or SSH keys to the local Git config and removes them in the post-step. These extra config writes are minimal but enable subsequent authenticated Git commands without additional network round-trips.

## Summary

- **Default speed**: The action optimizes for speed with shallow clones (`fetch-depth: 1`) and no LFS by default.
- **History costs**: Full history (`fetch-depth: 0`) increases network transfer and storage proportionally to repository size.
- **Selective downloads**: Partial clones (`filter`) and sparse checkouts reduce data transfer by deferring or excluding blob downloads.
- **Binary overhead**: LFS adds a secondary fetch operation that scales with the size and quantity of large files.
- **Fallback penalty**: REST API fallback provides compatibility when Git 2.18+ is unavailable but sacrifices performance and features.

## Frequently Asked Questions

### How does fetch-depth affect actions/checkout performance?

The `fetch-depth` parameter directly controls the amount of Git history transferred. A value of `1` (the default) creates a shallow clone fetching only the latest commit, minimizing network traffic and disk usage. Setting it to `0` fetches the complete history and all branches, which can increase checkout time by seconds or more depending on repository size, as implemented in the fetch logic of [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts).

### What is the performance difference between partial clone and sparse checkout?

**Partial clone** (`filter: blob:none`) fetches all directory trees but defers downloading file contents until accessed, reducing initial transfer while maintaining full directory structure. **Sparse checkout** limits the working tree to specific paths, reducing both disk I/O and storage. Partial clone affects data transfer timing, while sparse checkout affects disk write operations and subsequent step performance.

### Why is my checkout slow when using Git LFS?

When `lfs: true` is configured, the action executes an additional `git lfs fetch` command after the standard checkout, as seen in [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) lines 70‑78. This second network request downloads all large files tracked by LFS, which can significantly increase checkout duration for repositories containing numerous or sizable binary assets.

### Does actions/checkout work without Git installed?

Yes, but with performance trade-offs. If the runner lacks Git 2.18 or later, the action falls back to downloading a repository tarball via the GitHub REST API using `github-api-helper.downloadRepository`. This fallback avoids Git installation but is slower for large repositories, does not support submodules, and cannot handle LFS files.