# Introduction to Cache

#### Eliot J. B. McIntire

#### May 15 2026

# 1 Reproducible workflow

As part of a reproducible workflow, caching of function calls, code chunks, and other elements of a project is a critical component. The objective of a reproducible workflow is is likely that an entire work flow from raw data to publication, decision support, report writing, presentation building etc., could be built and be reproducible anywhere, on any computer, operating system, with any starting conditions, on demand. The `reproducible::Cache` function is built to work with any R function.

## 1.1 Differences with other approaches

`Cache` users `DBI` as a backend, with key functions, `dbReadTable`, `dbRemoveTable`, `dbSendQuery`, `dbSendStatement`, `dbCreateTable` and `dbAppendTable`. These can all be accessed via `Cache`, `showCache`, `clearCache`, and `keepCache`. It is optimized for speed of transactions, using `digest::digest` on objects and files. The main function is superficially similar to `archivist::cache`, which uses `digest::digest` in all cases to determine whether the arguments are identical in subsequent iterations. It also but does many things that make standard caching with `digest::digest` don’t work reliably between systems. For these, the function `.robustDigest` is introduced to make caching transferable between systems. This is relevant for file paths, environments, parallel clusters, functions (which are contained within an environment), and many others (e.g., see `?.robustDigest` for methods). `Cache` also adds important elements like automated tagging and the option to retrieve disk-cached values via stashed objects in memory using `memoise::memoise`. This means that running `Cache` 1, 2, and 3 times on the same function will get progressively faster. This can be extremely useful for web apps built with, say `shiny`.

## 1.2 Function-level caching

Any function can be cached by wrapping `Cache` around the function call, or by using base pipe `|>`:

This will be a slight change to a function call, such as: `terra::project(raster, crs = terra::crs(newRaster))` to `Cache(terra::project(raster, crs = terra::crs(newRaster)))` or with the pipe, which may be more convenient as it is easy to add and remove caching in the code base: `terra::project(raster, crs = terra::crs(newRaster)) |> Cache()`

This is particularly useful for expensive operations.

    library(reproducible)
    library(data.table)

    ##
    ## Attaching package: 'data.table'

    ## The following object is masked from 'package:terra':
    ##
    ##     shift

    tmpDir <- file.path(tempfile(), "reproducible_examples", "Cache")
    dir.create(tmpDir, recursive = TRUE)

    # Source raster with a complete LCC definition
    ras <- terra::rast(terra::ext(0, 300, 0, 300), vals = 1:9e4, res = 1)
    terra::crs(ras) <- "+proj=lcc +lat_1=60 +lat_2=70 +lat_0=50 +lon_0=-100 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"

    # Target CRS in PROJ form (no EPSG lookup)
    newCRS <- "+proj=longlat +datum=WGS84 +no_defs"

    # Derive target extent from source extent (no registry lookup)
    target_ext <- terra::project(terra::ext(ras), from = terra::crs(ras), to = newCRS)

    # Build template with chosen resolution; assign CRS
    tmplate <- terra::rast(target_ext, resolution = 0.00001)
    terra::crs(tmplate) <- newCRS

    # No Cache
    system.time(map1 <- terra::project(ras, tmplate, method = "near"))

    ##    user  system elapsed
    ##   0.027   0.000   0.028

    # Try with memoise for this example -- for many simple cases, memoising will not be faster
    opts <- options("reproducible.useMemoise" = TRUE)
    # With Cache -- a little slower the first time because saving to disk
    system.time({
      suppressWarnings({
        map1 <- terra::project(ras, tmplate, method = "near") |>
          Cache(cachePath = tmpDir)
      })
    })

    ## Saved! Cache file: b080b61ea3444bd7.rds; fn: project (and added a memoised copy)

    ##    user  system elapsed
    ##   0.388   0.121   0.478

    # faster the second time; improvement depends on size of object and time to run function
    system.time({
      map2 <- terra::project(ras, tmplate, method = "near") |>
        Cache(cachePath = tmpDir)
    })

    ## Object to retrieve (fn: project, b080b61ea3444bd7.rds) ...

    ## Loaded! Memoised result from previous project call

    ##    user  system elapsed
    ##   0.175   0.001   0.176

    options(opts)

    all.equal(map1, map2, check.attributes = FALSE) # TRUE

    ## [1] "Attributes: < Component \".Cache\": Component \"newCache\": 1 element mismatch >"

## 1.3 Caching examples

### 1.3.1 Basic use

    try(clearCache(tmpDir, ask = FALSE), silent = TRUE) # just to make sure it is clear

    ranNumsA <- rnorm(10, 16) |> Cache(cachePath = tmpDir)

    ## Saved! Cache file: aa549dd751b2f26d.rds; fn: rnorm

    # All same
    ranNumsB <- rnorm(10, 16) |> Cache(cachePath = tmpDir) # recovers cached copy

    ## Object to retrieve (fn: rnorm, aa549dd751b2f26d.rds) ...

    ## Loaded! Cached result from previous rnorm call

    ranNumsD1 <- Cache(quote(rnorm(n = 10, 16))) |> Cache(cachePath = tmpDir) # recovers cached copy

    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.

    ## Saved! Cache file: aa549dd751b2f26d.rds; fn: rnorm

    ## Saved! Cache file: 603f3ba7e9e2c042.rds; fn: Cache

    ranNumsD2 <- Cache(rnorm(n = 10, 16)) |> Cache(cachePath = tmpDir) # recovers cached copy

    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.

    ## Object to retrieve (fn: rnorm, aa549dd751b2f26d.rds) ...

    ## Loaded! Cached result from previous rnorm call

    ## Saved! Cache file: 45c631b2206cfc1c.rds; fn: Cache

    # pipe
    ranNumsD3 <- rnorm(n = 10, 16) |> Cache(cachePath = tmpDir) # recovers cached copy

    ## Object to retrieve (fn: rnorm, aa549dd751b2f26d.rds) ...

    ## Loaded! Cached result from previous rnorm call

    # Any minor change makes it different
    ranNumsE <- rnorm(10, 6) |> Cache(cachePath = tmpDir) # different

    ## Saved! Cache file: d78b46a2a76d6d80.rds; fn: rnorm

