# How Holehe Handles Rate Limiting for Individual Site Modules

> Discover how Holehe handles rate limiting for individual site modules by marking limits and visualizing them without interrupting scans. Learn more about this essential security feature.

- Repository: [Palenath/holehe](https://github.com/megadose/holehe)
- Tags: internals
- Published: 2026-09-09

---

**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`](https://github.com/megadose/holehe/blob/main/holehe/modules/transport/blablacar.py) at line 9, the module sets `frequent_rate_limit = True` to indicate that BlaBlaCar aggressively throttles requests:

```python

# 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`](https://github.com/megadose/holehe/blob/main/blablacar.py) lines 33-35 and 62-67, the module handles token acquisition failures and response validation by explicitly setting the rate limit flag:

```python

# 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`](https://github.com/megadose/holehe/blob/main/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`](https://github.com/megadose/holehe/blob/main/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:

```python

# 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`:

```python

# 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`](https://github.com/megadose/holehe/blob/main/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.