Blog/tutorials

# How to ratelimit tRPC routes with Unkey

Learn how to use Unkey to ratelimit tRPC routes in your Next.js application.

Written by

Lê Sỹ Cường

Published on

May 17, 2024

Ratelimiting is not just a feature; it's a lifeline for production applications. Without it, you could face a skyrocketing bill. Your server could be pushed to its limits, leaving real users stranded and your application's reputation at stake.

Unkey provides ratelimiting that is distributed globally and can be easily added to any server, ensuring your protection. We will discuss the features of our service, including synchronous and asynchronous protection, identifier overrides, and how our analytical data can help you identify spikes in usage and how it can be used in a tRPC application.

## Prerequisites

To get up and running with the app and follow along, you need:

- A fundamental understanding of Next.js, primarily regarding routes and server-side data loading.
- Basic familiarity with tRPC.
- An application with user authentication implemented. This example uses Auth.js, but you can use any provider you like.
- Access to your `UNKEY_ROOT_KEY`, which you can get by signing up for a free account

In this post, we will use create-t3-app for the demo, so feel free to use that if you want an easy way to use tRPC + Auth.js in a Next.js application.

## Installing the `@unkey/ratelimit` package

Before we start coding, we need to install the `@unkey/ratelimit` package. This package gives you access to Unkey's API with type safety.

    1npm install @unkey/ratelimit

### Updating our env

We need to use the `UNKEY_ROOT_KEY` to run our ratelimiting package, so we must first update the `env.js` file in the `src` directory. Add `UNKEY_ROOT_KEY: z.string()` to the `server` object and `UNKEY_ROOT_KEY: process.env.UNKEY_ROOT_KEY` to the `runtimeEnv` object.

Now that it is updated add your Unkey root key to your .env as `UNKEY_ROOT_KEY` which can be found in the Unkey dashboard under settings Root Keys.

## Adding ratelimiting to a procedure

Now that the package is installed and our `.env` has been updated, we can configure our ratelimiter. Inside the `server/api/routers/post` file, we have a `create` procedure. This procedure allows users to create posts; currently, users can create as many as they like and as quickly as they like.

### Configure our ratelimiter

In this example, we will configure our ratelimiter in the procedure itself. Of course, you can abstract this into a utility file if you prefer. First, we must import `Ratelimit` from the `@unkey/ratelimit` package and `TRPCError` and `env`.

    1import { z } from "zod";
    2
    3import {
    4  createTRPCRouter,
    5  protectedProcedure,
    6  publicProcedure,
    7} from "~/server/api/trpc";
    8import { posts } from "~/server/db/schema";
    9import { env } from "~/env";
    10import { TRPCError } from "@trpc/server";
    11import { Ratelimit } from "@unkey/ratelimit";

To configure the Ratelimiter, we need to pass four things along, the root key, the namespace, the limit, and the duration of our ratelimiting. Inside the mutation, add the following:

    1const unkey = new Ratelimit({
    2  rootKey: env.UNKEY_ROOT_KEY,
    3  namespace: "posts.create",
    4  limit: 3,
    5  duration: "5s",
    6});

The namespace can be anything, but we are using the tRPC route and procedure to make it easier to track in Unkey's analytics. We now have the ability to rate-limit this procedure, allowing only three requests per five seconds.

### Using our ratelimiting

To use the ratelimit, we need an identifier. This can be anything you like, such as a user ID or an IP address. We will be using our user's ID as they are required to be logged in to create a new post. Then, we can call `unkey.limit` with the identifier, and unkey will return a boolean of true or false, which we can use to make a decision.

    1const { success } = await unkey.limit(ctx.session.user.id);

So now we have the boolean we can check if it's false and then throw a TRPCError telling the user they have been ratelimited and stop any more logic running.

    1const { success } = await unkey.limit(ctx.session.user.id);
    2
    3if (!success) {
    4  throw new TRPCError({ code: "TOO_MANY_REQUESTS" });
    5}

At this point, our code is ready to test. Give it a whirl, and try posting multiple times. You will see that the posts won't update anymore after you are rate-limited.

## What about more expensive requests?

Unkey allows you to tell us how expensive a request should be. For example, maybe you have an AI route that costs you a lot more than any other route, so you want to reduce the number of requests that can be used.

    1const { success } = await unkey.limit(ctx.session.user.id, {
    2  cost: 3,
    3});

This request costs three instead of one, giving you extra flexibility around expensive routes.

## Faster response

Although Unkey response times are fast, there are some cases where you are willing to give up some accuracy in favor of quicker response times. You can use our `async` option, which has 98% accuracy, but we don't need to confirm the limit with the origin before returning a decision. You can set this either on the `limit` request or on the configuration itself.

    1const unkey = new Ratelimit({
    2  rootKey: env.UNKEY_ROOT_KEY,
    3  namespace: "posts.create",
    4  limit: 3,
    5  duration: "5s",
    6  async: true,
    7});
    8
    9// or
    10
    11const { success } = await unkey.limit(ctx.session.user.id, {
    12  async: true,
    13});

While this is a small overview of using Unkey's ratelimiting with tRPC, we also offer other features that aren't covered here, including:

- Overrides for specific identifiers
- Metadata
- Resources flagging

You can read more about those features in our documentation on Ratelimiting.

Written by

Lê Sỹ Cường

Published on

May 17, 2024

Contents

- Prerequisites
- Installing the `@unkey/ratelimit` package
- Updating our env
- Adding ratelimiting to a procedure
- Configure our ratelimiter
- Using our ratelimiting
- What about more expensive requests?
- Faster response

Suggested

Vncod — Hành trình định nghĩa lại tiêu chuẩn vận hành Game

Mar 26, 2026

How to ratelimit public pages

Dec 11, 2025

Building a flow editor

Dec 02, 2025

## Sẵn sàng bứt phá doanh thu.
Bắt đầu ngay hôm nay.

Liên hệ với chúng tôi
Server Game

Hỗ trợ cài đặt trọn gói. Cam kết vận hành ổn định 24/7.

We value your privacy
This site uses cookies to improve your browsing experience, analyze site traffic, and show personalized content.