#### 1.3.1.1 Example 1: Basic cache use with tags

    ranNumsA <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Saved! Cache file: adf21923cd1e50d0.rds; fn: rnorm

    ranNumsB <- runif(4) |> Cache(cachePath = tmpDir, userTags = "objectName:b")

    ## Saved! Cache file: e23cab430872a0ea.rds; fn: runif

    showCache(tmpDir, userTags = c("objectName"))

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         a
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:19.00139
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.001259089 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun         0.0009067059 secs
    ## 15: e23cab430872a0ea            function                     runif
    ## 16: e23cab430872a0ea          objectName                         b
    ## 17: e23cab430872a0ea            accessed 2026-05-15 22:47:19.00660
    ## 18: e23cab430872a0ea             inCloud                     FALSE
    ## 19: e23cab430872a0ea   elapsedTimeDigest          0.001269817 secs
    ## 20: e23cab430872a0ea           preDigest     .FUN:881ec847b7161f3c
    ## 21: e23cab430872a0ea           preDigest      max:853b1797f54b229c
    ## 22: e23cab430872a0ea           preDigest      min:c40c00762a0dac94
    ## 23: e23cab430872a0ea           preDigest        n:7eef4eae85fd9229
    ## 24: e23cab430872a0ea               class                   numeric
    ## 25: e23cab430872a0ea         object.size                        80
    ## 26: e23cab430872a0ea            fromDisk                     FALSE
    ## 27: e23cab430872a0ea          resultHash
    ## 28: e23cab430872a0ea elapsedTimeFirstRun         0.0009038448 secs
    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:19.003118
    ##  2: 2026-05-15 22:47:19.003118
    ##  3: 2026-05-15 22:47:19.003118
    ##  4: 2026-05-15 22:47:19.003118
    ##  5: 2026-05-15 22:47:19.003118
    ##  6: 2026-05-15 22:47:19.003118
    ##  7: 2026-05-15 22:47:19.003118
    ##  8: 2026-05-15 22:47:19.003118
    ##  9: 2026-05-15 22:47:19.003118
    ## 10: 2026-05-15 22:47:19.003118
    ## 11: 2026-05-15 22:47:19.003118
    ## 12: 2026-05-15 22:47:19.003118
    ## 13: 2026-05-15 22:47:19.003118
    ## 14: 2026-05-15 22:47:19.003118
    ## 15:  2026-05-15 22:47:19.00834
    ## 16:  2026-05-15 22:47:19.00834
    ## 17:  2026-05-15 22:47:19.00834
    ## 18:  2026-05-15 22:47:19.00834
    ## 19:  2026-05-15 22:47:19.00834
    ## 20:  2026-05-15 22:47:19.00834
    ## 21:  2026-05-15 22:47:19.00834
    ## 22:  2026-05-15 22:47:19.00834
    ## 23:  2026-05-15 22:47:19.00834
    ## 24:  2026-05-15 22:47:19.00834
    ## 25:  2026-05-15 22:47:19.00834
    ## 26:  2026-05-15 22:47:19.00834
    ## 27:  2026-05-15 22:47:19.00834
    ## 28:  2026-05-15 22:47:19.00834
    ##                    createdDate
    ##                         <char>

    showCache(tmpDir, userTags = c("^a$")) # regular expression ... "a" exactly

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         a
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:19.00139
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.001259089 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun         0.0009067059 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:19.003118
    ##  2: 2026-05-15 22:47:19.003118
    ##  3: 2026-05-15 22:47:19.003118
    ##  4: 2026-05-15 22:47:19.003118
    ##  5: 2026-05-15 22:47:19.003118
    ##  6: 2026-05-15 22:47:19.003118
    ##  7: 2026-05-15 22:47:19.003118
    ##  8: 2026-05-15 22:47:19.003118
    ##  9: 2026-05-15 22:47:19.003118
    ## 10: 2026-05-15 22:47:19.003118
    ## 11: 2026-05-15 22:47:19.003118
    ## 12: 2026-05-15 22:47:19.003118
    ## 13: 2026-05-15 22:47:19.003118
    ## 14: 2026-05-15 22:47:19.003118

    showCache(tmpDir, userTags = c("runif")) # show only cached objects made during runif call

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: e23cab430872a0ea            function                     runif
    ##  2: e23cab430872a0ea          objectName                         b
    ##  3: e23cab430872a0ea            accessed 2026-05-15 22:47:19.00660
    ##  4: e23cab430872a0ea             inCloud                     FALSE
    ##  5: e23cab430872a0ea   elapsedTimeDigest          0.001269817 secs
    ##  6: e23cab430872a0ea           preDigest     .FUN:881ec847b7161f3c
    ##  7: e23cab430872a0ea           preDigest      max:853b1797f54b229c
    ##  8: e23cab430872a0ea           preDigest      min:c40c00762a0dac94
    ##  9: e23cab430872a0ea           preDigest        n:7eef4eae85fd9229
    ## 10: e23cab430872a0ea               class                   numeric
    ## 11: e23cab430872a0ea         object.size                        80
    ## 12: e23cab430872a0ea            fromDisk                     FALSE
    ## 13: e23cab430872a0ea          resultHash
    ## 14: e23cab430872a0ea elapsedTimeFirstRun         0.0009038448 secs
    ##                   createdDate
    ##                        <char>
    ##  1: 2026-05-15 22:47:19.00834
    ##  2: 2026-05-15 22:47:19.00834
    ##  3: 2026-05-15 22:47:19.00834
    ##  4: 2026-05-15 22:47:19.00834
    ##  5: 2026-05-15 22:47:19.00834
    ##  6: 2026-05-15 22:47:19.00834
    ##  7: 2026-05-15 22:47:19.00834
    ##  8: 2026-05-15 22:47:19.00834
    ##  9: 2026-05-15 22:47:19.00834
    ## 10: 2026-05-15 22:47:19.00834
    ## 11: 2026-05-15 22:47:19.00834
    ## 12: 2026-05-15 22:47:19.00834
    ## 13: 2026-05-15 22:47:19.00834
    ## 14: 2026-05-15 22:47:19.00834

    clearCache(tmpDir, userTags = c("runif"), ask = FALSE) # remove only cached objects made during runif call

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    showCache(tmpDir) # all

    ## Cache size:

    ## Total (including Rasters): 482 bytes

    ## Selected objects (not including Rasters): 482 bytes

    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##  1: 45c631b2206cfc1c            function                            Cache
    ##  2: 45c631b2206cfc1c            accessed        2026-05-15 22:47:18.95982
    ##  3: 45c631b2206cfc1c             inCloud                            FALSE
    ##  4: 45c631b2206cfc1c   elapsedTimeDigest                 0.002118111 secs
    ##  5: 45c631b2206cfc1c           preDigest             FUN:16fcb175c353ba66
    ##  6: 45c631b2206cfc1c           preDigest cacheSaveFormat:cf2828ea967d53e7
    ##  7: 45c631b2206cfc1c           preDigest          dryRun:e9aac936a0e8f6ae
    ##  8: 45c631b2206cfc1c           preDigest            .FUN:a844fd4a43c312e6
    ##  9: 45c631b2206cfc1c           preDigest  .cacheChaining:71681d621365dfd7
    ## 10: 45c631b2206cfc1c           preDigest     .cacheExtra:c85d88fc56f4e042
    ## 11: 45c631b2206cfc1c           preDigest   .functionName:c85d88fc56f4e042
    ## 12: 45c631b2206cfc1c           preDigest            conn:118387d5d48f757d
    ## 13: 45c631b2206cfc1c           preDigest             drv:9ce9a83896bf68a1
    ## 14: 45c631b2206cfc1c               class                          numeric
    ## 15: 45c631b2206cfc1c         object.size                              176
    ## 16: 45c631b2206cfc1c            fromDisk                            FALSE
    ## 17: 45c631b2206cfc1c          resultHash
    ## 18: 45c631b2206cfc1c elapsedTimeFirstRun                 0.006330729 secs
    ## 19: 603f3ba7e9e2c042            function                            Cache
    ## 20: 603f3ba7e9e2c042            accessed        2026-05-15 22:47:18.94684
    ## 21: 603f3ba7e9e2c042             inCloud                            FALSE
    ## 22: 603f3ba7e9e2c042   elapsedTimeDigest                 0.002407312 secs
    ## 23: 603f3ba7e9e2c042           preDigest             FUN:265d86c3bd130de5
    ## 24: 603f3ba7e9e2c042           preDigest cacheSaveFormat:cf2828ea967d53e7
    ## 25: 603f3ba7e9e2c042           preDigest          dryRun:e9aac936a0e8f6ae
    ## 26: 603f3ba7e9e2c042           preDigest            .FUN:a844fd4a43c312e6
    ## 27: 603f3ba7e9e2c042           preDigest  .cacheChaining:71681d621365dfd7
    ## 28: 603f3ba7e9e2c042           preDigest     .cacheExtra:c85d88fc56f4e042
    ## 29: 603f3ba7e9e2c042           preDigest   .functionName:c85d88fc56f4e042
    ## 30: 603f3ba7e9e2c042           preDigest            conn:118387d5d48f757d
    ## 31: 603f3ba7e9e2c042           preDigest             drv:9ce9a83896bf68a1
    ## 32: 603f3ba7e9e2c042               class                             call
    ## 33: 603f3ba7e9e2c042         object.size                             1320
    ## 34: 603f3ba7e9e2c042            fromDisk                            FALSE
    ## 35: 603f3ba7e9e2c042          resultHash
    ## 36: 603f3ba7e9e2c042 elapsedTimeFirstRun                  0.00774622 secs
    ## 37: aa549dd751b2f26d            function                            rnorm
    ## 38: aa549dd751b2f26d            accessed        2026-05-15 22:47:18.93473
    ## 39: aa549dd751b2f26d             inCloud                            FALSE
    ## 40: aa549dd751b2f26d   elapsedTimeDigest                 0.001377821 secs
    ## 41: aa549dd751b2f26d           preDigest            .FUN:4f604aa46882b368
    ## 42: aa549dd751b2f26d           preDigest            mean:15620f138033a66c
    ## 43: aa549dd751b2f26d           preDigest               n:c5775c3b366fb719
    ## 44: aa549dd751b2f26d           preDigest              sd:853b1797f54b229c
    ## 45: aa549dd751b2f26d               class                          numeric
    ## 46: aa549dd751b2f26d         object.size                              176
    ## 47: aa549dd751b2f26d            fromDisk                            FALSE
    ## 48: aa549dd751b2f26d          resultHash
    ## 49: aa549dd751b2f26d elapsedTimeFirstRun                 0.001137495 secs
    ## 50: aa549dd751b2f26d            accessed        2026-05-15 22:47:18.94257
    ## 51: aa549dd751b2f26d            accessed        2026-05-15 22:47:18.97231
    ## 52: adf21923cd1e50d0            function                            rnorm
    ## 53: adf21923cd1e50d0          objectName                                a
    ## 54: adf21923cd1e50d0            accessed        2026-05-15 22:47:19.00139
    ## 55: adf21923cd1e50d0             inCloud                            FALSE
    ## 56: adf21923cd1e50d0   elapsedTimeDigest                 0.001259089 secs
    ## 57: adf21923cd1e50d0           preDigest            .FUN:4f604aa46882b368
    ## 58: adf21923cd1e50d0           preDigest            mean:c40c00762a0dac94
    ## 59: adf21923cd1e50d0           preDigest               n:7eef4eae85fd9229
    ## 60: adf21923cd1e50d0           preDigest              sd:853b1797f54b229c
    ## 61: adf21923cd1e50d0               class                          numeric
    ## 62: adf21923cd1e50d0         object.size                               80
    ## 63: adf21923cd1e50d0            fromDisk                            FALSE
    ## 64: adf21923cd1e50d0          resultHash
    ## 65: adf21923cd1e50d0 elapsedTimeFirstRun                0.0009067059 secs
    ## 66: d78b46a2a76d6d80            function                            rnorm
    ## 67: d78b46a2a76d6d80            accessed        2026-05-15 22:47:18.97539
    ## 68: d78b46a2a76d6d80             inCloud                            FALSE
    ## 69: d78b46a2a76d6d80   elapsedTimeDigest                 0.001249552 secs
    ## 70: d78b46a2a76d6d80           preDigest            .FUN:4f604aa46882b368
    ## 71: d78b46a2a76d6d80           preDigest            mean:152602b8ff81e5bb
    ## 72: d78b46a2a76d6d80           preDigest               n:c5775c3b366fb719
    ## 73: d78b46a2a76d6d80           preDigest              sd:853b1797f54b229c
    ## 74: d78b46a2a76d6d80               class                          numeric
    ## 75: d78b46a2a76d6d80         object.size                              176
    ## 76: d78b46a2a76d6d80            fromDisk                            FALSE
    ## 77: d78b46a2a76d6d80          resultHash
    ## 78: d78b46a2a76d6d80 elapsedTimeFirstRun                0.0008485317 secs
    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:18.967147
    ##  2: 2026-05-15 22:47:18.967147
    ##  3: 2026-05-15 22:47:18.967147
    ##  4: 2026-05-15 22:47:18.967147
    ##  5: 2026-05-15 22:47:18.967147
    ##  6: 2026-05-15 22:47:18.967147
    ##  7: 2026-05-15 22:47:18.967147
    ##  8: 2026-05-15 22:47:18.967147
    ##  9: 2026-05-15 22:47:18.967147
    ## 10: 2026-05-15 22:47:18.967147
    ## 11: 2026-05-15 22:47:18.967147
    ## 12: 2026-05-15 22:47:18.967147
    ## 13: 2026-05-15 22:47:18.967147
    ## 14: 2026-05-15 22:47:18.967147
    ## 15: 2026-05-15 22:47:18.967147
    ## 16: 2026-05-15 22:47:18.967147
    ## 17: 2026-05-15 22:47:18.967147
    ## 18: 2026-05-15 22:47:18.967147
    ## 19: 2026-05-15 22:47:18.955561
    ## 20: 2026-05-15 22:47:18.955561
    ## 21: 2026-05-15 22:47:18.955561
    ## 22: 2026-05-15 22:47:18.955561
    ## 23: 2026-05-15 22:47:18.955561
    ## 24: 2026-05-15 22:47:18.955561
    ## 25: 2026-05-15 22:47:18.955561
    ## 26: 2026-05-15 22:47:18.955561
    ## 27: 2026-05-15 22:47:18.955561
    ## 28: 2026-05-15 22:47:18.955561
    ## 29: 2026-05-15 22:47:18.955561
    ## 30: 2026-05-15 22:47:18.955561
    ## 31: 2026-05-15 22:47:18.955561
    ## 32: 2026-05-15 22:47:18.955561
    ## 33: 2026-05-15 22:47:18.955561
    ## 34: 2026-05-15 22:47:18.955561
    ## 35: 2026-05-15 22:47:18.955561
    ## 36: 2026-05-15 22:47:18.955561
    ## 37: 2026-05-15 22:47:18.937041
    ## 38: 2026-05-15 22:47:18.937041
    ## 39: 2026-05-15 22:47:18.937041
    ## 40: 2026-05-15 22:47:18.937041
    ## 41: 2026-05-15 22:47:18.937041
    ## 42: 2026-05-15 22:47:18.937041
    ## 43: 2026-05-15 22:47:18.937041
    ## 44: 2026-05-15 22:47:18.937041
    ## 45: 2026-05-15 22:47:18.937041
    ## 46: 2026-05-15 22:47:18.937041
    ## 47: 2026-05-15 22:47:18.937041
    ## 48: 2026-05-15 22:47:18.937041
    ## 49: 2026-05-15 22:47:18.937041
    ## 50: 2026-05-15 22:47:18.942659
    ## 51: 2026-05-15 22:47:18.972394
    ## 52: 2026-05-15 22:47:19.003118
    ## 53: 2026-05-15 22:47:19.003118
    ## 54: 2026-05-15 22:47:19.003118
    ## 55: 2026-05-15 22:47:19.003118
    ## 56: 2026-05-15 22:47:19.003118
    ## 57: 2026-05-15 22:47:19.003118
    ## 58: 2026-05-15 22:47:19.003118
    ## 59: 2026-05-15 22:47:19.003118
    ## 60: 2026-05-15 22:47:19.003118
    ## 61: 2026-05-15 22:47:19.003118
    ## 62: 2026-05-15 22:47:19.003118
    ## 63: 2026-05-15 22:47:19.003118
    ## 64: 2026-05-15 22:47:19.003118
    ## 65: 2026-05-15 22:47:19.003118
    ## 66: 2026-05-15 22:47:18.977146
    ## 67: 2026-05-15 22:47:18.977146
    ## 68: 2026-05-15 22:47:18.977146
    ## 69: 2026-05-15 22:47:18.977146
    ## 70: 2026-05-15 22:47:18.977146
    ## 71: 2026-05-15 22:47:18.977146
    ## 72: 2026-05-15 22:47:18.977146
    ## 73: 2026-05-15 22:47:18.977146
    ## 74: 2026-05-15 22:47:18.977146
    ## 75: 2026-05-15 22:47:18.977146
    ## 76: 2026-05-15 22:47:18.977146
    ## 77: 2026-05-15 22:47:18.977146
    ## 78: 2026-05-15 22:47:18.977146
    ##                    createdDate
    ##                         <char>

    clearCache(tmpDir, ask = FALSE)

