Every Go project depends on external modules — from the standard library extensions to third-party packages pulled from proxy.golang.org. Relying entirely on public module proxies introduces real risks that compound as your team and codebase grow. Build pipelines break when upstream proxies go down, supply chain attacks slip through unchecked module downloads, and network egress costs spiral with every CI run pulling the same dependencies.
A self-hosted Go module proxy solves all three problems at once. It caches modules locally for faster builds, gives you control over which packages enter your supply chain, and eliminates repeated network calls to external services. In 2026, two open-source projects lead this space: Athens and GOPROXY. Each takes a fundamentally different approach to the same problem.
This guide compares both tools, provides production-ready Docker Compose configurations, and helps you choose the right proxy for your Go development workflow.
Why Self-Host a Go Module Proxy?
Go modules changed how the language manages dependencies, but the default behavior — downloading directly from proxy.golang.org — isn’t ideal for every organization. Here is why teams choose to run their own proxy:
- Build speed — cached modules serve from local storage, cutting CI build times by 40-70% for large projects with hundreds of dependencies
- Supply chain security — validate module checksums against your own
sum.golang.orgmirror and block unapproved packages before they reach your codebase - Offline builds — once cached, modules are available even when the public proxy is unreachable or your network is isolated
- Private modules — host internal Go packages alongside public ones through a single
GOPROXYendpoint, eliminating separate private registry tooling - Bandwidth savings — a single cached module serves every developer and CI job, reducing egress costs for teams running many concurrent builds
- Compliance and audit — log every module download, track versions in use across your organization, and maintain an artifact trail for security reviews
For teams running Go at scale — whether that means a handful of microservices or a monorepo with thousands of packages — a self-hosted proxy pays for itself in saved build time alone.
Athens: The Full-Featured Go Module Proxy
Athens (4,740 stars, last updated April 2026) is the most widely deployed self-hosted Go module proxy. Originally created as an official Go community project, it provides a complete proxy server with pluggable storage backends, a web-based module browser, and support for private Go repositories.
Key Features
- Multiple storage backends — MongoDB, MinIO/S3, Azure Blob Storage, Google Cloud Storage, and local disk
- Web UI — browse cached modules, view versions, and download packages through a built-in interface
- Private module support — configure wildcard patterns (
GOPRIVATE) to proxy internal repositories alongside public ones - Module download filtering — whitelist or block specific modules and version patterns
- Distributed caching — run multiple Athens instances behind a load balancer with shared storage
- VCS integration — pulls modules directly from GitHub, GitLab, Bitbucket, or any Git-compatible source
- Go checksum database integration — validates module integrity against
sum.golang.orgby default
Docker Compose Deployment
Here is a production-ready Athens setup with MongoDB for module storage and local disk for configuration:
| |
Athens Configuration File
Create config/filter.json to control which modules Athens will proxy:
| |
Then configure your Go client to use the proxy:
| |
S3 Storage Backend
For production deployments, swap MongoDB for S3-compatible storage to enable multi-region caching:
| |
This configuration is particularly useful for teams running CI across multiple geographic regions, where each region needs fast local access to the same module cache.
GOPROXY: The Minimalist Alternative
GOPROXY (1,478 stars, last updated April 2026) takes a different approach. Rather than a full-featured server, it provides a lightweight Go module proxy handler — a library you embed into your own Go application. This gives you complete control over the proxy’s behavior, storage, and integration with existing infrastructure.
Key Features
- Minimal footprint — the core handler is under 1,000 lines of Go code
- Embeddable — integrate into existing Go services, reverse proxies, or CI pipelines
- Custom storage — implement your own
Cacherinterface to store modules anywhere - Protocol compliance — fully implements the GOPROXY protocol specification
- No external dependencies — runs as a single Go binary with no database requirement
- Hot module caching — cache modules to disk with configurable TTL and eviction policies
Self-Hosted Deployment
Because GOPROXY is a library, you wrap it in a minimal Go server. Here is a complete working example:
| |
Build and run:
| |
Docker Compose for GOPROXY
Package the self-hosted proxy in a lightweight container:
| |
| |
Build and start:
| |
Feature Comparison
| Feature | Athens | GOPROXY |
|---|---|---|
| Type | Standalone server | Embeddable library |
| Stars | 4,740 | 1,478 |
| Storage | MongoDB, S3, Azure, GCS, disk | Disk (custom implementations possible) |
| Web UI | Built-in module browser | None |
| Private modules | Yes (filter config) | Yes (via GoBinEnv) |
| Checksum verification | Built-in sum.golang.org | Configurable |
| Docker image | Official (gomods/athens) | Build from source |
| External dependencies | MongoDB or object storage | None |
| Multi-instance | Shared storage backend | Each instance has own cache |
| Download filtering | JSON config file | Programmatic control |
| Memory footprint | ~50-100 MB with MongoDB | ~10-20 MB |
| Best for | Teams needing a ready-to-use proxy | Developers embedding proxy into existing systems |
Choosing the Right Go Module Proxy
Choose Athens when:
- You need a production-ready proxy with zero custom code
- Multiple storage backend options matter for your infrastructure
- A web-based module browser would help your team audit dependencies
- You want built-in support for private Go repositories
- Your CI runs across multiple regions with shared object storage
Choose GOPROXY when:
- You want to embed proxy functionality into an existing Go service
- Minimal dependencies and small binary size are priorities
- You need custom caching logic (e.g., Redis-backed cache, custom eviction)
- Your team prefers programmatic control over configuration files
- You are building a custom developer platform with integrated module proxying
For most organizations, Athens is the right starting point. It deploys in minutes with Docker Compose, scales horizontally with shared storage, and requires no code to operate. GOPROXY shines in specialized scenarios where the proxy is one component of a larger internal platform.
Production Best Practices
1. Configure Upstream Proxy Fallback
Always configure Athens or GOPROXY to fall back to the official Go proxy:
| |
This ensures your proxy can fetch modules it has not yet cached, while still serving cached copies for repeat requests.
2. Enable Module Checksum Verification
Keep the Go checksum database active to detect tampered modules:
| |
3. Set Appropriate Timeouts
Large modules can take time to download. Configure generous timeouts to avoid partial downloads:
| |
4. Use Reverse Proxy for HTTPS
Terminate TLS with a reverse proxy (Nginx, Caddy, or Traefik) in front of Athens:
| |
| |
5. Monitor Cache Hit Rates
Track how often your proxy serves cached modules versus fetching from upstream. Athens exposes Prometheus metrics on /metrics by default:
| |
For related reading, see our guide on self-hosted package registries with Nexus and Verdaccio for a broader view of artifact management, or our comparison of self-hosted SBOM tracking tools to complement your Go module proxy with software bill of materials generation. Teams managing CI/CD pipelines should also review our dependency automation guide covering Renovate and Dependabot for automated module update workflows.
FAQ
What is a Go module proxy and why do I need one?
A Go module proxy is a server that implements the GOPROXY protocol, caching Go module downloads and serving them to clients on request. Instead of every go get or go build fetching directly from proxy.golang.org, your proxy serves cached copies. This speeds up builds, reduces network dependency, and gives you control over which modules your team can use.
Does Athens support private Go modules?
Yes. Athens can proxy private repositories hosted on GitHub, GitLab, or any Git-compatible service. Configure GOPRIVATE environment variables and authentication tokens (via ATHENS_GITHUB_TOKEN, ATHENS_GITLAB_TOKEN, or SSH keys) to enable access. You can also use the filter file to include or exclude specific module patterns.
Can I run multiple Athens instances for high availability?
Yes. Athens is designed for horizontal scaling. Deploy multiple instances behind a load balancer and point them at a shared storage backend (MongoDB replica set, S3 bucket, or Azure Blob container). Each instance reads and writes to the same storage layer, so any cached module is available from any node.
What is the difference between Athens and GOPROXY?
Athens is a complete, standalone Go module proxy server with built-in storage, web UI, and configuration. GOPROXY is a Go library (handler) that you embed into your own application. Think of Athens as a ready-to-deploy product and GOPROXY as a building block for custom solutions.
How do I migrate from proxy.golang.org to a self-hosted proxy?
Point your GOPROXY environment variable to your proxy’s URL: export GOPROXY=http://your-proxy:3000. Go will automatically start routing all module requests through your proxy. Existing builds will work immediately — the proxy fetches any uncached modules from upstream on first request, then serves them from cache on subsequent requests. No manual import or pre-warming is required.
Does GOPROXY cache modules to disk?
Yes, when configured with a disk-based cacher. The cacher.NewDisk(path) function creates a local file system cache at the specified directory. You can also implement the Cacher interface to use Redis, etcd, or any other storage system.
How do I secure my self-hosted Go module proxy?
Place the proxy behind HTTPS using a reverse proxy (Nginx, Caddy, or Traefik) with TLS certificates. For Athens, you can enable basic authentication with ATHENS_BASIC_AUTH_USER and ATHENS_BASIC_AUTH_PASS. For team environments, integrate with OAuth or SSO through your reverse proxy. Always keep module checksum verification enabled to detect tampered packages.
Can I use Athens with Go workspaces (Go 1.18+)?
Yes. Athens works transparently with Go workspaces (go.work files). The proxy intercepts all module resolution requests regardless of whether they come from a single module or a workspace. No special configuration is needed — just set GOPROXY in your environment or go.env file.