Picture syncing the full RKE2 manifest into a Hauler store: five files and seventy hardened images, close to ten gigabytes of content, over a link that tops out around 500 Mbps because that's what the environment gives you.
In Hauler 2.0, that sync pulled one image at a time. Image one finishes, image two starts, and the network sits idle between every handoff. On a large manifest over a slow uplink, that idle time is most of the wall-clock time.
Hauler 2.1 fills it. Pulls now run in parallel by default, and on the workload above that turns an eighteen-minute sync into a four-minute one. In practice that is 3 to 5 times faster, and for the engineers doing this work it is the difference between a sync that fits inside a maintenance window and one that eats an afternoon. Every minute spent watching a progress bar is a minute not spent deploying, validating, or moving on to the next task, and across a team running these transfers day in and day out, that time compounds.
Hauler 2.0 rebuilt the OCI plumbing from the inside. The team dropped the ORAS intermediary layer and the forked Cosign dependency, replacing both with direct integrations and an internal signature implementation. At the time, the visible payoff was resilience: retries, granular error handling, chunked hauls, and a cleaner foundation.
That rewrite is also what makes 2.1 possible. Serial pulls were not just a missing feature in the old design; concurrent pulls were hard to do safely on top of the dependencies Hauler used to carry. Once the transfer path was owned end to end, running five fetches at once and coordinating their blob writes into a single OCI layout became a tractable problem instead of a risky one. The 2.0 work paid for itself here.
Hauler store sync and chart --add-images now fetch and store artifacts concurrently, five jobs at a time out of the box.
You control the degree of parallelism with --concurrency, or -j for short, or the HAULER_CONCURRENCY environment variable. The default is 5. A second knob, --blob-concurrency, tunes how many blob writes run in parallel within the OCI layout; it defaults to 16 and scales up to 32 based on your concurrency setting.
The win scales with how much of your time is spent waiting on the network. The slower the registry or the link, the more idle time there is to overlap, and the bigger the speedup. In airgapped environments, where the uplink is usually the bottleneck, this is exactly the workload parallel pulls are built for. See the table below for the metrics gathered during our testing.
| Registry | Hauler 2.0 | Hauler 2.1 | Optimization |
| Carbide (Legacy) | 18:48 | 4:17 | 4.4x faster |
| Carbide (Current) | 8:23 | 2:47 | 3.0x faster |
Two changes make it easier to see what Hauler is doing and to trust what it stored.
Audit logging. A new audit log records every artifact added, saved, loaded, or copied. When you need to prove exactly what crossed the airgap, for compliance, change control, or a postmortem, you have the receipt.
Store to manifest. hauler store create manifest generates a hauler-manifest.yaml directly from an existing store's contents, and a new hauler.dev/original-ref annotation preserves provenance so the generated manifest resolves back to its source even when rewrites are in play. Sync produces a store, and now the store can produce a sync-able manifest.
Chart resource upgrades. Charts now take a platform, honor Helm values set in the manifest, and expose Helm's verification, auth, and TLS options. Chart dependencies are also processed before --add-images discovery, so images from sub-charts actually get found.
Private and insecure registry pulls. First-class support for credentialed pulls from private registries, and for insecure registries with self-signed certs or plain HTTP, which show up often enough in real deployments to deserve proper handling.
Unified flag handling. Flags, environment variables, and annotations now follow one precedence model across the CLI. Explicit flag beats env var beats default, with no surprises when you mix HAULER_* variables with command-line flags.
You do not touch these directly, but they are why Hauler stays current and keeps its security posture from drifting. containered moves to v2, aligning with upstream and its next-generation resolver. Helm moves to v4. Go moves to 1.26.6. Alongside those are the usual dependency bumps, including cosign, go-containerregistry, and oras-go, plus Trivy vulnerability scanning wired through the build with VEX filtering to keep the noise down.
A few smaller improvements round out 2.1:
Remote chunk fixes. The chunked-save path from 2.0 picked up bug fixes, and remote chunks are now supported, so you no longer need every part physically co-located on the loader. Hauler can read chunks from a remote location during load.
Blob integrity check. hauler store info now verifies every blob's digest against its content, catching corruption or a bad transfer at rest before you carry a broken haul across the boundary.
TLS support for remote registries and fileservers. Remote registries and fileservers can now be reached over TLS, so pulls and pushes to those endpoints stay encrypted in transit.
The 2.0 release rebuilt the transfer path. The 2.1 release cashes it in. That is the shape of the work the RGS team is investing in: architecture first, so that features like parallel pulls arrive as a natural consequence rather than a bolted-on special case. Reliability matters, maintainability matters, and when the network is the constraint, the tooling should get out of the way.
Hauler v2.1.0 is available now. Release notes, documentation, and binaries live on the Hauler GitHub repository and at the Hauler docs site. There are three install paths: the one-line installer (curl -sfL https://get.hauler.dev | bash) for connected hosts, a Homebrew tap for macOS, and pre-built binaries on the releases page for airgap, where you download once, copy across the boundary, and drop the binary in your PATH.
Connect with the Hauler team through GitHub, to share feedback.