Per-fingerprint rate limiting applies limits based on a unique device/browser fingerprint. It provides more granular and robust identification than traditional methods like IP address or User-Agent.

Description

The per_fingerprint limiter enforces request quotas using a device/browser fingerprint derived from multiple attributes. It is especially useful for anonymous traffic where no stable user ID is available.

Key Features

  • Unique identification: Combines UserID, token, IP, and User-Agent into a single identifier
  • Evasion resistance: Harder to bypass than IP-only limits
  • Granularity: Enables device/browser-specific limits
  • Integration: Works with the existing fingerprinting middleware

Configuration

{
  "name": "rate_limiter",
  "enabled": true,
  "stage": "pre_request",
  "priority": 1,
  "settings": {
    "limits": {
      "per_fingerprint": {
        "limit": 10,
        "window": "1m"
      },
      "per_ip": {
        "limit": 50,
        "window": "1m"
      },
      "per_user": {
        "limit": 100,
        "window": "1m"
      },
      "global": {
        "limit": 1000,
        "window": "1m"
      }
    },
    "actions": {
      "type": "reject",
      "retry_after": "60"
    }
  }
}

Evaluation Order

Limits are checked in the following order (from most specific to most general):
  1. per_fingerprint: Unique fingerprint limit
  2. per_ip: Client IP address limit
  3. per_user: Authenticated user limit
  4. global: Global limit

Requirements

  • Fingerprinting middleware is enabled
  • The fingerprint is generated automatically per request
  • Compatible with all existing rate limiting types

Use Cases

Abuse protection

{
  "per_fingerprint": {
    "limit": 5,
    "window": "1m"
  }
}

Graduated limits

{
  "per_fingerprint": {
    "limit": 10,
    "window": "1m"
  },
  "per_ip": {
    "limit": 50,
    "window": "1m"
  },
  "global": {
    "limit": 1000,
    "window": "1m"
  }
}

Anonymous users

For unauthenticated users, per_fingerprint offers a more robust alternative to per_user:
{
  "per_fingerprint": {
    "limit": 20,
    "window": "1h"
  },
  "per_user": {
    "limit": 100,
    "window": "1h"
  }
}

Considerations

  • Dependency: Requires the fingerprinting middleware to be configured
  • Performance: Fingerprints are base64 strings; impact is minimal
  • Fallback: If no fingerprint is available, “unknown” is used as the key
  • Compatibility: Works alongside all other rate limiting types