How `subagent_concurrency` Controls Parallel Task Execution in DeepSeek-Reasonix

The subagent_concurrency setting caps simultaneous sub-agent execution at 32 (default 6), preventing deadlocks by rejecting new spawns once the session-wide slot limit is reached.

The subagent_concurrency parameter in the DeepSeek-Reasonix repository governs how many isolated child agents can operate simultaneously within a single session. When skills such as explore, research, review, or security_review are marked with runAs=subagent, the system spawns isolated child loops that consume concurrency slots. Configured via agent.max_subagent_concurrency in TOML, this mechanism prevents resource exhaustion and parent-child deadlocks by enforcing strict limits on parallel sub-agent processes.

What Is subagent_concurrency?

subagent_concurrency exposes a session-wide semaphore that controls the maximum number of sub-agents permitted to run at once. In the codebase, this value is represented by agent.max_subagent_concurrency and is enforced by the session's write-scheduler. Each time a skill triggers a sub-agent spawn, the scheduler attempts to allocate a slot from the available pool.

How Parallel Execution Is Controlled

The concurrency mechanism operates through slot tracking and fast-fail validation.

Slot Allocation and Write Scheduling

When Reasonix spawns a sub-agent, the write-scheduler hands out a sub-agent concurrency slot to the child process. The scheduler maintains two critical counters: the total number of active sub-agents and the subset allowed to perform write-capable actions (parallel writers). According to internal/agent/scheduler.go, the system checks these counters before permitting any new sub-agent to initialize.

Deadlock Prevention

The primary architectural goal is avoiding scenarios where a parent sub-agent waits indefinitely for a child that cannot be created. If the number of active sub-agents reaches the configured max_subagent_concurrency, the scheduler aborts the spawn immediately with the error: "subagent concurrency limit reached (%d); nested subagents fail fast to avoid parent/child slot deadlock". This fail-fast approach prevents circular dependencies where nested sub-agents would otherwise block on unavailable slots.

Configuration Limits and Defaults

The limits are defined in internal/agent/write_claims.go:

  • Default: DefaultMaxSubagentConcurrency = 6 (line 13) — the out-of-the-box concurrency cap used when no custom value is specified.
  • Hard ceiling: MaxSubagentConcurrencyLimit = 32 (line 20) — any user-provided value exceeding 32 is clamped to this maximum.

The helper function NormalizeConcurrencyLimits(total, writers int) (lines 39–44) enforces these bounds, ensuring both total sub-agent slots and parallel-writer slots remain within the valid range of [1, 32].

Configuring subagent_concurrency

You can adjust the limit via TOML configuration or programmatically at runtime.

TOML Configuration (default 6, maximum 32):


# reasonix.example.toml

[agent]
max_subagent_concurrency = 6   # session-wide sub-agent concurrency for tasks/fleet/skills

Runtime Configuration via Desktop UI:

// desktop/settings_app.go
func (a *App) SetMaxSubagentConcurrency(n int) error {
    total, _ := agent.NormalizeConcurrencyLimits(n, 0)
    a.cfg.Agent.MaxSubagentConcurrency = total
    // propagate to scheduler …
    return nil
}

Handling Concurrency Limit Errors

When the scheduler detects that currentSubagents >= maxTotal, it returns an error immediately rather than queuing the request. As implemented in internal/agent/scheduler.go (lines 49–98), this prevents the session from entering an unstable state:

// internal/agent/scheduler.go
if currentSubagents >= maxTotal {
    return noop, fmt.Errorf(
        "subagent concurrency limit reached (%d); nested subagents fail fast to avoid parent/child slot deadlock",
        maxTotal)
}

This error surface allows calling code to handle saturation gracefully, whether by retrying with backoff or escalating to the user.

Summary

  • subagent_concurrency controls how many sub-agents can run simultaneously in a single DeepSeek-Reasonix session.
  • Default limit is 6 (DefaultMaxSubagentConcurrency), with a hard ceiling of 32 (MaxSubagentConcurrencyLimit).
  • The write-scheduler allocates slots and rejects new sub-agents once the limit is reached to prevent deadlocks.
  • Configuration occurs via agent.max_subagent_concurrency in TOML or through the NormalizeConcurrencyLimits helper for runtime changes.

Frequently Asked Questions

What happens if I set max_subagent_concurrency higher than 32?

The value is automatically clamped to 32. The NormalizeConcurrencyLimits function in internal/agent/write_claims.go enforces this hard ceiling regardless of the input value, ensuring the system never allocates more than 32 concurrent sub-agent slots.

Why does DeepSeek-Reasonix use a fail-fast error instead of queuing excess sub-agents?

Fail-fast behavior prevents parent-child deadlocks. If a parent sub-agent waited for a child to spawn while all slots were occupied, the parent would hang indefinitely. By returning an error immediately when the limit is reached, the scheduler forces the caller to handle saturation explicitly rather than risking circular wait conditions.

Which skills trigger sub-agent creation and consume concurrency slots?

Skills marked with runAs=subagent spawn isolated child loops that consume slots. Common examples include explore, research, review, and security_review. Each invocation of these skills requests a slot from the session's write-scheduler before execution begins.

Can I change the concurrency limit without restarting the Reasonix session?

Yes. The desktop/settings_app.go implementation demonstrates runtime adjustment via SetMaxSubagentConcurrency, which calls NormalizeConcurrencyLimits to validate the new value before applying it to the active scheduler configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →