From 7b37b58bc7b574e41b2459cd752d7ed7d4b20c35 Mon Sep 17 00:00:00 2001
From: Jiangzhou He <hejiangzhou@gmail.com>
Date: Mon, 4 Aug 2025 09:58:25 -0700
Subject: [PATCH] docs(flow-control): make the documentation for flow control
 more clear

---
 docs/docs/core/flow_def.mdx | 37 ++++++++++++++++++++++++++++---------
 docs/docs/core/settings.mdx |  8 ++++----
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/docs/docs/core/flow_def.mdx b/docs/docs/core/flow_def.mdx
index c32c49a1..db8ea724 100644
--- a/docs/docs/core/flow_def.mdx
+++ b/docs/docs/core/flow_def.mdx
@@ -360,21 +360,40 @@ It will use `Staging__doc_embeddings` as the collection name if the current app
 
 ### Control Processing Concurrency
 
-You can control the concurrency of the processing by setting the following options:
+CocoIndex processes data in parallel to maximize throughput, but unconstrained parallelism can overwhelm your system.
+Processing too many items simultaneously can lead to:
 
-*   `max_inflight_rows`: the maximum number of concurrent inflight requests for the processing.
-*   `max_inflight_bytes`: the maximum number of concurrent inflight bytes for the processing.
+- **Memory exhaustion**: Large datasets loaded concurrently can consume excessive RAM
+- **Resource contention**: Too many parallel operations competing for CPU, disk I/O, or network bandwidth
+- **System instability**: High concurrency can cause timeouts, crashes, or degraded performance
 
-These options can be passed in to the following APIs:
+To prevent these issues, CocoIndex provides concurrency controls that limit how many data items are processed simultaneously.
 
-*   [`FlowBuilder.add_source()`](#import-from-source): The options above control the processing concurrency of multiple rows from a source. New rows will not be loaded in memory if it'll be over the limit.
+#### Concurrency Options
 
-    Besides, global limits on overall processing concurrency of all sources from all flows can be specified by [`GlobalExecutionOptions`](/docs/core/settings#globalexecutionoptions) or corresponding [environment variables](/docs/core/settings#list-of-environment-variables).
-    If both global and per-source limits are specified, both need to be satisfied to admit additional source rows.
+You can control processing concurrency using these options:
 
-*   [`DataSlice.row()`](#for-each-row):  The options above provides a finer-grained control, to limit the processing concurrency of multiple rows within a table at any level.
+*   `max_inflight_rows`: Limits the maximum number of data rows being processed concurrently
+*   `max_inflight_bytes`: Limits the total memory footprint of data being processed concurrently (measured in bytes)
 
-`max_inflight_bytes` only counts the number of bytes already existing in the current row before any further processing.
+When these limits are reached, CocoIndex will pause loading new data until some of the current processing completes, ensuring your system remains stable.
+
+#### Where to Apply Concurrency Controls
+
+These concurrency options can be configured at different levels:
+
+*   **Source level** via [`FlowBuilder.add_source()`](#import-from-source): Controls how many rows from a data source are processed simultaneously. This prevents overwhelming your system when ingesting large datasets.
+
+    You can also set global limits across all sources and flows using [`GlobalExecutionOptions`](/docs/core/settings#globalexecutionoptions) or environment variables [`COCOINDEX_SOURCE_MAX_INFLIGHT_ROWS`](/docs/core/settings#list-of-environment-variables)/[`COCOINDEX_SOURCE_MAX_INFLIGHT_BYTES`](/docs/core/settings#list-of-environment-variables).
+    When both global and per-source limits are specified, both limits are enforced independently - a new row can only be processed if there's available capacity in both the global budget (shared across all sources) and the per-source budget (specific to that source).
+
+*   **Row iteration level** via [`DataSlice.row()`](#for-each-row): Provides fine-grained control over parallel processing within nested data structures, allowing you to tune concurrency at any level of your data hierarchy.
+
+:::note
+
+The `max_inflight_bytes` limit only counts the size of data that already exists in memory before any transformations are applied. It doesn't include the memory used by intermediate processing results.
+
+:::
 
 For example:
 
diff --git a/docs/docs/core/settings.mdx b/docs/docs/core/settings.mdx
index 706cab37..02ec10f3 100644
--- a/docs/docs/core/settings.mdx
+++ b/docs/docs/core/settings.mdx
@@ -109,10 +109,10 @@ If you use the Postgres database hosted by [Supabase](https://supabase.com/), pl
 
 `GlobalExecutionOptions` is used to configure the global execution options shared by all flows. It has the following fields:
 
-*   `source_max_inflight_rows` (type: `int`, optional): The maximum number of concurrent inflight requests for all source operations.
-*   `source_max_inflight_bytes` (type: `int`, optional): The maximum number of concurrent inflight bytes for all source operations.
+*   `source_max_inflight_rows` (type: `int | None`, default: `256`): The maximum number of concurrent inflight rows for all source operations.
+*   `source_max_inflight_bytes` (type: `int | None`, default: `None`): The maximum number of concurrent inflight bytes for all source operations.
 
-See also [flow definition docs](/docs/core/flow_def#control-processing-concurrency) to control processing concurrency on per-source basis.
+See also [flow definition docs](/docs/core/flow_def#control-processing-concurrency) about why it's necessary to control processing concurrency, and how to configure it on per-source basis.
 If both global and per-source limits are specified, both need to be satisfied to admit additional source rows.
 
 ## List of Environment Variables
@@ -125,5 +125,5 @@ This is the list of environment variables, each of which has a corresponding fie
 | `COCOINDEX_DATABASE_URL` | `database.url` | Yes |
 | `COCOINDEX_DATABASE_USER` | `database.user` | No |
 | `COCOINDEX_DATABASE_PASSWORD` | `database.password` | No |
-| `COCOINDEX_SOURCE_MAX_INFLIGHT_ROWS` | `global_execution_options.source_max_inflight_rows` | No |
+| `COCOINDEX_SOURCE_MAX_INFLIGHT_ROWS` | `global_execution_options.source_max_inflight_rows` | No (default: `256`) |
 | `COCOINDEX_SOURCE_MAX_INFLIGHT_BYTES` | `global_execution_options.source_max_inflight_bytes` | No |
