How Holehe Handles Rate Limiting for Individual Site Modules

Holehe treats rate limiting as a first-class outcome where each site module declares a frequent_rate_limit flag and reports limits via a "rateLimit": True entry in the result dictionary, while the core engine visualizes these with yellow [x] markers without stopping the scan.

Holehe is an open-source email investigation tool by megadose that checks email addresses across hundreds of websites. Unlike tools that crash or hang when services throttle requests, Holehe implements a granular rate limiting system that operates at the individual module level. This architecture allows the tool to continue scanning remaining sites even when specific platforms like BlaBlaCar or Twitter enforce strict request limits.

Per-Module Rate Limiting Architecture

Every site-specific module in Holehe is responsible for self-reporting when it encounters API throttling or connection limits. This decentralized approach ensures that rate limit detection lives alongside the specific logic needed to interpret each service's unique responses, whether that means missing authentication tokens or specific HTTP status codes.

Declaring Rate Limit Frequency with frequent_rate_limit

Each module begins by declaring whether the target service frequently applies rate limits through a boolean flag. In holehe/modules/transport/blablacar.py at line 9, the module sets frequent_rate_limit = True to indicate that BlaBlaCar aggressively throttles requests:


# holehe/modules/transport/blablacar.py

async def blablacar(email, client, out):
    name = "blablacar"
    domain = "blablacar.com"
    method = "register"
    frequent_rate_limit = True  # ← Declares aggressive throttling

This flag serves as metadata that helps users understand which sites are prone to blocking before they even run the scan.

Detecting Rate Limits During Execution

When making HTTP requests, modules wrap network calls in try/except blocks to catch throttling signals. If the service returns a missing token, authentication failure, or specific response pattern indicating rate limiting, the module appends a result dictionary with "rateLimit": True instead of crashing.

In blablacar.py lines 33-35 and 62-67, the module handles token acquisition failures and response validation by explicitly setting the rate limit flag:


# holehe/modules/transport/blablacar.py

try:
    appToken = await client.get(...).text.split(...)[1]
except Exception:
    out.append({
        "name": name,
        "domain": domain,
        "method": method,
        "frequent_rate_limit": frequent_rate_limit,
        "rateLimit": True,  # ← Explicit rate limit report

        "exists": False,
        "emailrecovery": None,
        "phoneNumber": None,
        "others": None})
    return

# Later validation

if "url" in data.keys():
    out.append({
        "name": name,
        "domain": domain,
        "method": method,
        "frequent_rate_limit": frequent_rate_limit,
        "rateLimit": True,  # ← Service signaled throttling

        ...
    })

Centralized Result Processing in holehe/core.py

While detection happens at the module level, the central orchestration logic in holehe/core.py handles aggregation and visualization. The launch_module function and print_result function work together to ensure rate-limited sites are clearly marked without interrupting the overall scan workflow.

The Result Dictionary Contract

Every module communicates with the core engine through a standardized result dictionary containing specific keys. The rateLimit boolean is a required field that differentiates between a successful check, a rate-limited check, and an error state.

Visual Feedback for Blocked Requests

The print_result function in holehe/core.py (lines 22-26) iterates through all results and renders rate-limited entries with a yellow [x] prefix. This provides immediate visual feedback that the site could not be queried due to throttling:


# holehe/core.py – print_result function

for results in data:
    if results["rateLimit"] and not args.onlyused:
        websiteprint = print_color("[x] " + results["domain"], "yellow", args)
        print(websiteprint)

This visualization appears alongside other results, ensuring users understand which sites returned data versus which ones blocked the request.

Distinguishing Rate Limits from Errors

Holehe strictly separates rate limiting from unexpected exceptions to prevent false positives. If a module raises an unhandled exception during execution, the launch_module function (lines 71-75) catches it and records a result with "error": True and "rateLimit": False:


# holehe/core.py – launch_module exception handling

try:
    await module(email, client, out)
except Exception:
    out.append({
        "name": name,
        "domain": data[name],
        "rateLimit": False,  # ← Not a rate limit

        "error": True,       # ← Actual error state

        "exists": False,
        "emailrecovery": None,
        "phoneNumber": None,
        "others": None})

This distinction ensures that network timeouts, parsing errors, or HTML structure changes do not get misclassified as rate limiting, allowing developers to debug module failures separately from throttling issues.

Summary

  • Module-level flags: Each site module declares frequent_rate_limit to indicate throttling susceptibility before making requests.
  • Explicit reporting: Modules detect service-specific throttling signals and report them via "rateLimit": True in the standardized result dictionary.
  • Visual distinction: The core engine displays rate-limited sites with yellow [x] markers in the terminal output.
  • Error isolation: Unexpected exceptions are captured separately with "error": True, preventing confusion between technical failures and intentional service limits.
  • Non-blocking execution: Rate limiting on one module never stops the entire email scan; remaining modules continue executing asynchronously.

Frequently Asked Questions

How does Holehe display rate-limited sites in the output?

Holehe renders rate-limited sites with a yellow [x] marker prefixed to the domain name. The print_result function in holehe/core.py checks the rateLimit boolean in each result dictionary and applies yellow coloring via the print_color utility when the flag is true.

What is the difference between rateLimit and error in Holehe results?

The rateLimit field indicates that the service explicitly blocked the request due to throttling or missing authentication tokens, while the error field indicates an unexpected exception occurred during execution (such as a network timeout or HTML parsing failure). This separation allows users to distinguish between service-imposed limits and potential module bugs.

Can I filter out rate-limited sites when running Holehe?

Yes. The print_result function respects the --only-used flag (accessed via args.onlyused), which suppresses the display of sites where rateLimit is true. This allows users to focus only on confirmed registrations without the visual noise of blocked services.

Why does each module declare its own frequent_rate_limit flag?

The frequent_rate_limit flag serves as documentation and metadata for the specific service being checked. Since each platform implements different throttling policies (some strict, some lenient), declaring this at the module level allows the tool to provide accurate context about which sites are likely to fail due to throttling before the scan even begins.

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 →