#### 1.3.1.2 Example 2: using the “accessed” tag

    ranNumsA <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Saved! Cache file: adf21923cd1e50d0.rds; fn: rnorm

    ranNumsB <- runif(4) |> Cache(cachePath = tmpDir, userTags = "objectName:b")

    ## Saved! Cache file: e23cab430872a0ea.rds; fn: runif

    # access it again, from Cache
    Sys.sleep(1)
    ranNumsA <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Object to retrieve (fn: rnorm, adf21923cd1e50d0.rds) ...

    ## Loaded! Cached result from previous rnorm call

    wholeCache <- showCache(tmpDir)

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    # keep only items accessed "recently" (i.e., only objectName:a)
    onlyRecentlyAccessed <- showCache(tmpDir, userTags = max(wholeCache[tagKey == "accessed"]$tagValue))

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    # inverse join with 2 data.tables ... using: a[!b]
    # i.e., return all of wholeCache that was not recently accessed
    #   Note: the two different ways to access -- old way with "artifact" will be deprecated
    toRemove <- unique(wholeCache[!onlyRecentlyAccessed, on = "cacheId"], by = "cacheId")$cacheId
    clearCache(tmpDir, toRemove, ask = FALSE) # remove ones not recently accessed

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    showCache(tmpDir) # still has more recently accessed

    ## Empty data.table (0 rows and 4 cols): cacheId,tagKey,tagValue,createdDate

