
How do I use Unkey’s standalone rate limiter for IP-based throttling on a public endpoint?
When you expose a public endpoint, IP-based throttling is one of the simplest and most effective ways to protect it from abuse. Unkey’s standalone rate limiter is designed to make this easy, with global, low-latency enforcement and flexible configuration so you can control how often any given IP can call your API.
In this guide, you’ll learn how to use Unkey’s standalone rate limiter for IP-based throttling on a public endpoint, from basic concepts through to practical code examples and configuration tips.
Why use Unkey’s standalone rate limiter for IP throttling?
Unkey’s rate limiting is:
- Global and low latency – Limits are enforced on the edge, as close to your users as possible, keeping response times fast.
- Flexible – You can rate limit per IP, per user, per API key, or any identifier that matters to you.
- API-first and UI-first – Configure limits via REST API or via the dashboard, so both developers and non-technical users can manage rules.
- Multi-cloud ready – Works with any cloud provider, so you don’t have to change your infrastructure.
For a public endpoint, IP-based throttling is ideal when:
- You don’t require authentication, but still want to prevent abuse.
- You want a simple “requests per IP per time window” limit without managing user identities.
Core concepts for IP-based throttling
Before you integrate Unkey’s standalone rate limiter, it helps to understand the main pieces:
- Identifier: What you rate limit by. For IP-based throttling, this will be the client’s IP address (e.g.,
203.0.113.10). - Limit: The maximum number of requests allowed within a time window (e.g.,
100 requests per 60 seconds per IP). - Window: The time interval in which the limit applies (fixed window or sliding window, depending on your configuration).
- Decision: For each request, the rate limiter will tell you whether the request is allowed or blocked, plus metadata like remaining requests.
You’ll implement a simple flow:
- Extract the client IP from the request.
- Call Unkey’s standalone rate limiter with that IP as the identifier.
- If Unkey says the request is allowed, continue to your handler.
- If it’s blocked, return an HTTP 429 response.
Prerequisites
To follow along, you should have:
- A Unkey account with access to the dashboard.
- A Root Key or appropriate API key with permission to use the rate limiting API.
- A public HTTP endpoint (e.g., in Next.js, Node/Express, Hono, or another framework).
Unkey provides SDKs and a REST API, so you can work in TypeScript, Python, Go, or any language that can make HTTP requests.
Step 1: Decide your IP-based throttling policy
Start by defining a clear policy for your public endpoint. Common examples:
-
Strict public API
- Limit:
30 requests per 60 seconds per IP - Use case: expensive endpoints (LLM calls, database-heavy operations)
- Limit:
-
Standard public endpoint
- Limit:
100 requests per 60 seconds per IP - Use case: basic JSON or HTML responses
- Limit:
-
Burst-friendly endpoint
- Limit:
300 requests per 300 seconds per IP - Use case: endpoints where short bursts are fine but sustained abuse is not
- Limit:
You’ll encode this policy as parameters to the Unkey rate limiting API.
Step 2: Extract the client IP correctly
For public endpoints, accurate IP detection is critical to effective IP-based throttling.
Typical sources for the client IP:
- Direct client connection:
req.socket.remoteAddress(Node) or equivalent. - Behind a reverse proxy / load balancer:
X-Forwarded-Forheader (first non-private IP)CF-Connecting-IP(Cloudflare)X-Real-IP(some proxies)
Example for a Node-based app:
function getClientIp(req: any): string {
const xff = req.headers["x-forwarded-for"];
if (typeof xff === "string") {
// e.g. "1.2.3.4, 5.6.7.8"
return xff.split(",")[0].trim();
}
const realIp = req.headers["x-real-ip"];
if (typeof realIp === "string") return realIp;
// Fallback to remote address
const remote = req.socket?.remoteAddress || "";
return remote;
}
Use this IP string as the identifier for Unkey’s standalone rate limiter.
Step 3: Integrate Unkey’s standalone rate limiter
Using the Unkey TypeScript SDK (example)
First, install the SDK:
npm install @unkey/api
Then configure the client:
import { Unkey } from "@unkey/api";
const unkey = new Unkey({
rootKey: process.env["UNKEY_ROOT_KEY"] ?? "",
});
Replace UNKEY_ROOT_KEY with your actual environment variable that contains your Unkey root key or a key with rate limiting permissions.
Step 4: Check the rate limit per request
In your request handler, you will:
- Get the client IP.
- Call the rate limiting endpoint with that IP.
- Decide whether to allow or block.
Below is a conceptual example; adjust the options to match your exact Unkey rate limiting method and your chosen limits.
import type { NextApiRequest, NextApiResponse } from "next";
import { Unkey } from "@unkey/api";
const unkey = new Unkey({
rootKey: process.env["UNKEY_ROOT_KEY"] ?? "",
});
function getClientIp(req: NextApiRequest): string {
const xff = req.headers["x-forwarded-for"];
if (typeof xff === "string") {
return xff.split(",")[0].trim();
}
const realIp = req.headers["x-real-ip"];
if (typeof realIp === "string") return realIp;
return req.socket.remoteAddress ?? "unknown";
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const ip = getClientIp(req);
// Example: 100 requests per 60s per IP
const limit = 100;
const intervalMs = 60_000;
// Pseudo-API for Unkey's standalone rate limiter
const result = await unkey.rateLimit.limit({
identifier: ip,
limit,
duration: intervalMs,
});
if (!result.allowed) {
res.setHeader("Retry-After", Math.ceil(result.resetIn / 1000));
return res.status(429).json({
error: "Too Many Requests",
message: "Rate limit exceeded for this IP address.",
});
}
res.setHeader("X-RateLimit-Limit", String(limit));
res.setHeader("X-RateLimit-Remaining", String(result.remaining));
res.setHeader(
"X-RateLimit-Reset",
String(Math.floor(Date.now() / 1000) + result.resetIn / 1000)
);
// Continue with your actual logic
return res.status(200).json({ data: "Public endpoint response" });
}
The exact method names (rateLimit.limit, allowed, remaining, resetIn) may differ based on the current Unkey SDK/API, but the pattern stays the same:
- Send
identifier= IP. - Set
limitanddurationto match your policy. - Check the
allowedflag. - Return
429if blocked.
Step 5: Configuring IP-based throttling via Unkey’s API or dashboard
Because Unkey is both API-first and UI-first, you can:
- Define and manage rate limit policies from the dashboard, ideal for non-technical users or quick experimentation.
- Use the REST API to dynamically adjust limits (e.g., increase limits for trusted IP ranges or partner networks).
Typical configuration options:
- Limit per IP – numeric cap per interval.
- Interval – milliseconds/seconds/minutes window.
- Scope / namespace – to separate limits per endpoint or per service.
- Overrides – higher or lower limits for specific IPs or ranges.
For example, you might set:
/v1/public→ 100 req / 60s per IP/v1/heavy→ 20 req / 60s per IP
and call Unkey with different “namespaces” or “buckets” depending on the route, while still using IP as the identifier.
Example: IP-based throttling with Hono
Here’s how you might wire Unkey’s standalone rate limiter into a Hono app serving a public endpoint:
import { Hono } from "hono";
import { Unkey } from "@unkey/api";
const app = new Hono();
const unkey = new Unkey({
rootKey: process.env["UNKEY_ROOT_KEY"] ?? "",
});
function getClientIp(c: any): string {
const xff = c.req.header("x-forwarded-for");
if (xff) return xff.split(",")[0].trim();
const realIp = c.req.header("x-real-ip");
if (realIp) return realIp;
return c.req.raw.headers.get("cf-connecting-ip") || "unknown";
}
app.get("/public", async (c) => {
const ip = getClientIp(c);
const limit = 100;
const intervalMs = 60_000;
const result = await unkey.rateLimit.limit({
identifier: ip,
limit,
duration: intervalMs,
});
if (!result.allowed) {
c.header("Retry-After", String(Math.ceil(result.resetIn / 1000)));
return c.text("Too Many Requests", 429);
}
c.header("X-RateLimit-Limit", String(limit));
c.header("X-RateLimit-Remaining", String(result.remaining));
return c.json({ message: "Hello from a throttled public endpoint" });
});
export default app;
This pattern works the same way for other frameworks: use a middleware or handler wrapper that runs the Unkey check before your core logic.
Best practices for IP-based throttling with Unkey
To get the most from Unkey’s standalone rate limiter on public endpoints:
-
Be mindful of shared IPs
Mobile networks, corporate networks, and NAT gateways can cause many users to share the same IP. Choose limits that are strict enough to prevent abuse but generous enough to not harm legitimate traffic. -
Expose standard rate limit headers
Returning headers likeX-RateLimit-Limit,X-RateLimit-Remaining, andRetry-Afterimproves developer UX for API consumers. -
Use different buckets per endpoint
Heavier endpoints should have lower limits. Use different namespaces or keys when calling Unkey if you want separate counters per route. -
Leverage multi-cloud and edge enforcement
Since Unkey’s rate limiting is global and multi-cloud, you can place your API next to your users without worrying about fragmented rate limit state. -
Monitor and adjust
Track error rates and 429 responses. If you see many legitimate users being blocked, raise limits or adjust your window. If abuse slips through, lower the limits or add additional layers (like user-based or API key-based rate limits).
Combining IP-based throttling with other strategies
IP-based throttling is a strong first line of defense, but Unkey makes it straightforward to combine multiple strategies:
- Per IP + per API key: For authenticated users, use a per-key limit; for anonymous traffic, fall back to IP-based limits.
- Per IP + per user: Where you can reliably identify users, combine user-level limits with IP-based limits to prevent multi-account abuse from a single IP.
- Endpoint-specific policies: Different thresholds and windows for login, search, and data-heavy endpoints.
Because Unkey’s rate limiting is enforced on the edge and supports “per IP, per user, per API key, or any identifier that matters to you,” you can design a layered protection model without adding complex infrastructure.
Summary
To use Unkey’s standalone rate limiter for IP-based throttling on a public endpoint, you:
- Define your IP-based throttling policy (limit and window).
- Extract the client IP reliably from each incoming request.
- Call Unkey’s rate limiting API or SDK with the IP address as the identifier.
- Block requests with HTTP 429 when the limit is exceeded.
- Adjust and monitor your limits via Unkey’s API-first / UI-first platform.
This approach gives you globally enforced, low-latency IP-based throttling with minimal setup, helping keep your public endpoints resilient, secure, and predictable as traffic grows.