1. Compute
  2. Function Tracing

Overview

Function tracing helps you understand where time is spent when a Chalk Compute function runs. Use it to debug slow calls, follow nested function calls, and see which parts of your application are doing work.

After a traced call runs, view it from the function’s Scaling Group page under Remote Call Traces.


Enable tracing

Set tracing=True on a function:

import chalkcompute

@chalkcompute.function(
    cpu="1",
    memory="1Gi",
    tracing=True,
)
def score_transaction(transaction_id: str) -> float:
    return 0.42

Nested calls appear in the same trace when tracing is enabled on each function:

import chalkcompute

@chalkcompute.function(tracing=True)
def fetch_profile(user_id: str) -> dict:
    return {"user_id": user_id, "segment": "active"}


@chalkcompute.function(tracing=True)
def score_user(user_id: str) -> float:
    with chalkcompute.trace("score_user.fetch_profile"):
        profile = fetch_profile(user_id)

    return 0.9 if profile["segment"] == "active" else 0.1


with chalkcompute.trace("demo.score_user"):
    score = score_user("user_123")

In the trace, you can see the outer function, the call to fetch_profile, and the inner function’s execution together. You can also add manual spans, like score_user.fetch_profile, to label important parts of your own code.


Advanced configuration

Manual spans

Use chalkcompute.trace() to label meaningful application work:

with chalkcompute.trace("checkout.score_transaction"):
    score = score_transaction("txn_123")

For a whole caller function, use @chalkcompute.traced:

@chalkcompute.traced("batch.score_transactions")
def run_batch(transaction_ids: list[str]) -> list[float]:
    return [score_transaction(txn_id) for txn_id in transaction_ids]

Manual spans are useful around model calls, retrieval steps, preprocessing, and other code you want to separate in the trace. To see a remote function’s own execution, enable tracing=True or TracingPolicy on that function.

Tracing policies

Use TracingPolicy when you only want to collect a percentage of calls:

@chalkcompute.function(
    tracing=chalkcompute.TracingPolicy(sample_rate=0.25),
)
def recommend(user_id: str) -> list[str]:
    ...

sample_rate must be between 0.0 and 1.0.

ConfigurationBehavior
tracing=TrueCollect traces for every call.
tracing=TracingPolicy(sample_rate=0.25)Collect traces for about 25% of calls.
tracing=TracingPolicy(sample_rate=0.0)Trace this function only when its caller is already traced.
tracing=FalseTurn tracing off for the function.
OmittedUse the default behavior: only continue a caller’s trace if tracing support is already installed in the image.

Once a call is traced, nested function calls stay in the same trace. This keeps multi-function workflows readable.

tracing=True and TracingPolicy(...) automatically install tracing support for functions deployed with @chalkcompute.function or RemoteFunction. If you omit tracing, Chalk does not add those packages for you. The default can still continue an existing trace if your image already includes tracing support, for example because it installs chalkcompute or chalk-remote-call-python[tracing].


Troubleshooting

If you do not see remote function spans:

  • Redeploy the function after changing tracing.
  • Enable tracing on both outer and inner functions to see both functions’ execution in a nested trace.
  • Wrap local tests in chalkcompute.trace() if you want the call to be part of an explicit trace.
  • Make sure you are looking at the called function’s Scaling Group page and a time range that includes the call.