#### 1.3.1.3 Example 3: using keepCache

`keepCache` does the same as previous example, but more simply.

    ranNumsA <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Saved! Cache file: adf21923cd1e50d0.rds; fn: rnorm

    ranNumsB <- Cache(runif(4)) |> Cache(cachePath = tmpDir, userTags = "objectName:b")

    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.

    ## Saved! Cache file: e23cab430872a0ea.rds; fn: runif

    ## Saved! Cache file: e5b9e9c9fe2613dc.rds; fn: Cache

    # keep only those cached items from the last 24 hours
    oneDay <- 60 * 60 * 24
    keepCache(tmpDir, after = Sys.time() - oneDay, ask = FALSE)

    ## Nothing to remove; keeping all

    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##  1: adf21923cd1e50d0            function                            rnorm
    ##  2: adf21923cd1e50d0          objectName                                a
    ##  3: adf21923cd1e50d0            accessed        2026-05-15 22:47:20.21677
    ##  4: adf21923cd1e50d0             inCloud                            FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest                 0.003528833 secs
    ##  6: adf21923cd1e50d0           preDigest            .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest            mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest               n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest              sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                          numeric
    ## 11: adf21923cd1e50d0         object.size                               80
    ## 12: adf21923cd1e50d0            fromDisk                            FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun                  0.00209856 secs
    ## 15: e5b9e9c9fe2613dc            function                            Cache
    ## 16: e5b9e9c9fe2613dc          objectName                                b
    ## 17: e5b9e9c9fe2613dc            accessed        2026-05-15 22:47:20.22847
    ## 18: e5b9e9c9fe2613dc             inCloud                            FALSE
    ## 19: e5b9e9c9fe2613dc   elapsedTimeDigest                 0.003151417 secs
    ## 20: e5b9e9c9fe2613dc           preDigest             FUN:38646c86c4ff7e88
    ## 21: e5b9e9c9fe2613dc           preDigest cacheSaveFormat:cf2828ea967d53e7
    ## 22: e5b9e9c9fe2613dc           preDigest          dryRun:e9aac936a0e8f6ae
    ## 23: e5b9e9c9fe2613dc           preDigest            .FUN:a844fd4a43c312e6
    ## 24: e5b9e9c9fe2613dc           preDigest  .cacheChaining:71681d621365dfd7
    ## 25: e5b9e9c9fe2613dc           preDigest     .cacheExtra:c85d88fc56f4e042
    ## 26: e5b9e9c9fe2613dc           preDigest   .functionName:c85d88fc56f4e042
    ## 27: e5b9e9c9fe2613dc           preDigest            conn:118387d5d48f757d
    ## 28: e5b9e9c9fe2613dc           preDigest             drv:9ce9a83896bf68a1
    ## 29: e5b9e9c9fe2613dc               class                          numeric
    ## 30: e5b9e9c9fe2613dc         object.size                             1008
    ## 31: e5b9e9c9fe2613dc            fromDisk                            FALSE
    ## 32: e5b9e9c9fe2613dc          resultHash
    ## 33: e5b9e9c9fe2613dc elapsedTimeFirstRun                 0.009959698 secs
    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:20.220585
    ##  2: 2026-05-15 22:47:20.220585
    ##  3: 2026-05-15 22:47:20.220585
    ##  4: 2026-05-15 22:47:20.220585
    ##  5: 2026-05-15 22:47:20.220585
    ##  6: 2026-05-15 22:47:20.220585
    ##  7: 2026-05-15 22:47:20.220585
    ##  8: 2026-05-15 22:47:20.220585
    ##  9: 2026-05-15 22:47:20.220585
    ## 10: 2026-05-15 22:47:20.220585
    ## 11: 2026-05-15 22:47:20.220585
    ## 12: 2026-05-15 22:47:20.220585
    ## 13: 2026-05-15 22:47:20.220585
    ## 14: 2026-05-15 22:47:20.220585
    ## 15: 2026-05-15 22:47:20.239699
    ## 16: 2026-05-15 22:47:20.239699
    ## 17: 2026-05-15 22:47:20.239699
    ## 18: 2026-05-15 22:47:20.239699
    ## 19: 2026-05-15 22:47:20.239699
    ## 20: 2026-05-15 22:47:20.239699
    ## 21: 2026-05-15 22:47:20.239699
    ## 22: 2026-05-15 22:47:20.239699
    ## 23: 2026-05-15 22:47:20.239699
    ## 24: 2026-05-15 22:47:20.239699
    ## 25: 2026-05-15 22:47:20.239699
    ## 26: 2026-05-15 22:47:20.239699
    ## 27: 2026-05-15 22:47:20.239699
    ## 28: 2026-05-15 22:47:20.239699
    ## 29: 2026-05-15 22:47:20.239699
    ## 30: 2026-05-15 22:47:20.239699
    ## 31: 2026-05-15 22:47:20.239699
    ## 32: 2026-05-15 22:47:20.239699
    ## 33: 2026-05-15 22:47:20.239699
    ##                    createdDate
    ##                         <char>

    # Keep all Cache items created with an rnorm() call
    keepCache(tmpDir, userTags = "rnorm", ask = FALSE)

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         a
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:20.21677
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.003528833 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun           0.00209856 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:20.220585
    ##  2: 2026-05-15 22:47:20.220585
    ##  3: 2026-05-15 22:47:20.220585
    ##  4: 2026-05-15 22:47:20.220585
    ##  5: 2026-05-15 22:47:20.220585
    ##  6: 2026-05-15 22:47:20.220585
    ##  7: 2026-05-15 22:47:20.220585
    ##  8: 2026-05-15 22:47:20.220585
    ##  9: 2026-05-15 22:47:20.220585
    ## 10: 2026-05-15 22:47:20.220585
    ## 11: 2026-05-15 22:47:20.220585
    ## 12: 2026-05-15 22:47:20.220585
    ## 13: 2026-05-15 22:47:20.220585
    ## 14: 2026-05-15 22:47:20.220585

    showCache(tmpDir)

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         a
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:20.21677
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.003528833 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun           0.00209856 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:20.220585
    ##  2: 2026-05-15 22:47:20.220585
    ##  3: 2026-05-15 22:47:20.220585
    ##  4: 2026-05-15 22:47:20.220585
    ##  5: 2026-05-15 22:47:20.220585
    ##  6: 2026-05-15 22:47:20.220585
    ##  7: 2026-05-15 22:47:20.220585
    ##  8: 2026-05-15 22:47:20.220585
    ##  9: 2026-05-15 22:47:20.220585
    ## 10: 2026-05-15 22:47:20.220585
    ## 11: 2026-05-15 22:47:20.220585
    ## 12: 2026-05-15 22:47:20.220585
    ## 13: 2026-05-15 22:47:20.220585
    ## 14: 2026-05-15 22:47:20.220585

    # Remove all Cache items that happened within a rnorm() call
    clearCache(tmpDir, userTags = "rnorm", ask = FALSE)

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    showCache(tmpDir) ## empty

    ## Empty data.table (0 rows and 4 cols): cacheId,tagKey,tagValue,createdDate

    # Also, can set a time before caching happens and remove based on this
    #  --> a useful, simple way to control Cache
    ranNumsA <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Saved! Cache file: adf21923cd1e50d0.rds; fn: rnorm

    startTime <- Sys.time()
    Sys.sleep(1)
    ranNumsB <- rnorm(5) |> Cache(cachePath = tmpDir, userTags = "objectName:b")

    ## Saved! Cache file: 438a3028a4570cf9.rds; fn: rnorm

    keepCache(tmpDir, after = startTime, ask = FALSE) # keep only those newer than startTime

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: 438a3028a4570cf9            function                     rnorm
    ##  2: 438a3028a4570cf9          objectName                         b
    ##  3: 438a3028a4570cf9            accessed 2026-05-15 22:47:21.32679
    ##  4: 438a3028a4570cf9             inCloud                     FALSE
    ##  5: 438a3028a4570cf9   elapsedTimeDigest          0.001997471 secs
    ##  6: 438a3028a4570cf9           preDigest     .FUN:4f604aa46882b368
    ##  7: 438a3028a4570cf9           preDigest     mean:c40c00762a0dac94
    ##  8: 438a3028a4570cf9           preDigest        n:a4f076b3db622faf
    ##  9: 438a3028a4570cf9           preDigest       sd:853b1797f54b229c
    ## 10: 438a3028a4570cf9               class                   numeric
    ## 11: 438a3028a4570cf9         object.size                        96
    ## 12: 438a3028a4570cf9            fromDisk                     FALSE
    ## 13: 438a3028a4570cf9          resultHash
    ## 14: 438a3028a4570cf9 elapsedTimeFirstRun          0.001380205 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.329512
    ##  2: 2026-05-15 22:47:21.329512
    ##  3: 2026-05-15 22:47:21.329512
    ##  4: 2026-05-15 22:47:21.329512
    ##  5: 2026-05-15 22:47:21.329512
    ##  6: 2026-05-15 22:47:21.329512
    ##  7: 2026-05-15 22:47:21.329512
    ##  8: 2026-05-15 22:47:21.329512
    ##  9: 2026-05-15 22:47:21.329512
    ## 10: 2026-05-15 22:47:21.329512
    ## 11: 2026-05-15 22:47:21.329512
    ## 12: 2026-05-15 22:47:21.329512
    ## 13: 2026-05-15 22:47:21.329512
    ## 14: 2026-05-15 22:47:21.329512

    clearCache(tmpDir, ask = FALSE)

