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.
Related Source Files
user_scanner/core/orchestrator.py— Core engine; definesMAX_CONCURRENT_REQUESTSand_run_batchsemaphore logicuser_scanner/__main__.py— CLI parser handling--concurrencydelegationuser_scanner/core/helpers.py—ScanConfigdataclass for scan parameterizationtests/test_orchestrator.py— Unit tests validatingset_concurrencymutation behavior
Summary
- The default concurrency for username scanning is 60 requests, hard-coded as
MAX_CONCURRENT_REQUESTSinuser_scanner/core/orchestrator.py - A semaphore instantiated in
_run_batchenforces this limit during async request dispatch - Override via
--concurrency <int>in CLI mode orset_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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →