<@ULVA73B9P> Can I set different local result stor...
# ask-marvin
t
@Marvin Can I set different local result storage paths for flows deployed together (i.e. with serve(deployment1, deployment2)? Currently the way I set storage path is through the PREFECT_RESULTS_LOCAL_STORAGE_PATH environment variable but then it's shared between the two workflows.
m
thought for 294.9 seconds
Yes. In Prefect 3.x you can set result storage per flow (and therefore per deployment), even when you serve multiple deployments together. The environment variable
PREFECT_RESULTS_LOCAL_STORAGE_PATH
is a global default. If you want different locations per workflow, set
result_storage
on each flow. This overrides the global default. Option A (recommended) — set result_storage per flow:
Copy code
from prefect import flow, serve
from prefect.filesystems import LocalFileSystem

@flow(name="flow_a", result_storage=LocalFileSystem(basepath="/var/prefect-results/flow_a"))
def flow_a():
    ...

@flow(name="flow_b", result_storage=LocalFileSystem(basepath="/var/prefect-results/flow_b"))
def flow_b():
    ...

if __name__ == "__main__":
    serve(
        flow_a.to_deployment(name="flow-a"),
        flow_b.to_deployment(name="flow-b"),
    )
Tip: You can also pass a plain path string for local storage:
Copy code
@flow(result_storage="/var/prefect-results/flow_a")
def flow_a():
    ...
Option B — set the env var per deployment via job variables:
Copy code
d1 = flow_a.to_deployment(
    name="flow-a",
    job_variables={"env": {"PREFECT_RESULTS_LOCAL_STORAGE_PATH": "/var/prefect-results/flow_a"}}
)
d2 = flow_b.to_deployment(
    name="flow-b",
    job_variables={"env": {"PREFECT_RESULTS_LOCAL_STORAGE_PATH": "/var/prefect-results/flow_b"}}
)

serve(d1, d2)
If both are set, the explicit
result_storage
on the flow takes precedence over the env default. References: - Results and result storage (Prefect 3) - Settings reference - Customize job variables (per-deployment env) - LocalFileSystem source - Result storage resolution
t
@Marvin When setting result_storage to LocaFileSystem(basepath=my_path) I get the following error:
Copy code
TypeError: Result storage configuration must be persisted server-side. Please call `.save()` on your block before passing it in.
When using a plain string, I have the following error:
Copy code
ValueError: Unable to find block document named my_path for block type
m
thought for 270.3 seconds
Thanks for the details — this behavior makes sense in Prefect 3.x. What’s happening: - When you pass
LocalFileSystem(basepath=my_path)
directly, Prefect requires that block to be saved server-side so it can be referenced in future runs/deployments. That’s why you see: “Result storage configuration must be persisted server-side. Please call `.save()`…” - When you pass a plain string like
"my_path"
, Prefect interprets strings as references to saved blocks (not file paths). Since there’s no saved block with that name, you see: “Unable to find block document named my_path…”. How to fix it (choose one of these): 1) Save a LocalFileSystem block, then reference it - Save once (e.g., in a setup script or a notebook):
Copy code
from prefect.filesystems import LocalFileSystem

fs = LocalFileSystem(basepath="/absolute/path/for/results")
fs.save("my-results", overwrite=True)  # creates a saved block named "my-results"
- Option A: Reference the saved block by slug in your flow (recommended and most portable):
Copy code
from prefect import flow

@flow(result_storage="local-file-system/my-results")
def my_flow():
    ...
- Option B: Load the saved block and pass the block object:
Copy code
from prefect import flow
from prefect.filesystems import LocalFileSystem

@flow(result_storage=LocalFileSystem.load("my-results"))
def my_flow():
    ...
2) Pass a Path object (not a string) If you just want a local path without creating a saved block, pass a
pathlib.Path
object. Prefect will automatically wrap it in a
LocalFileSystem
under the hood:
Copy code
from pathlib import Path
from prefect import flow

@flow(result_storage=Path("/absolute/path/for/results"))
def my_flow():
    ...
Note: A plain string like "/tmp/results" will be treated as a block reference and fail; use
Path("/tmp/results")
instead. Where to set this: - Set
result_storage
on the
@flow
and/or
@task
decorators. This configuration is included in deployments. There is no
result_storage
parameter on
flow.deploy(...)
in 3.x. A few extra notes: - If you set
result_storage
, Prefect will enable
persist_result=True
automatically unless you override it. - Double-check the class name: it’s
LocalFileSystem
(not
LocaFileSystem
). - Docs for reference: - Results (Prefect 3.x) - Blocks overview - LocalFileSystem API If you can share how you’re applying
result_storage
today (decorator vs. elsewhere) and your exact
my_path
value, I can tailor the snippet to your setup.
t
@Marvin When using Path, I still get the
TypeError: Result storage configuration must be persisted server-side. Please call
.save()` on your block before passing it in.` error. Thanks, I'll ask the community.
m
thought for 199.3 seconds
You’re right to flag this — using a Path for
result_storage
should work in Prefect 3.x, but there’s a known issue in some 3.x releases (e.g., 3.0.10) where passing a
pathlib.Path
still triggers the “persisted server-side” error. Reference: Issue #15794. Workarounds that will unblock you today: - Save a LocalFileSystem block and reference it by slug (most reliable)
Copy code
from prefect.filesystems import LocalFileSystem

fs = LocalFileSystem(basepath="/absolute/path/for/results")
fs.save("my-results", overwrite=True)  # saves a block named "my-results"
Then in your flow:
Copy code
from prefect import flow

@flow(result_storage="local-file-system/my-results")
def my_flow():
    ...
Or:
Copy code
from prefect import flow
from prefect.filesystems import LocalFileSystem

@flow(result_storage=LocalFileSystem.load("my-results"))
def my_flow():
    ...
- If you prefer Path and are hitting the bug, try upgrading to the latest 3.x; if the issue persists in your version, stick with the saved-block approach above. Notes: - Strings like
"my_path"
are interpreted as block slugs, not filesystem paths — hence the “Unable to find block document named my_path” error. -
result_storage
belongs on the `@flow`/`@task` decorator; it’s not a parameter to
flow.deploy(...)
. - If your deployment runs remotely, make sure the path you set is accessible in that runtime. If you share your Prefect version and how you’re setting
result_storage
(decorator vs
with_options
), I can confirm whether you’re on an affected release and suggest the smallest change. If you’d rather take it to the community, totally fine — linking the issue above will provide helpful context.