#### 1.3.1.4 Example 4: searching for multiple objects in the cache

    # default userTags is "and" matching; for "or" matching use |
    ranNumsA <- runif(4) |> Cache(cachePath = tmpDir, userTags = "objectName:a")

    ## Saved! Cache file: e23cab430872a0ea.rds; fn: runif

    ranNumsB <- rnorm(4) |> Cache(cachePath = tmpDir, userTags = "objectName:b")

    ## Saved! Cache file: adf21923cd1e50d0.rds; fn: rnorm

    # show all objects (runif and rnorm in this case)
    showCache(tmpDir)

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         b
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:21.40027
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.001793861 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun          0.001219273 secs
    ## 15: e23cab430872a0ea            function                     runif
    ## 16: e23cab430872a0ea          objectName                         a
    ## 17: e23cab430872a0ea            accessed 2026-05-15 22:47:21.39091
    ## 18: e23cab430872a0ea             inCloud                     FALSE
    ## 19: e23cab430872a0ea   elapsedTimeDigest          0.003344536 secs
    ## 20: e23cab430872a0ea           preDigest     .FUN:881ec847b7161f3c
    ## 21: e23cab430872a0ea           preDigest      max:853b1797f54b229c
    ## 22: e23cab430872a0ea           preDigest      min:c40c00762a0dac94
    ## 23: e23cab430872a0ea           preDigest        n:7eef4eae85fd9229
    ## 24: e23cab430872a0ea               class                   numeric
    ## 25: e23cab430872a0ea         object.size                        80
    ## 26: e23cab430872a0ea            fromDisk                     FALSE
    ## 27: e23cab430872a0ea          resultHash
    ## 28: e23cab430872a0ea elapsedTimeFirstRun           0.00195694 secs
    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.402668
    ##  2: 2026-05-15 22:47:21.402668
    ##  3: 2026-05-15 22:47:21.402668
    ##  4: 2026-05-15 22:47:21.402668
    ##  5: 2026-05-15 22:47:21.402668
    ##  6: 2026-05-15 22:47:21.402668
    ##  7: 2026-05-15 22:47:21.402668
    ##  8: 2026-05-15 22:47:21.402668
    ##  9: 2026-05-15 22:47:21.402668
    ## 10: 2026-05-15 22:47:21.402668
    ## 11: 2026-05-15 22:47:21.402668
    ## 12: 2026-05-15 22:47:21.402668
    ## 13: 2026-05-15 22:47:21.402668
    ## 14: 2026-05-15 22:47:21.402668
    ## 15: 2026-05-15 22:47:21.394489
    ## 16: 2026-05-15 22:47:21.394489
    ## 17: 2026-05-15 22:47:21.394489
    ## 18: 2026-05-15 22:47:21.394489
    ## 19: 2026-05-15 22:47:21.394489
    ## 20: 2026-05-15 22:47:21.394489
    ## 21: 2026-05-15 22:47:21.394489
    ## 22: 2026-05-15 22:47:21.394489
    ## 23: 2026-05-15 22:47:21.394489
    ## 24: 2026-05-15 22:47:21.394489
    ## 25: 2026-05-15 22:47:21.394489
    ## 26: 2026-05-15 22:47:21.394489
    ## 27: 2026-05-15 22:47:21.394489
    ## 28: 2026-05-15 22:47:21.394489
    ##                    createdDate
    ##                         <char>

    # show objects that are both runif and rnorm
    # (i.e., none in this case, because objecs are either or, not both)
    showCache(tmpDir, userTags = c("runif", "rnorm")) ## empty

    ## Cache size:

    ## Total (including Rasters): 0 bytes

    ## Selected objects (not including Rasters): 0 bytes

    ## Empty data.table (0 rows and 4 cols): cacheId,tagKey,tagValue,createdDate

    # show objects that are either runif or rnorm ("or" search)
    showCache(tmpDir, userTags = "runif|rnorm")

    ## Cache size:

    ## Total (including Rasters): 40 bytes

    ## Selected objects (not including Rasters): 40 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         b
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:21.40027
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.001793861 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun          0.001219273 secs
    ## 15: e23cab430872a0ea            function                     runif
    ## 16: e23cab430872a0ea          objectName                         a
    ## 17: e23cab430872a0ea            accessed 2026-05-15 22:47:21.39091
    ## 18: e23cab430872a0ea             inCloud                     FALSE
    ## 19: e23cab430872a0ea   elapsedTimeDigest          0.003344536 secs
    ## 20: e23cab430872a0ea           preDigest     .FUN:881ec847b7161f3c
    ## 21: e23cab430872a0ea           preDigest      max:853b1797f54b229c
    ## 22: e23cab430872a0ea           preDigest      min:c40c00762a0dac94
    ## 23: e23cab430872a0ea           preDigest        n:7eef4eae85fd9229
    ## 24: e23cab430872a0ea               class                   numeric
    ## 25: e23cab430872a0ea         object.size                        80
    ## 26: e23cab430872a0ea            fromDisk                     FALSE
    ## 27: e23cab430872a0ea          resultHash
    ## 28: e23cab430872a0ea elapsedTimeFirstRun           0.00195694 secs
    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.402668
    ##  2: 2026-05-15 22:47:21.402668
    ##  3: 2026-05-15 22:47:21.402668
    ##  4: 2026-05-15 22:47:21.402668
    ##  5: 2026-05-15 22:47:21.402668
    ##  6: 2026-05-15 22:47:21.402668
    ##  7: 2026-05-15 22:47:21.402668
    ##  8: 2026-05-15 22:47:21.402668
    ##  9: 2026-05-15 22:47:21.402668
    ## 10: 2026-05-15 22:47:21.402668
    ## 11: 2026-05-15 22:47:21.402668
    ## 12: 2026-05-15 22:47:21.402668
    ## 13: 2026-05-15 22:47:21.402668
    ## 14: 2026-05-15 22:47:21.402668
    ## 15: 2026-05-15 22:47:21.394489
    ## 16: 2026-05-15 22:47:21.394489
    ## 17: 2026-05-15 22:47:21.394489
    ## 18: 2026-05-15 22:47:21.394489
    ## 19: 2026-05-15 22:47:21.394489
    ## 20: 2026-05-15 22:47:21.394489
    ## 21: 2026-05-15 22:47:21.394489
    ## 22: 2026-05-15 22:47:21.394489
    ## 23: 2026-05-15 22:47:21.394489
    ## 24: 2026-05-15 22:47:21.394489
    ## 25: 2026-05-15 22:47:21.394489
    ## 26: 2026-05-15 22:47:21.394489
    ## 27: 2026-05-15 22:47:21.394489
    ## 28: 2026-05-15 22:47:21.394489
    ##                    createdDate
    ##                         <char>

    # keep only objects that are either runif or rnorm ("or" search)
    keepCache(tmpDir, userTags = "runif|rnorm", ask = FALSE)

    ## Nothing to remove; keeping all

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: adf21923cd1e50d0            function                     rnorm
    ##  2: adf21923cd1e50d0          objectName                         b
    ##  3: adf21923cd1e50d0            accessed 2026-05-15 22:47:21.40027
    ##  4: adf21923cd1e50d0             inCloud                     FALSE
    ##  5: adf21923cd1e50d0   elapsedTimeDigest          0.001793861 secs
    ##  6: adf21923cd1e50d0           preDigest     .FUN:4f604aa46882b368
    ##  7: adf21923cd1e50d0           preDigest     mean:c40c00762a0dac94
    ##  8: adf21923cd1e50d0           preDigest        n:7eef4eae85fd9229
    ##  9: adf21923cd1e50d0           preDigest       sd:853b1797f54b229c
    ## 10: adf21923cd1e50d0               class                   numeric
    ## 11: adf21923cd1e50d0         object.size                        80
    ## 12: adf21923cd1e50d0            fromDisk                     FALSE
    ## 13: adf21923cd1e50d0          resultHash
    ## 14: adf21923cd1e50d0 elapsedTimeFirstRun          0.001219273 secs
    ## 15: e23cab430872a0ea            function                     runif
    ## 16: e23cab430872a0ea          objectName                         a
    ## 17: e23cab430872a0ea            accessed 2026-05-15 22:47:21.39091
    ## 18: e23cab430872a0ea             inCloud                     FALSE
    ## 19: e23cab430872a0ea   elapsedTimeDigest          0.003344536 secs
    ## 20: e23cab430872a0ea           preDigest     .FUN:881ec847b7161f3c
    ## 21: e23cab430872a0ea           preDigest      max:853b1797f54b229c
    ## 22: e23cab430872a0ea           preDigest      min:c40c00762a0dac94
    ## 23: e23cab430872a0ea           preDigest        n:7eef4eae85fd9229
    ## 24: e23cab430872a0ea               class                   numeric
    ## 25: e23cab430872a0ea         object.size                        80
    ## 26: e23cab430872a0ea            fromDisk                     FALSE
    ## 27: e23cab430872a0ea          resultHash
    ## 28: e23cab430872a0ea elapsedTimeFirstRun           0.00195694 secs
    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.402668
    ##  2: 2026-05-15 22:47:21.402668
    ##  3: 2026-05-15 22:47:21.402668
    ##  4: 2026-05-15 22:47:21.402668
    ##  5: 2026-05-15 22:47:21.402668
    ##  6: 2026-05-15 22:47:21.402668
    ##  7: 2026-05-15 22:47:21.402668
    ##  8: 2026-05-15 22:47:21.402668
    ##  9: 2026-05-15 22:47:21.402668
    ## 10: 2026-05-15 22:47:21.402668
    ## 11: 2026-05-15 22:47:21.402668
    ## 12: 2026-05-15 22:47:21.402668
    ## 13: 2026-05-15 22:47:21.402668
    ## 14: 2026-05-15 22:47:21.402668
    ## 15: 2026-05-15 22:47:21.394489
    ## 16: 2026-05-15 22:47:21.394489
    ## 17: 2026-05-15 22:47:21.394489
    ## 18: 2026-05-15 22:47:21.394489
    ## 19: 2026-05-15 22:47:21.394489
    ## 20: 2026-05-15 22:47:21.394489
    ## 21: 2026-05-15 22:47:21.394489
    ## 22: 2026-05-15 22:47:21.394489
    ## 23: 2026-05-15 22:47:21.394489
    ## 24: 2026-05-15 22:47:21.394489
    ## 25: 2026-05-15 22:47:21.394489
    ## 26: 2026-05-15 22:47:21.394489
    ## 27: 2026-05-15 22:47:21.394489
    ## 28: 2026-05-15 22:47:21.394489
    ##                    createdDate
    ##                         <char>

    clearCache(tmpDir, ask = FALSE)

