Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add perniemann/pnCore --skill pn-rate-limitinggit clone --depth 1 https://github.com/perniemann/pnCoreWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/perniemann/pncore/pn-rate-limiting)<a href="https://agentmods.dev/skills/perniemann/pncore/pn-rate-limiting"><img src="https://agentmods.dev/badge/skills/perniemann/pncore/pn-rate-limiting/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/perniemann/pncore/pn-rate-limiting"><img src="https://agentmods.dev/badge/skills/perniemann/pncore/pn-rate-limiting.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00047 | $0.01483 |
| Opus 5 | $0.00023 | $0.00741 |
| Sonnet 5 | $0.00009 | $0.00297 |
| Haiku 4.5 | $0.00005 | $0.00148 |
Grade A, and why
pn-rate-limiting scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 6d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 173 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Rate limiting
When to use
- Protecting public or authenticated API endpoints from overuse
- Implementing per-user, per-IP, or per-API-key rate limits
- Adding abuse prevention to auth endpoints (login, password reset, OTP)
- Configuring edge-level rate limiting (Vercel, Cloudflare)
- Returning correct
429 Too Many Requestsresponses withRetry-After
Algorithm choice
| Algorithm | Characteristics | Use when |
|---|---|---|
| Fixed window | Simple, burst-friendly at window edges | Low-stakes limits; not recommended for auth |
| Sliding window | Smoother, no edge burst | General API protection |
| Token bucket | Allows short bursts up to bucket capacity | APIs where occasional bursts are acceptable |
| Leaky bucket | Strictly uniform output rate | Rate-shaping queues, not request rejection |
Default recommendation: sliding window for API protection; token bucket for background jobs.
Redis sliding window (ioredis)
import { Redis } from "ioredis";
const redis = new Redis(process.env.REDIS_URL!);
interface RateLimitResult {
allowed: boolean;
remaining: number;
resetAt: number; // Unix ms
}
async function rateLimit(
key: string,
limit: number,
windowMs: number
): Promise<RateLimitResult> {
const now = Date.now();
const windowStart = now - windowMs;
const redisKey = `rl:${key}`;
const pipeline = redis.pipeline();
pipeline.zremrangebyscore(redisKey, 0, windowStart); // remove old entries
pipeline.zadd(redisKey, now, `${now}-${Math.random()}`); // add current request
pipeline.zcard(redisKey); // count in window
pipeline.pexpire(redisKey, windowMs); // auto-expire key
const results = await pipeline.exec();
const count = results?.[2]?.[1] as number ?? 0;
return {
allowed: count <= limit,
remaining: Math.max(0, limit - count),
resetAt: now + windowMs,
};
}
// Middleware (Express)
export async function rateLimitMiddleware(req: Request, res: Response, next: NextFunction) {
const key = `ip:${req.ip}`; // or `user:${req.user?.id}` for authenticated
const result = await rateLimit(key, 100, 60_000); // 100 req / min
res.setHeader("X-RateLimit-Limit", 100);
res.setHeader("X-RateLimit-Remaining", result.remaining);
res.setHeader("X-RateLimit-Reset", Math.ceil(result.resetAt / 1000));
if (!result.allowed) {
res.setHeader("Retry-After", Math.ceil((result.resetAt - Date.now()) / 1000));
return res.status(429).json({ error: "Too many requests", retryAfter: result.resetAt });
}
next();
}
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 6d ago First seen · 173 lines · 47 tokens per session scan A 39ea0be988e6
pn-rate-limiting is a skill published in the GitHub repository perniemann/pnCore (0 stars, last pushed 4d ago), licensed MIT. It adds 47 tokens to every session and 1,483 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.
Other skills, from other repositories
architecture-patterns
Implement proven backend architecture patterns including Clean Architecture, Hexagonal Architecture, and Domain-Driven Design. Use this skill when designing clean architecture for a new microservice, when refactoring a monolith to use bounded contexts, when implementing hexagonal or onion architecture patterns, or…
event-store-design
Design and implement event stores for event-sourced systems. Use when building event sourcing infrastructure, choosing event store technologies, or implementing event persistence patterns.
chat-sdk
Build multi-platform chat bots with Chat SDK (chat npm package). Use when developers want to (1) Build a Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, or WhatsApp bot, (2) Use Chat SDK to handle mentions, direct messages, subscribed threads, reactions, slash commands, cards, modals, files, or AI…
developing-genkit-tooling
Best practices for authoring Genkit tooling, including CLI commands and MCP server tools. Covers naming conventions, architectural patterns, and consistency guidelines.
ax-go-flow
Use when writing Go code with github.com/ax-llm/ax/packages/go for flows, nodes, program graphs, nested programs, dynamic options, caching, and optimizer components.
output-dev-workflow-cost
Calculate and display the cost of an Output SDK workflow execution run. Use when checking LLM token costs, API service costs, or total spend for a specific workflow run.