Nathan Low
11/17/2025, 8:49 PMNate
11/17/2025, 9:00 PMNathan Low
11/17/2025, 9:08 PMNathan Low
11/20/2025, 3:24 PMNate
11/20/2025, 3:25 PMNate
11/20/2025, 3:26 PMNathan Low
11/20/2025, 3:31 PMNate
11/20/2025, 3:34 PM.result() or .wait() on terminal futures (futures you don't pass to another task / flow or return) or else you're not guaranteeing that those futures are not garbage collected
but it sounds like that might not be what you're running into. ill keep on the lookout for your examplesNathan Low
11/20/2025, 3:58 PMNathan Low
11/20/2025, 5:18 PMNate
11/20/2025, 5:28 PMNathan Low
11/20/2025, 5:29 PMNate
11/20/2025, 6:21 PMNathan Low
11/20/2025, 6:27 PMNate
11/20/2025, 6:29 PMNathan Low
11/20/2025, 6:36 PMNate
11/20/2025, 6:37 PMNate
11/20/2025, 6:38 PMquote it but then we wont check for futures. if you know a df doesn't have futures in it then quoting it should help a lot
@Marvin can you show a concise example on thatMarvin
11/20/2025, 6:38 PMMarvin
11/20/2025, 6:42 PMquote tells Prefect not to recursively inspect/resolve futures inside the value; the task still receives the raw value.
Example with a large DataFrame:
from prefect import flow, task
from prefect.utilities.annotations import quote
import pandas as pd
@task
def summarize(df):
# Receives the raw DataFrame; quote is removed before invocation
return df.shape
@flow
def main():
df = pd.DataFrame({"a": range(5_000_000)})
# If you know there are no futures in df, quote() avoids expensive introspection
return summarize(quote(df))
if __name__ == "__main__":
main()
Same idea for a big payload you don’t want Prefect to walk:
@task
def consume(payload):
# Receives the raw dict; no dependency tracking inside it
return list(payload.keys())
@flow
def run():
big_payload = {"df": pd.DataFrame({"a": range(1_000_000)}), "meta": {"x": 1}}
return consume(quote(big_payload))
Notes:
- Quoted values are not traversed for futures; dependencies inside are not tracked.
- The task gets the unwrapped value (no quote wrapper) at call time.Nathan Low
11/20/2025, 7:12 PMNate
11/20/2025, 7:19 PMNathan Low
11/24/2025, 3:51 PMNathan Low
11/24/2025, 4:00 PMNathan Low
11/24/2025, 4:07 PMNathan Low
11/24/2025, 9:49 PMNathan Low
11/24/2025, 9:50 PMNate
11/24/2025, 10:00 PMpbpaste | uv run --with pandas -Nate
11/24/2025, 10:00 PMNathan Low
11/24/2025, 10:05 PMNate
11/24/2025, 10:06 PMNate
11/24/2025, 10:06 PMNathan Low
11/24/2025, 10:07 PMNathan Low
11/24/2025, 10:08 PMNate
11/24/2025, 10:08 PMid / fk generation issues in the sb
Nate
11/24/2025, 10:09 PMNate
11/24/2025, 10:09 PMNate
11/24/2025, 10:09 PMNathan Low
11/24/2025, 10:12 PMNathan Low
11/24/2025, 10:12 PMNathan Low
11/25/2025, 3:23 PMNate
11/25/2025, 3:24 PMNathan Low
11/25/2025, 3:26 PMNathan Low
11/25/2025, 3:36 PMNate
11/25/2025, 3:38 PMNathan Low
11/25/2025, 3:39 PMNathan Low
11/25/2025, 3:50 PMNate
11/25/2025, 3:51 PMNate
11/25/2025, 3:51 PMNathan Low
11/25/2025, 3:52 PMNate
11/25/2025, 3:52 PMNate
11/25/2025, 3:53 PMNathan Low
11/25/2025, 3:53 PMNathan Low
11/25/2025, 3:59 PMNathan Low
11/25/2025, 4:00 PMNathan Low
11/25/2025, 4:09 PMNate
11/25/2025, 4:10 PM» pbpaste | uv run --with pandas -Nate
11/25/2025, 4:11 PMNathan Low
11/25/2025, 4:13 PMNathan Low
11/25/2025, 4:14 PMNathan Low
11/25/2025, 4:15 PMNate
11/25/2025, 4:16 PMpip ? orNate
11/25/2025, 4:17 PMNathan Low
11/25/2025, 4:17 PMNate
11/25/2025, 4:18 PMNate
11/25/2025, 4:20 PMNathan Low
11/25/2025, 4:23 PMNate
11/25/2025, 4:24 PMpbpaste | docker run -i --rm prefecthq/prefect:3-python3.12 uv run --with pandas -Nate
11/25/2025, 4:24 PMNathan Low
11/25/2025, 4:24 PMNate
11/25/2025, 4:24 PMNathan Low
11/25/2025, 4:24 PMNate
11/25/2025, 4:25 PMNathan Low
11/25/2025, 7:17 PMNathan Low
11/25/2025, 7:17 PMNathan Low
11/25/2025, 7:30 PMNathan Low
11/25/2025, 7:39 PMNathan Low
11/25/2025, 8:04 PMimport time
from prefect import flow, task
@task
def dummy_task(x):
return x
@flow
def test_mapping():
start = time.time()
futures = dummy_task.map(range(100))
map_time = time.time() - start
print(f"Mapping took: {map_time:.2f}s")
start = time.time()
futures.wait()
wait_time = time.time() - start
print(f"Waiting took: {wait_time:.2f}s")
if __name__ == "__main__":
test_mapping()Nate
11/25/2025, 8:05 PMNate
11/25/2025, 8:05 PMNathan Low
11/25/2025, 8:06 PMNathan Low
11/25/2025, 8:06 PMNate
11/25/2025, 8:06 PM--python 3.x.y with uv runNathan Low
11/25/2025, 8:27 PMGet-Clipboard | docker run -i -e PREFECT_API_URL=$env:PREFECT_API_URL -e PREFECT_API_KEY=$env:PREFECT_API_KEY --rm prefecthq/prefect:3-python3.12 uv run --with pandas --with prefect --python 3.13.1 -
Gets me:
Mapping took: 0.22s
Waiting took: 4.01sNathan Low
11/25/2025, 8:34 PMNate
11/25/2025, 8:47 PMNathan Low
11/25/2025, 9:06 PMimport os
# MUST be before any prefect imports
import time
from prefect import flow, task, get_run_logger
@task
def dummy_task(x):
return x
@flow
def test_mapping():
logger = get_run_logger()
start = time.time()
futures = dummy_task.map(range(100))
map_time = time.time() - start
<http://logger.info|logger.info>(f"Mapping took: {map_time:.2f}s")
start = time.time()
futures.wait()
wait_time = time.time() - start
<http://logger.info|logger.info>(f"Waiting took: {wait_time:.2f}s")
<http://logger.info|logger.info>(f"Final Notes:")
<http://logger.info|logger.info>(f"Mapping took: {map_time:.2f}s")
<http://logger.info|logger.info>(f"Waiting took: {wait_time:.2f}s")
if __name__ == "__main__":
test_mapping()
How I'm running it through docker to get to the cloud:
Get-Clipboard | docker run -i -e PREFECT_API_URL=$env:PREFECT_API_URL -e PREFECT_API_KEY=$env:PREFECT_API_KEY -e PREFECT_LOGGING_LEVEL="DEBUG" --rm prefecthq/prefect:3-python3.12 uv run --with pandas --with prefect --python 3.13.1 -
At this point all I'm doing is trying to figure out with claude why the network traffic is different between windows and docker, something about the way tcp is handled apparently.Nathan Low
11/25/2025, 9:07 PMNathan Low
11/26/2025, 2:04 PMNathan Low
11/26/2025, 2:05 PMNathan Low
12/01/2025, 4:48 PMNate
12/01/2025, 4:49 PMNathan Low
12/01/2025, 5:00 PM