#### 1.3.1.5 Example 5: using caching to speed up rerunning expensive computations

    ras <- terra::rast(terra::ext(0, 5, 0, 5),
      res = 1,
      vals = sample(1:5, replace = TRUE, size = 25),
      crs = "+proj=lcc +lat_1=48 +lat_2=33 +lon_0=-100 +ellps=WGS84"
    )

    rasCRS <- terra::crs(ras)
    # Build an explicit target raster (same CRS, coarser resolution).
    # Avoids the `terra::project(x, char_crs, res = N)` shorthand which
    # recurses internally and forwards an unrecognized `wopt` set on
    # recent terra versions, producing
    # `[write] unknown option(s): xscale,yscale`.
    rasTarget <- terra::rast(terra::ext(ras), crs = rasCRS, resolution = 5)

    # A slow operation, like GIS operation
    notCached <- suppressWarnings(
      # project raster generates warnings when run non-interactively
      terra::project(ras, rasTarget)
    )

    cached <- suppressWarnings(
      # project raster generates warnings when run non-interactively
      # using quote works also
      terra::project(ras, rasTarget) |> Cache(cachePath = tmpDir)
    )

    ## Saved! Cache file: aabe3de853553f5c.rds; fn: project

    # second time is much faster
    reRun <- suppressWarnings(
      # project raster generates warnings when run non-interactively
      terra::project(ras, rasTarget) |> Cache(cachePath = tmpDir)
    )

    ## Object to retrieve (fn: project, aabe3de853553f5c.rds) ...

    ## Loaded! Cached result from previous project call

    # recovered cached version is same as non-cached version
    all.equal(notCached, reRun, check.attributes = FALSE) ## TRUE

    ## [1] "Attributes: < Names: 2 string mismatches >"
    ## [2] "Attributes: < Length mismatch: comparison on first 2 components >"
    ## [3] "Attributes: < Component 1: Modes: character, list >"
    ## [4] "Attributes: < Component 1: names for current but not for target >"
    ## [5] "Attributes: < Component 1: Attributes: < names for target but not for current > >"
    ## [6] "Attributes: < Component 1: Attributes: < Length mismatch: comparison on first 0 components > >"
    ## [7] "Attributes: < Component 1: target is character, current is list >"
    ## [8] "Attributes: < Component 2: 'current' is not an envRefClass >"

### 1.3.2 Nested Caching

Nested caching, which is when Caching of a function occurs inside an outer function, which is itself cached. This is a critical element to working within a reproducible work flow. It is not enough during development to cache flat code chunks, as there will be many levels of “slow” functions. Ideally, at all points in a development cycle, it should be possible to get to any line of code starting from the very initial steps, running through everything up to that point, in less than a few seconds. If the workflow can be kept very fast like this, then there is a guarantee that it will work at any point.

    ##########################
    ## Nested Caching
    # Make 2 functions
    inner <- function(mean) {
      d <- 1
      rnorm(n = 3, mean = mean)
    }
    outer <- function(n) {
      inner(0.1) |> Cache(cachePath = tmpdir2)
    }

    # make 2 different cache paths
    tmpdir1 <- file.path(tempfile(), "first")
    tmpdir2 <- file.path(tempfile(), "second")

    # Run the Cache ... notOlderThan propagates to all 3 Cache calls,
    #   but cachePath is tmpdir1 in top level Cache and all nested
    #   Cache calls, unless individually overridden ... here inner
    #   uses tmpdir2 repository
    outer(n = 2) |> Cache(cachePath = tmpdir1)

    ## Saved! Cache file: a352d42cb0291199.rds; fn: inner

    ## Saved! Cache file: 61564dd5e84ab6d5.rds; fn: outer

    ## [1]  0.2801313 -1.9307119  0.6693429
    ## attr(,".Cache")
    ## attr(,".Cache")$newCache
    ## [1] TRUE
    ##
    ## attr(,"tags")
    ## [1] "cacheId:61564dd5e84ab6d5"
    ## attr(,"callInCache")
    ## [1] ""

    showCache(tmpdir1) # 2 function calls

    ## Cache size:

    ## Total (including Rasters): 252 bytes

    ## Selected objects (not including Rasters): 252 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: 61564dd5e84ab6d5            function                     outer
    ##  2: 61564dd5e84ab6d5            accessed 2026-05-15 22:47:21.68423
    ##  3: 61564dd5e84ab6d5             inCloud                     FALSE
    ##  4: 61564dd5e84ab6d5   elapsedTimeDigest          0.003709078 secs
    ##  5: 61564dd5e84ab6d5           preDigest     .FUN:fd3ff16451bebbef
    ##  6: 61564dd5e84ab6d5           preDigest        n:82dc709f2b91918a
    ##  7: 61564dd5e84ab6d5               class                   numeric
    ##  8: 61564dd5e84ab6d5         object.size                      1008
    ##  9: 61564dd5e84ab6d5            fromDisk                     FALSE
    ## 10: 61564dd5e84ab6d5          resultHash
    ## 11: 61564dd5e84ab6d5 elapsedTimeFirstRun           0.02812433 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.713526
    ##  2: 2026-05-15 22:47:21.713526
    ##  3: 2026-05-15 22:47:21.713526
    ##  4: 2026-05-15 22:47:21.713526
    ##  5: 2026-05-15 22:47:21.713526
    ##  6: 2026-05-15 22:47:21.713526
    ##  7: 2026-05-15 22:47:21.713526
    ##  8: 2026-05-15 22:47:21.713526
    ##  9: 2026-05-15 22:47:21.713526
    ## 10: 2026-05-15 22:47:21.713526
    ## 11: 2026-05-15 22:47:21.713526

    showCache(tmpdir2) # 1 function call

    ## Cache size:

    ## Total (including Rasters): 20 bytes

    ## Selected objects (not including Rasters): 20 bytes

    ##              cacheId              tagKey                  tagValue
    ##               <char>              <char>                    <char>
    ##  1: a352d42cb0291199            function                     inner
    ##  2: a352d42cb0291199       outerFunction                     outer
    ##  3: a352d42cb0291199            accessed 2026-05-15 22:47:21.70622
    ##  4: a352d42cb0291199             inCloud                     FALSE
    ##  5: a352d42cb0291199   elapsedTimeDigest           0.01299953 secs
    ##  6: a352d42cb0291199           preDigest     .FUN:c411a17f70613a02
    ##  7: a352d42cb0291199           preDigest     mean:22413394efd9f6a3
    ##  8: a352d42cb0291199               class                   numeric
    ##  9: a352d42cb0291199         object.size                        80
    ## 10: a352d42cb0291199            fromDisk                     FALSE
    ## 11: a352d42cb0291199          resultHash
    ## 12: a352d42cb0291199 elapsedTimeFirstRun          0.001986265 secs
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.709714
    ##  2: 2026-05-15 22:47:21.709714
    ##  3: 2026-05-15 22:47:21.709714
    ##  4: 2026-05-15 22:47:21.709714
    ##  5: 2026-05-15 22:47:21.709714
    ##  6: 2026-05-15 22:47:21.709714
    ##  7: 2026-05-15 22:47:21.709714
    ##  8: 2026-05-15 22:47:21.709714
    ##  9: 2026-05-15 22:47:21.709714
    ## 10: 2026-05-15 22:47:21.709714
    ## 11: 2026-05-15 22:47:21.709714
    ## 12: 2026-05-15 22:47:21.709714

    # userTags get appended
    # all items have the outer tag propagate, plus inner ones only have inner ones
    clearCache(tmpdir1, ask = FALSE)
    outerTag <- "outerTag"
    innerTag <- "innerTag"
    inner <- function(mean) {
      d <- 1
      rnorm(n = 3, mean = mean) |> Cache(notOlderThan = Sys.time() - 1e5, userTags = innerTag)
    }
    outer <- function(n) {
      inner(0.1) |> Cache()
    }
    aa <- Cache(outer, n = 2) |> Cache(cachePath = tmpdir1, userTags = outerTag)

    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.

    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.
    ## No cachePath supplied and getOption('reproducible.cachePath') is inside a temporary directory;
    ##   this will not persist across R sessions.

    ## Saved! Cache file: a481e2b85f7337f2.rds; fn: rnorm

    ## Saved! Cache file: 9691c7bae9ad6582.rds; fn: inner

    ## Saved! Cache file: 2d26a68d5154433e.rds; fn: outer

    ## Saved! Cache file: a094cae4475c01b3.rds; fn: Cache

    showCache(tmpdir1) # rnorm function has outerTag and innerTag, inner and outer only have outerTag

    ## Cache size:

    ## Total (including Rasters): 252 bytes

    ## Selected objects (not including Rasters): 252 bytes

    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##  1: a094cae4475c01b3            function                            Cache
    ##  2: a094cae4475c01b3            userTags                         outerTag
    ##  3: a094cae4475c01b3            accessed        2026-05-15 22:47:21.75370
    ##  4: a094cae4475c01b3             inCloud                            FALSE
    ##  5: a094cae4475c01b3   elapsedTimeDigest                 0.004555702 secs
    ##  6: a094cae4475c01b3           preDigest             FUN:f4ab56347506d214
    ##  7: a094cae4475c01b3           preDigest cacheSaveFormat:cf2828ea967d53e7
    ##  8: a094cae4475c01b3           preDigest          dryRun:e9aac936a0e8f6ae
    ##  9: a094cae4475c01b3           preDigest            .FUN:a844fd4a43c312e6
    ## 10: a094cae4475c01b3           preDigest  .cacheChaining:71681d621365dfd7
    ## 11: a094cae4475c01b3           preDigest     .cacheExtra:c85d88fc56f4e042
    ## 12: a094cae4475c01b3           preDigest   .functionName:c85d88fc56f4e042
    ## 13: a094cae4475c01b3           preDigest            conn:118387d5d48f757d
    ## 14: a094cae4475c01b3           preDigest             drv:9ce9a83896bf68a1
    ## 15: a094cae4475c01b3           preDigest               n:82dc709f2b91918a
    ## 16: a094cae4475c01b3               class                          numeric
    ## 17: a094cae4475c01b3         object.size                             1008
    ## 18: a094cae4475c01b3            fromDisk                            FALSE
    ## 19: a094cae4475c01b3          resultHash
    ## 20: a094cae4475c01b3 elapsedTimeFirstRun                  0.02816415 secs
    ##              cacheId              tagKey                         tagValue
    ##               <char>              <char>                           <char>
    ##                    createdDate
    ##                         <char>
    ##  1: 2026-05-15 22:47:21.782937
    ##  2: 2026-05-15 22:47:21.782937
    ##  3: 2026-05-15 22:47:21.782937
    ##  4: 2026-05-15 22:47:21.782937
    ##  5: 2026-05-15 22:47:21.782937
    ##  6: 2026-05-15 22:47:21.782937
    ##  7: 2026-05-15 22:47:21.782937
    ##  8: 2026-05-15 22:47:21.782937
    ##  9: 2026-05-15 22:47:21.782937
    ## 10: 2026-05-15 22:47:21.782937
    ## 11: 2026-05-15 22:47:21.782937
    ## 12: 2026-05-15 22:47:21.782937
    ## 13: 2026-05-15 22:47:21.782937
    ## 14: 2026-05-15 22:47:21.782937
    ## 15: 2026-05-15 22:47:21.782937
    ## 16: 2026-05-15 22:47:21.782937
    ## 17: 2026-05-15 22:47:21.782937
    ## 18: 2026-05-15 22:47:21.782937
    ## 19: 2026-05-15 22:47:21.782937
    ## 20: 2026-05-15 22:47:21.782937
    ##                    createdDate
    ##                         <char>

