# Performance

> Make downloads from CloudRepo resilient and measurable: partial and resumed downloads, timing a transfer from your own machine, and reusing what your client already downloaded.

CloudRepo states no speed figure. Many things affect what you see, among them your network, your build machine, the size of what you fetch and your distance to CloudRepo’s region, so this page shows how to measure it, what CloudRepo’s download path does with partial and repeated requests, and which cache of your tools to keep.

## Download part of a file

CloudRepo answers a request for one range of bytes with `206 Partial Content`, the bytes you asked for and a `Content-Range` header. An open range (`Range: bytes=9000000-`) and a suffix range (`Range: bytes=-1024`) work in hosted, proxy and group repositories, and a closed range (`Range: bytes=100-199`) works in hosted repositories. `GET` and `HEAD` both carry `Accept-Ranges: bytes`.

A few things to know when you build a client:

- A range that starts past the end of the file is answered `416` with `Content-Range: bytes */<length>`.
- Several ranges in one request are answered with the whole file, not a multipart response.
- In a hosted repository, a range CloudRepo cannot read, such as `bytes=500-100` or a unit other than `bytes`, is ignored and the whole file is sent.
- In a hosted repository, with `If-Range` set to the file’s current `ETag`, the range is served. With a stale or weak tag, or a date, the whole file is sent.
- `HEAD` answers the file’s `Content-Length`, `ETag` and `Accept-Ranges` without sending the file.

## Resume an interrupted download

Because a repository answers an open range with the rest of the file, curl can finish a download that stopped part of the way. `--continue-at -` tells curl to read how many bytes the output file already holds and ask for the rest:

**Terminal**

```bash
curl --netrc --fail --silent --show-error --continue-at - --output big-1.0.jar \
  https://your-org.mycloudrepo.io/repositories/your-repo/com/example/big/1.0/big-1.0.jar
```

Keep your credential in `~/.netrc`, as in [Test the credential on its own](/docs/reference/troubleshooting.html#test-the-credential-on-its-own), so it is on no command line. Run the same command again until it exits `0`.

Expected: the file on disk grows until it holds the whole file.

## Measure a transfer

To see what a download gets from your machine, time one with curl’s `--write-out`:

**Terminal**

```bash
curl --netrc --fail --silent --show-error --output /dev/null \
  --write-out 'downloaded %{size_download} bytes in %{time_total} s (%{speed_download} bytes/s)\n' \
  https://your-org.mycloudrepo.io/repositories/your-repo/com/example/big/1.0/big-1.0.jar
```

Run it more than once, from the machine whose builds are slow and from another network, and compare.

## Reuse what your client already downloaded

Each build tool keeps a local cache of what it has downloaded. Where each one keeps it, according to the tool’s own documentation:

| Tool   | Local cache                                                                                                    | Documentation                                                                                  |
| ------ | -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Maven  | The local repository, `${user.home}/.m2/repository` by default.                                                | [Maven settings, `localRepository`](https://maven.apache.org/settings.html)                    |
| Gradle | The dependency cache in the `.gradle` directory of your home folder, for example `~/.gradle/caches/modules-2`. | [Gradle dependency caching](https://docs.gradle.org/current/userguide/dependency_caching.html) |
| npm    | The `_cacache` directory inside npm’s `cache` directory, `~/.npm` by default on POSIX systems.                 | [npm cache](https://docs.npmjs.com/cli/v11/commands/npm-cache)                                 |
| pip    | HTTP responses and locally built wheels, `~/.cache/pip` by default on Linux; `pip cache dir` prints the path.  | [pip caching](https://pip.pypa.io/en/stable/topics/caching/)                                   |

A CI job on a fresh machine starts with those directories empty, so it downloads again what an earlier run already fetched. Keep the directory between runs with your platform’s cache feature, such as GitHub Actions’ [dependency caching](https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching) or GitLab CI/CD’s [caching](https://docs.gitlab.com/ci/caching/), and your CI guide shows where your platform keeps its credentials: [CI/CD overview](/docs/ci/overview.html).

---

The page: https://www.cloudrepo.io/docs/reference/performance.html
