# go mod download vs go mod tidy: Key Differences and When to Use Each

> Understand go mod download vs go mod tidy. Learn how download populates the cache and tidy cleans your go.mod and go.sum files for efficient dependency management. Get started today.

- Repository: [Go/go](https://github.com/golang/go)
- Tags: deep-dive
- Published: 2026-02-14

---

**The primary difference is that `go mod download` populates the local module cache without modifying module definitions, while `go mod tidy` cleans up `go.mod` and `go.sum` by adding missing dependencies and removing unused ones.**

Both commands operate on a module’s dependency graph, but they serve distinct purposes within the Go toolchain. According to the `golang/go` source code, understanding the architectural separation between cache management and dependency graph maintenance is essential for efficient CI pipelines and reproducible builds.

## Core Functional Differences

**`go mod download`** focuses exclusively on fetching and verifying module contents. It parses the existing `go.mod` file to identify required modules, then ensures their source code is present in the local module cache (`$GOMODCACHE`). The command never adds or removes `require` statements from `go.mod`, though it will append checksum entries to `go.sum` for any newly downloaded modules.

**`go mod tidy`** performs dependency graph maintenance. It scans the source tree to discover imported packages, computes the minimal set of required modules, and reconciles that set with the current `go.mod`. This process may add new `require` statements, drop unused ones, and prune irrelevant `exclude` or `replace` directives. Finally, it regenerates `go.sum` to contain checksums exactly for the modules required by the final `go.mod`, removing any stale entries.

## How go mod download Works

The implementation resides in [[`src/cmd/go/internal/modcmd/download.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modcmd/download.go)](https://github.com/golang/go/blob/master/src/cmd/go/internal/modcmd/download.go). When executed, the command follows this flow:

1. **Parse Requirements**: Reads the current `go.mod` to obtain the list of required modules.
2. **Fetch Modules**: Invokes `modfetch.DownloadModule` (defined in [`src/cmd/go/internal/modfetch/fetch.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modfetch/fetch.go)) for each module entry.
3. **Cache Population**: Resolves the module version, contacts the configured proxy or cache, verifies the checksum against `go.sum`, and stores the module zip and source files in `$GOMODCACHE`.
4. **Output**: If `-json` is supplied, emits a `ModuleJSON` struct (lines 94–112 in [`download.go`](https://github.com/golang/go/blob/main/download.go)) describing the download result.

```bash

# Pre-populate the cache for all dependencies listed in go.mod

go mod download

# Download a specific version with machine-readable output

go mod download -json golang.org/x/tools@latest

```

## How go mod tidy Works

The logic lives in [[`src/cmd/go/internal/modcmd/tidy.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modcmd/tidy.go)](https://github.com/golang/go/blob/master/src/cmd/go/internal/modcmd/tidy.go). This command orchestrates the tidy algorithm from the `modload` package:

1. **Load Graph**: Calls `modload.LoadAllModules` to initialize the module loading system.
2. **Source Analysis**: Walks the source tree to discover all imported packages and computes the minimal required module set.
3. **Reconcile Dependencies**: Compares the computed set against the existing `go.mod`, adding missing `require` statements and removing unused ones.
4. **Write Changes**: Invokes `modload.WriteGoMod` to rewrite `go.mod` and `modload.WriteGoSum` to generate a clean `go.sum` containing only the necessary checksums.

Unlike `go mod download`, `go mod tidy` accepts no arguments and always operates on the module in the current directory.

```bash

# Clean up go.mod and go.sum after removing an import

go mod tidy

```

## When to Use Each Command

Use **`go mod download`** when you need to:
- Pre-populate the module cache before running tests or CI steps that require dependency source code.
- Verify that a specific module version can be fetched from the proxy.
- Populate `$GOMODCACHE` in a Docker layer without modifying build files.

Use **`go mod tidy`** when you need to:
- Ensure the module’s dependency list is accurate after adding or removing code imports.
- Keep `go.mod` and `go.sum` minimal and reproducible before committing changes.
- Prune unused dependencies that are no longer referenced by the codebase.

## Summary

- **`go mod download`** only reads `go.mod` to fetch modules into `$GOMODCACHE`, never modifying the module definition itself.
- **`go mod tidy`** actively modifies `go.mod` and `go.sum` to reflect the actual imports used in the source code.
- **Download** appends to `go.sum` but never deletes entries; **tidy** regenerates `go.sum` to match the final dependency set exactly.
- **Download** accepts specific module arguments and supports `-json` output; **tidy** works only on the current directory module.

## Frequently Asked Questions

### Does `go mod download` update the `go.mod` file?

No. According to the implementation in [`download.go`](https://github.com/golang/go/blob/main/download.go), the command only reads the existing `go.mod` to determine which modules to fetch. It never adds or removes `require` statements, though it may append new checksum entries to `go.sum` for modules that were not previously recorded.

### Can `go mod tidy` be run with specific module arguments?

No. The `go mod tidy` command takes no arguments and always operates on the module in the current working directory. It scans the entire source tree to determine the complete set of required dependencies before updating the module definition files.

### Which command should I run before committing code to version control?

Run **`go mod tidy`**. This ensures that `go.mod` contains the minimal set of required dependencies and that `go.sum` includes only the checksums for those specific modules. This practice keeps the repository state clean and reproducible for other developers.

### How do these commands handle the `go.sum` file differently?

`go mod download` writes checksum entries for any downloaded modules that were not already present in `go.sum`, but it does not delete any entries. In contrast, `go mod tidy` rewrites `go.sum` completely so that it contains checksums exactly for the modules required by the final `go.mod`, removing any unused entries in the process.