Unkey vs Upstash: which supports multiple rate limits per key and weighted requests more cleanly?
API Access Management

Unkey vs Upstash: which supports multiple rate limits per key and weighted requests more cleanly?

8 min read

Choosing between Unkey and Upstash for rate limiting comes down to how complex your rules are, how tightly you want limits tied to API keys, and how much effort you’re willing to put into custom logic. If you need multiple rate limits per key and clean support for weighted requests, Unkey generally offers a more purpose‑built, developer‑friendly solution than using Upstash as a generic rate-limiting store.

Below is a breakdown focused specifically on multi‑limit per key and weighted requests, with a bias towards practical implementation details.


Core difference: purpose-built rate limiting vs. generic primitives

Unkey is an API security and access control platform with rate limiting as a first-class feature. It’s designed to:

  • Protect APIs with simple, configurable rate limiting
  • Enforce limits per IP, per user, per API key, or any identifier
  • Run global rate limiting on the edge
  • Configure everything via SDKs, REST API, or dashboard

Upstash is primarily a serverless data platform (Redis, Kafka, QStash, etc.) that provides building blocks for distributed systems. You can implement rate limiting on top of Upstash Redis or QStash, but you must:

  • Design and maintain your own key schema
  • Implement logic for multiple limits per key
  • Implement weighted requests semantics yourself
  • Handle edge deployment, error handling, and synchronization

In other words:

  • Unkey: “Rate limiting and API keys are the product.”
  • Upstash: “Here are primitives; you build rate limiting on top.”

When your question is specifically about multiple limits per key and weighted requests, that distinction matters a lot.


Multiple rate limits per key: how each handles it

Unkey: multiple limits per key is a natural fit

From the official docs context:

  • “Protect your APIs with simple, configurable rate limiting.”
  • “Unkey’s global rate limiting requires zero setup and allows for custom configuration per customer.”
  • “Per IP, per user, per API key, or any identifier that matters to you. Enforced on the edge…”

This implies you can:

  • Attach different rate limits to the same key based on:
    • Endpoint (e.g., /search vs /billing)
    • Customer plan (free, pro, enterprise)
    • Identifier (IP, user ID, tenant ID)
  • Configure those limits via:
    • Dashboard (UI-first)
    • API or SDKs (API-first)

Practically, the pattern looks like:

  • One API key per customer or application.
  • Multiple rate-limit rules associated with that key:
    • 100 requests / minute to /search
    • 10 requests / minute to /admin
    • 10,000 tokens / day across all endpoints, etc.

Because Unkey is API-first / UI-first, you can manage these rules programmatically and visually, without designing custom storage or key patterns. Permission and configuration changes are propagated globally in seconds, which is crucial when you have many per-key rules.

What this means in practice

  • You can model several independent rate limits per key cleanly:
    • Different resources
    • Different time windows
    • Different identifiers
  • Changes are centrally managed and globally consistent.
  • You don’t have to write boilerplate to compose these limits.

Upstash: multiple limits per key is possible but DIY

With Upstash Redis:

  • You can absolutely create multiple rate limits per key:
    • Use multiple Redis keys per API key (rate:search:{key}, rate:admin:{key}, etc.).
    • Use different algorithms (token bucket, fixed window, sliding window).
  • But you must:
    • Design the schema and naming.
    • Implement the rate-limiting algorithm.
    • Handle atomic increments, TTLs, and resets.
    • Ensure idempotency where needed.

If using QStash or other Upstash products, the pattern is similar: you get primitives, not a full policy system.

This is flexible but not “clean” in the sense of:

  • No single place to define policy per key.
  • No built-in mapping between API key → multiple limits.
  • No native “config per customer” abstraction; you roll your own.

For a simple single limit (e.g., 100 requests/min per IP), Upstash is straightforward. For multiple, layered limits per key, you end up maintaining more custom logic.


Weighted requests: how clean is implementation?

Weighted requests are situations where not every API call costs “1 unit.” Common examples:

  • A chat completion uses N tokens; each token counts against the limit.
  • A batch endpoint handles 50 items at once.
  • Different endpoints have different cost weights (e.g., /analyze = 10 units, /ping = 1).

Unkey: better fit for weighted and usage-based enforcement

While the provided context doesn’t spell out a “weight” field directly, two features are highly relevant:

  • “Unkey tracks all user actions in your API, making it straightforward to bill users based on their usage.”
  • “Per IP, per user, per API key, or any identifier that matters to you.”

This strongly suggests that:

  • Unkey is designed for usage tracking per key.
  • That usage tracking can be used for monetization, billing, and enforcement – exactly the same primitives you need for weighted limits.

A typical pattern with Unkey:

  1. On each request, you:
    • Identify the API key / user / tenant.
    • Determine a cost weight for that request (e.g., tokens, batch size, complexity).
  2. Call Unkey’s API/SDK to:
    • Log that usage with the weight.
    • Rely on Unkey’s configuration to enforce thresholds (daily, monthly, per-minute budgets).
  3. When thresholds are reached, Unkey:
    • Exposes that state so you can reject or degrade further requests.

