Default Concurrency for Username Scanning in user-scanner: How It Works and How to Change It

The default concurrency for username scanning in user-scanner is 60 concurrent requests, defined by the MAX_CONCURRENT_REQUESTS constant in user_scanner/core/orchestrator.py.

This limit controls how many simultaneous HTTP requests the scanner fires against target platforms when hunting for username availability. Understanding this default—and how to override it—is essential for balancing scan speed against rate-limiting risks.


Where the Default Concurrency Is Defined

The user-scanner repository hard-codes its concurrency limit as a module-level constant. In user_scanner/core/orchestrator.py at line 27, you'll find:

MAX_CONCURRENT_REQUESTS = 60

This value is imported and enforced via an asyncio.Semaphore created inside the _run_batch function (lines 90–92). The semaphore wraps the request dispatch loop, ensuring no more than 60 coroutines execute network I/O at any given moment.


# From user_scanner/core/orchestrator.py, ~line 90

semaphore = asyncio.Semaphore(MAX_CONCURRENT_REQUESTS)

Raising this ceiling increases throughput but amplifies the risk of IP bans or HTTP 429 responses from protective platforms.


CLI Usage: Default vs. Custom Concurrency

Running with Default Concurrency (60)

Invoke a standard username scan without flags to use the built-in limit:

python -m user_scanner username johndoe

The orchestrator silently applies MAX_CONCURRENT_REQUESTS = 60 through the semaphore instantiated in _run_batch.

Overriding via --concurrency Flag

The CLI entry point at user_scanner/__main__.py exposes a --concurrency argument that propagates to the orchestrator:


# Reduce concurrency to 30 for stealthier scanning

python -m user_scanner username johndoe --concurrency 30

Internally, this calls set_concurrency(value) before the scan initiates, mutating the global limit used by subsequent semaphore creation.


Programmatic Control in Library Mode

When embedding user-scanner as a library, manipulate concurrency through the public set_concurrency helper before constructing your ScanConfig:

from user_scanner.core.orchestrator import set_concurrency, run_user_category
from user_scanner.core.helpers import ScanConfig
from pathlib import Path

# Elevate concurrency for faster LAN testing

set_concurrency(100)

config = ScanConfig()
results = run_user_category(
    Path("user_scanner/user_scan/social"),
    "target_username",
    config
)

The ScanConfig dataclass (defined in user_scanner/core/helpers.py) carries scan metadata but does not store concurrency—this remains a global orchestrator setting to ensure consistent semaphore behavior across batched requests.


How Concurrency Impacts Scan Behavior

Concurrency Level Use Case Trade-off
60 (default) General reconnaissance Balanced speed and stealth
< 30 Aggressive rate-limited platforms Slower but reduces ban probability
> 100 Local test environments or permissive APIs Maximum throughput; high detection risk

The semaphore architecture in _run_batch means reducing concurrency directly throttles the asyncio.gather pool size, while increases spawn additional connection attempts until the TCP stack or remote server intervenes.



Summary

  • The default concurrency for username scanning is 60 requests, hard-coded as MAX_CONCURRENT_REQUESTS in user_scanner/core/orchestrator.py
  • A semaphore instantiated in _run_batch enforces this limit during async request dispatch
  • Override via --concurrency <int> in CLI mode or set_concurrency(<int>) in library mode
  • Lower values reduce rate-limit triggers; higher values accelerate scans on permissive targets

Frequently Asked Questions

How do I check what concurrency value is currently active?

Import MAX_CONCURRENT_REQUESTS directly from the orchestrator module after any set_concurrency calls:

from user_scanner.core.orchestrator import MAX_CONCURRENT_REQUESTS, set_concurrency
set_concurrency(45)
print(MAX_CONCURRENT_REQUESTS)  # outputs: 45

The constant is updated in-place, so its value reflects the most recent configuration.

Is there a hard maximum concurrency enforced by the code?

No explicit ceiling exists in the source. However, practical limits emerge from OS file descriptor thresholds, platform rate limiting, and Python's asyncio event loop capacity. The test suite in tests/test_orchestrator.py verifies behavior up to reasonable multiples of the default.

Does changing concurrency affect all scan types equally?

Yes. The semaphore in _run_batch is agnostic to platform category (social, gaming, developer sites, etc.). All username scans route through this bottleneck, meaning a single set_concurrency call uniformly throttles or accelerates every request batch.

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 →