### 1.3.3 cacheId

Sometimes, it is not absolutely desirable to maintain the work flow intact because changes that are irrelevant to the analysis, such as changing messages sent to a user, may be changed, without a desire to rerun functions. The `cacheId` argument is for this. Once a piece of code is run, then the `cacheId` can be manually extracted (it is reported at the end of a Cache call) and manually placed in the code, passed in as, say, `cacheId = "ad184ce64541972b50afd8e7b75f821b"`.

    ### cacheId
    set.seed(1)
    rnorm(1) |> Cache(cachePath = tmpdir1)

    ## Saved! Cache file: ca275879d5116967.rds; fn: rnorm

    ## [1] -0.6264538
    ## attr(,".Cache")
    ## attr(,".Cache")$newCache
    ## [1] TRUE
    ##
    ## attr(,"tags")
    ## [1] "cacheId:ca275879d5116967"
    ## attr(,"callInCache")
    ## [1] ""

    # manually look at output attribute which shows cacheId: 422bae4ed2f770cc
    rnorm(1) |> Cache(cachePath = tmpdir1, cacheId = "422bae4ed2f770cc") # same value

    ## cacheId passed to override automatic digesting; using 422bae4ed2f770cc

    ## Saved! Cache file: 422bae4ed2f770cc.rds; fn: rnorm

    ## [1] 0.1836433
    ## attr(,".Cache")
    ## attr(,".Cache")$newCache
    ## [1] TRUE
    ##
    ## attr(,"tags")
    ## [1] "cacheId:422bae4ed2f770cc"
    ## attr(,"callInCache")
    ## [1] ""

    # override even with different inputs:
    rnorm(2) |> Cache(cachePath = tmpdir1, cacheId = "422bae4ed2f770cc")

    ## cacheId passed to override automatic digesting; using 422bae4ed2f770cc

    ## Object to retrieve (fn: rnorm, 422bae4ed2f770cc.rds) ...

    ## Loaded! Cached result from previous rnorm call

    ## [1] 0.1836433
    ## attr(,".Cache")
    ## attr(,".Cache")$newCache
    ## [1] FALSE
    ##
    ## attr(,"tags")
    ## [1] "cacheId:422bae4ed2f770cc"
    ## attr(,"callInCache")
    ## [1] ""

## 1.4 Working with the Cache manually

Since the cache is simply a `DBI` data table (of an SQLite database by default). In addition, there are several helpers in the `reproducible` package, including `showCache`, `keepCache` and `clearCache` that may be useful. Also, one can access cached items manually (rather than simply rerunning the same `Cache` function again).

    # As of reproducible version 1.0, there is a new backend directly using DBI
    mapHash <- unique(showCache(tmpDir, userTags = "project")$cacheId)

    ## Cache size:

    ## Total (including Rasters): 676 bytes

    ## Selected objects (not including Rasters): 676 bytes

    map <- loadFromCache(mapHash[1], cachePath = tmpDir)

    ## Loaded! Cached result from previous  call

    terra::plot(map)

    ## cleanup
    unlink(dirname(tmpDir), recursive = TRUE)

# 2 Alternative database backends

By default, caching relies on a sqlite database for it’s backend. While this works in many situations, there are some important limitations of using sqlite for caching, including 1) speed; 2) concurrent transactions; 3) sharing database across machines or projects. Fortunately, `Cache` makes use of `DBI` package and thus supports several database backends, including mysql and postgresql.

See https://github.com/PredictiveEcology/SpaDES/wiki/Using-alternate-database-backends-for-Cache for further information on configuring these additional backends.

# 3 Reproducible workflow

In general, we feel that a liberal use of `Cache` will make a re-usable and reproducible work flow. `shiny` apps can be made, taking advantage of `Cache`. Indeed, much of the difficulty in managing data sets and saving them for future use, can be accommodated by caching.