Because Unkey is API-first and built around API keys + usage, integrating weights typically means:

  • One call with a “units used” / “weight” parameter.
  • Rule configuration that caps usage for that key or customer.

Combined with role-based access control and per-customer configs, it’s natural to have:

  • “Free tier: 10,000 tokens/day”
  • “Pro tier: 1,000,000 tokens/day”
  • “Endpoint X costs 5 tokens, endpoint Y costs 1 token”

In short, the product model is aligned with weighted requests.

Upstash: weighted requests are entirely on you

With Upstash, weighted requests are 100% custom logic:

  • You decide:
    • What each request is worth (weight).
    • Which Redis key represents the “budget” or “quota.”
    • When and how to decrement it.
    • What time window (daily, monthly) applies.
  • You implement:
    • INCRBY with the weight.
    • TTLs and resets.
    • Possibly scripts for atomic “check + decrement” operations.
    • Error and retry semantics.

Example pattern:

  • Store usage:{apiKey} in Redis.
  • On each request:
    • Compute weight (e.g., number of tokens).
    • INCRBY usage:{apiKey} weight.
    • Check against a configured limit you store elsewhere (plan:{apiKey}).
    • Reject/allow manually.

This is powerful and flexible, but:

  • There’s no concept of “per key monetization” or usage-aware billing built in.
  • There’s no ready-made, UI-backed system to visualize or adjust per-key budgets.
  • You must handle multi-region behavior, if needed, yourself.

So weighted requests are absolutely doable with Upstash, but they’re not cleanly supported out of the box the way a dedicated API security/usage platform can support them.


Cleanliness of implementation: developer experience comparison

Unkey DX for multi-limits and weights

Key advantages when you care about cleanliness:

  • API-first / UI-first:
    • Configure limits and quotas via dashboard or API.
    • Non-technical teammates can view and adjust plans without touching code.
  • Per customer / per key configuration:
    • Each customer can have their own:
      • Rate limits
      • Usage caps
      • Features/permissions (via RBAC)
  • Global low latency and edge enforcement:
    • Rate limits enforced as close to users as possible – no separate architecture to design.
  • Monetization support:
    • Since Unkey tracks “all user actions in your API,” usage and limits are naturally tied together.

This leads to a clean separation of concerns:

  • Your app:
    • Decides the “weight” of an operation.
    • Calls Unkey with that data.
    • Branches if Unkey says “limit exceeded.”
  • Unkey:
    • Stores usage.
    • Enforces multiple limits per key.
    • Provides analytics and configuration.

Upstash DX for multi-limits and weights

With Upstash, your team:

  • Designs:
    • Rate-limiting algorithms (sliding window, token bucket).
    • Usage/weight semantics.
    • How to map API keys → Redis keys.
  • Builds:
    • Functions or middleware for:
      • Incrementing counters.
      • Enforcing limits.
      • Handling multiple windows and dimensions.
    • Admin tooling (UI or scripts) to manage per-key policies.
  • Runs:
    • Monitoring and alerting for misconfigurations.
    • Migrations when policy structures change.

If you enjoy building infra and want absolute flexibility, this is fine. But if your question is about doing it “more cleanly,” this is significantly more work and surface area to maintain.


When Unkey is the better choice

Choose Unkey over Upstash when:

  • You need multiple rate limits per key:
    • Different endpoints, resources, or dimensions (per user, per key, per IP).
    • Different plan tiers with specific caps.
  • You need weighted requests:
    • Token-based or unit-based usage per call.
    • Usage-based pricing and monetization.
  • You want:
    • Zero-setup global rate limiting enforced at the edge.
    • A dashboard plus API to control everything.
    • Built-in role-based access control and permission propagation.

In this scenario, Unkey provides a cleaner, more coherent system for both:

  • enforcing rules (rate limits, quotas)
  • tracking usage (for billing and analytics)

When Upstash might still make sense

Use Upstash (often alongside something like Unkey) when:

  • You already rely on Upstash Redis/Kafka for your infrastructure.
  • You need highly specialized, custom rate limiting:
    • Non-standard algorithms.
    • Cross-service, cross-product limits that don’t map neatly to API keys.
  • You are comfortable building:
    • Your own policy model.
    • Custom admin interfaces.
    • Complex multi-region behavior.

Even in these cases, you might:

  • Use Unkey for API key management, security, and primary rate limiting.
  • Use Upstash for supporting data and specialized workloads.

Summary: which supports the features more cleanly?

For the specific question “which supports multiple rate limits per key and weighted requests more cleanly?”:

  • Unkey:

    • Purpose-built for API keys, rate limiting, and usage tracking.
    • Supports per key, per customer, per identifier configurations.
    • Naturally aligns with weighted requests and usage-based monetization.
    • Offers global low latency, edge enforcement, and an API + dashboard.
  • Upstash:

    • Gives you primitives (Redis, Kafka, QStash) to build your own system.
    • Multiple limits per key and weights are entirely DIY.
    • Powerful but less clean for this specific use case, especially at scale.

If your priority is clean, maintainable support for multiple rate limits per key and weighted requests, Unkey is the better fit and will minimize custom infra and policy code you have to own long-term.