plumber2 async endpoint does not inherit global environment
16:12 09 Apr 2026

When using async = TRUE in plumber2 with the default mirai evaluator, the worker processes do not inherit anything loaded or defined in the global environment of the main R session — this includes database connections, environment variables, loaded libraries, and global objects. Here is a minimal example demonstrating the issue with libraries:

Minimal reproducible example:

library(plumber2)
library(dplyr)

pa <- api() |>
  api_get("/test", handler = function() {
    tryCatch({
      my_data <- tibble(x = 1:5)
      my_data |> dplyr::filter(x > 3)
    }, error = function(e) {
      list(error = conditionMessage(e))
    })
  }, async = TRUE)

mirai::daemons(2)

pa |> api_run(port = 8000, block = FALSE)

Calling the endpoint

curl http://localhost:8000/test

Returns:

{"error":["could not find function \"tibble\""]}

Even though dplyr is loaded in the global environment of the main R session, the mirai worker process does not have access to it.

Expected behavior:

Any setup done before api_run() (loading libraries, sourcing files, creating database connections, reading environment variables, loading ML models) should reasonably be expected to be available to async workers. Having to manually reconstruct the global environment in each worker defeats the purpose of having a built-in async evaluator.

Question:

Is there a built-in way in plumber2 to make the global environment available to async mirai workers, or is a custom evaluator the intended solution?

r asynchronous tidyverse mirai plumber2