Rasmus Simmelkjær Berntsen
12/08/2025, 9:45 AMMarvin
12/08/2025, 9:45 AMMarvin
12/08/2025, 9:48 AMpersist_result=True on the task/flow.
Example (shared storage across pods):
from datetime import timedelta
from prefect import task, flow
from prefect.tasks import task_input_hash
from prefect.filesystems import RemoteFileSystem
s3_store = RemoteFileSystem(basepath="<s3://my-bucket/prefect-results>") # ensure creds are available
@task(
cache_key_fn=task_input_hash,
cache_expiration=timedelta(days=1),
persist_result=True,
result_storage=s3_store,
)
def expensive(x):
...
@flow
def main(x):
return expensive(x)
Net/net:
- Worker pods do not hold the cache.
- Cache metadata lives in the Prefect API.
- Result bytes live in your configured result storage; use shared storage if you want cache hits across different Kubernetes pods.Rasmus Simmelkjær Berntsen
12/08/2025, 9:49 AMMarvin
12/08/2025, 9:49 AMMarvin
12/08/2025, 9:50 AMcache_expiration.
- Example: cache_expiration=timedelta(days=7) means Prefect will reuse a matching cached result for 7 days.
- If you set cache_expiration=None, the cache does not expire (it will be reused indefinitely) unless you change the cache key, set refresh_cache=True, or the metadata is no longer available (e.g., old run records are purged).
2) Object retention (how long the stored bytes live)
- Prefect does not automatically delete results from your storage.
- Where they live depends on your `result_storage`:
- Pod filesystem: disappears with the pod.
- Shared/PVC or cloud storage (S3/GCS/Azure): persists until you delete it.
- Cleanup is your responsibility. Use lifecycle/retention policies on your storage (e.g., S3 lifecycle rules) to delete old objects after your desired period.
Notes on metadata cleanup:
- The Prefect API stores cache metadata (cache_key + expiration) attached to past task runs. After cache_expiration passes, Prefect will ignore those entries.
- Prefect Cloud may apply workspace data-retention policies that purge old run records, which also removes the metadata needed for cache hits (the objects in your bucket will still remain unless your bucket policy deletes them).
- Self-hosted Server does not automatically purge old run records; you’d manage DB retention yourself.
Typical setup:
- Set cache_expiration to your desired TTL for reuse.
- Set persist_result=True and use shared storage for cross-pod reuse.
- Add a storage lifecycle rule to delete objects older than your TTL (plus a buffer).
Example:
from datetime import timedelta
from prefect import task
@task(
cache_key_fn=lambda ctx, params: f"{params['x']}",
cache_expiration=timedelta(days=7),
persist_result=True,
)
def expensive(x):
...
If you want guidance specific to Prefect Cloud vs self-hosted, let me know which you’re using and I can outline concrete cleanup options.