setup-bun icon indicating copy to clipboard operation
setup-bun copied to clipboard

Seems quick! where's the cache?

Open KyleSanderson opened this issue 1 year ago • 13 comments

Title is a bit tongue in cheek.

It doesn't look like there's a way to set a damage file or anything for purposes of a cache in the action. This is normally configured in the actions/setup-node action on GH actions.

It doesn't look like bun has that, which is a bit disappointing because it feels like there might be an even deeper win here if that was available.

KyleSanderson avatar Aug 24 '23 06:08 KyleSanderson

What do you mean by damage file? Saving dependencies/whole bun into cache?

xhyrom avatar Aug 24 '23 06:08 xhyrom

When a file is damaged (changed), the cache should be dropped and refreshed.

setup-node calls it cache-dependency-path, which is a fine modern name I guess.

EDIT2: Yes please. If there was caching for the built dependencies subsequent runs would be even faster(?).

KyleSanderson avatar Aug 24 '23 06:08 KyleSanderson

It might be possible to use github action's hashFiles expression to hash bun.lockb and package.json and use that as the cache key?

Alternatively shouldn't we just always cache the ~/.bun/install/cache folder?

Wazbat avatar Sep 10 '23 12:09 Wazbat

It might be possible to use github action's hashFiles expression to hash bun.lockb and package.json and use that as the cache key?

Yeah, that seems reasonable (until there's a better option).

Alternatively shouldn't we just always cache the ~/.bun/install/cache folder?

You could, but it doesn't align to the other node projects. If there's no problem with it in bun that's fine, but the other products expressly look at this.

KyleSanderson avatar Sep 11 '23 04:09 KyleSanderson

Alternatively shouldn't we just always cache the ~/.bun/install/cache folder?

You could, but it doesn't align to the other node projects. If there's no problem with it in bun that's fine, but the other products expressly look at this.

I haven't had a chance to use bun much yet, but from what I can see from the docs, it supposedly always downloads packages to that folder, then uses hardlinks to add the packages to the node_modules folder

If that's the case, then that's the only folder that needs to be cached. You could cache it with the same key every time, or use that same hashFiles expression to create a key, to stop the cache growing in size over time

Wazbat avatar Sep 11 '23 08:09 Wazbat

We haven't implemented dependency caching yet, because early testing showed bun install was faster than using Github's caching mechanism.

Electroid avatar Sep 11 '23 15:09 Electroid

can the hashFiles() technique really work? since the hash changes every time you run bun install :/ (i might completely be misunderstanding how caching in github actions is supposed to work)

image

ceIia avatar Sep 26 '23 12:09 ceIia

I tested the solution mentioned above with:

- uses: actions/cache@v3
  with:
    key: key
    path: ~/.bun/install/cache

It reduces the bun install time from 10 seconds to 2 seconds, but the cache restore time is 8 seconds, so it's a bit of a wash.

jylin avatar Nov 03 '23 12:11 jylin

For me, this cache config adds 2 seconds to restore the cache and then drops my bun install time from 6-10s to <2s. Of course sometimes the cache restore takes longer due to network variability, but that variability impacts install time too if fetching all deps every time. Seems worthwhile overall to put something like this in by default (exact ideal key config is up for debate).

      - uses: actions/cache@v4
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-${{ matrix.bun }}-bun-${{ hashFiles('**/bun.lockb') }}
          restore-keys: |
            ${{ runner.os }}-${{ matrix.bun }}-bun-

bgentry avatar Jan 22 '24 17:01 bgentry

@bgentry but what about the time to save the cache?

In my GitLab CI it took 2 min to save the cache:

image

(35s to restore cache, 2s to install).

On a run that the .lock file was changed (so, changed cache key and then no cache), it took 17s to install the packages and 1m20s to save the cache.

I use https://www.sonatype.com/products/sonatype-nexus-repository, so that might already remove the need to cache again the deps.

ftzi avatar Mar 07 '24 09:03 ftzi

1m20s sounds like you either have an enormous set of deps to cache, or a very slow transfer speed. With GitHub Actions my cache save time was generally under 10 seconds.

bgentry avatar Mar 07 '24 13:03 bgentry

I'm a bit confused, can someone help me out. This seems to be so suspiciously fast that it seems impossible.

I just refactored a workflow. The steps used to look like this (bunch of details omitted for brevity):

Single cached install step, then multiple parallel jobs after that
install-cache:
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
    - run: yarn install
    - run: npx playwright install
    - uses: actions/cache/save@v4

test-types:
  needs: install-cache
  steps:
    - uses: actions/checkout@v4
    - uses: actions/cache/restore@v4
    - run: yarn test:types

test-unit:
  needs: install-cache
  steps:
    - uses: actions/checkout@v4
    - uses: actions/cache/restore@v4
    - run: yarn test:unit

test-e2e:
  needs: install-cache
  steps:
    - uses: actions/checkout@v4
    - uses: actions/cache/restore@v4
    - run: yarn test:e2e

While experimenting with transitioning our stack from Node/Yarn to Bun, I updated this to just look like this:

All jobs start right away in parallel, install step just duplicated in every job
test-types:
  steps:
    - uses: actions/checkout@v4
    - uses: oven-sh/setup-bun@v1
    - run: bun install
    - run: bun run test:types

test-unit:
  steps:
    - uses: actions/checkout@v4
    - uses: oven-sh/setup-bun@v1
    - run: bun install
    - run: bun run test:unit

test-e2e:
  steps:
    - uses: actions/checkout@v4
    - uses: oven-sh/setup-bun@v1
    - run: bun install
    - run: bunx playwright install
    - run: bun run test:e2e

And... Bun installs the packages in less than a second? How is that possible when we have ~50 dependencies? Surely just the network download of the packages alone must take more than a second? Is there some kind of edge computing going on here where Actions can download the packages extra fast? Or is there a hidden cache somewhere that I'm unable to see? Our Actions cache page seems to be empty, and I believe even if some third-party action (e.g. setup-node) saves some cache for you (without using @actions/cache directly), it would show up there? I'm used to yarn install taking over a minute, and I figured a large % of that was the downloading, but maybe it really was the dependency resolution stuff that was taking the most time (which is what bun crushes yarn with)?

More details about how just ditching @actions/cache all-together saved me time

Regarding the fact that my change doesn't cache playwright anymore... simply saving (~10s) and restoring (~10s) our node_modules and playwright with @actions/cache takes longer than just installing playwright once (~12s).

Here are some comparison of run times between the different caching/installation approaches:

cache miss, need to do cache-save before cache-restores cache hit, only need to do cache-restores no cache step at all
run run run

vincerubinetti avatar Mar 08 '24 23:03 vincerubinetti

Does anyone have insight into why the results here seem to vary so much? Some reports of cache being much faster, some reports of cache being the same, and some reports (myself included) showing cache taking longer.

No cache: 21s to download and install Cache: 19s to restore ~600 mb cache, 8s to install

GitHub Action with no cache

name: Bun Install Benchmark

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  dependencies:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2

      - name: Install Dependencies
        run: bun i
GitHub Action with cache

name: Bun Install (With Cache) Benchmark

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  dependencies:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
          restore-keys: |
            ${{ runner.os }}-bun-

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2

      - name: Install Dependencies
        run: bun i

arimgibson avatar Aug 17 '24 00:08 arimgibson