# Runtime Cost Monitoring

Level: Advanced

## Goal

Use runtime cost data to identify expensive graph chains, decide whether a cost is caused by frequency or work size, and choose the smallest useful optimization.

## Symptoms

| Symptom                                    | First place to look                                            |
| ------------------------------------------ | -------------------------------------------------------------- |
| A frame stutters when a graph event fires. | Chain sample list and recent history spike.                    |
| A graph feels delayed.                     | Queued chains or high Trigger frequency.                       |
| Cost rises while the scene is idle.        | Repeating Triggers, timers, services, or polling logic.        |
| A fix does not improve performance.        | Wrong process selected or low-frequency chain optimized first. |
| Cost appears inconsistent.                 | Bursty events, async waits, or Debug Context mismatch.         |

## Likely Causes

* A Trigger fires every frame or more often than the design needs.
* `Queue` preserves too many chains under load.
* A long chain performs optional work every time it runs.
* A BT or GOAP branch reevaluates expensive checks too frequently.
* Custom Instructions allocate per execution.
* Blackboard list shape changes force cache refreshes more often than expected.
* The profiler is looking at a different `FlowCoreProcess` than the one causing the visible issue.

## Checks

1. Open the process profiler.
   * Enter Play Mode.
   * Select the GameObject with the relevant `FlowCoreProcess`.
   * Use the process Inspector to open the profiler.
   * Set Debug Context to the same GameObject.
2. Identify the expensive chain.
   * Use frame cost to see whether the process is expensive on the current frame.
   * Use the chain sample list to find the Entry or Trigger with the highest cost.
   * Use history to distinguish one-time spikes from repeated cost.
3. Classify the cost.
   * Frequency cost: the chain is small but runs too often.
   * Work-size cost: the chain runs rarely but does too much in one pass.
   * Queue cost: the chain runs late because prior executions are still waiting.
   * Allocation cost: custom logic or data churn creates garbage collection pressure.
4. Connect cost to graph structure.
   * Open the graph with the same Debug Context.
   * Follow the expensive Entry or Trigger.
   * Check Guards and Invoke Mode.
   * Look for repeated Blackboard list mutations, expensive custom Instructions, or broad module updates.

## Fixes

* Reduce Trigger frequency when every event does not need a full chain.
* Use `Bypass` for non-critical repeated updates where latest state matters more than processing every request.
* Keep `Queue` for ordered sequences that must preserve every request.
* Split a long chain when separate phases can run on different events.
* Move expensive checks behind Guards so they run only when needed.
* Cache project-side data in custom Instructions instead of allocating per execution.
* Batch Blackboard list mutations and rebuild once.
* Profile again after each change so the next bottleneck is based on evidence.

## Common Traps

* Optimizing the most visible graph instead of the graph with the measured cost.
* Treating one spike as a sustained performance problem.
* Switching away from `Queue` when the design actually requires ordered execution.
* Reading profiler results with the wrong Debug Context selected.
* Ignoring custom extension code because the chain is visually small.

## Related

* [Performance and Failure Modes](/flow-core-docs/documentation/troubleshooting/performance-and-failure-modes.md)
* [Design Levers](/flow-core-docs/documentation/core-concepts/design-levers.md)
* [Invoke and Reject Modes](/flow-core-docs/documentation/reference/invoke-and-reject-modes.md)
* [Lifecycle and Dataflow](/flow-core-docs/documentation/runtime-guide/lifecycle-and-dataflow.md)
* [FlowCore Settings](/flow-core-docs/documentation/reference/flow-core-settings.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://flow-core.gitbook.io/flow-core-docs/documentation/troubleshooting/runtime-cost-monitoring.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
