---
title: "@playstack/rate-limit-prisma"
description: "Postgres and Prisma storage for Playstack rate-limit policies."
tags: ["package","operations","rate-limiting","prisma","free"]
---

{/* package-access:start */}

> **Free.** MIT licensed. Check preview availability before installing. See [package access](/docs/packages#access-policy).

{/* package-access:end */}

`@playstack/rate-limit-prisma` implements the atomic `RateLimitStore` contract in Postgres for applications that prefer their existing relational database over another service.

{/* package-install:start */}

## Install

After confirming [preview access](/docs/packages#access-policy), install the package at your application's shared Playstack version:

```sh
npm install --save-exact @playstack/rate-limit-prisma@0.1.0-beta.1
```

Check the peer requirements below before choosing a runtime or provider.

{/* package-install:end */}

## Compose the store

```ts
import { PrismaRateLimitStore } from '@playstack/rate-limit-prisma'

const store = new PrismaRateLimitStore(prisma)
const limiter = createRateLimiter({ definitions, store, clock, keyHasher, environment })
```

`store.client` is the exact structural Prisma client supplied by the application.

## Atomic behavior

For each consume call, the adapter:

1. Creates missing buckets at full capacity.
2. Locks every row in lexicographic key order to avoid inconsistent lock ordering.
3. Refills and evaluates the complete group using application time.
4. Writes every resulting state in one transaction only when allowed.

A denied group consumes no bucket. Database or response-shape failures become `RateLimitUnavailableError`, allowing the core definition’s explicit open/closed policy to decide behavior.

## Rolling-window store

`PrismaRollingWindowRateLimitStore` implements the separate rolling-expiry/cooldown
policy from `@playstack/rate-limit/rolling-window`. Select the
`rate-limit.rolling-window.prisma` artifact (`playstack-rate-limit-rolling.prisma`)
and migrate it with the application's normal process. It does not reuse
token-bucket rows.

The store serializes first writes, locks subjects in order and reads PostgreSQL
`clock_timestamp()` after locks in one READ COMMITTED transaction. Returned
`evaluatedAtMs` keeps retry headers on the same clock. Configure client statement/
transaction bounds; ambiguous commits do not trigger automatic retry/fallback.

The host schedules `store.cleanupExpired(batchSize)`, default 1,000 and at most
10,000 rows, using database time and SKIP LOCKED. Active hit/cooldown state is
retained. This adds no package-owned timer or worker. Match the raw-query schema/
search path to the generated Prisma model.

The rolling adapter's disposable PostgreSQL evidence uses Prisma 6.12.0 and
PostgreSQL 17.11; it is not qualification of every Prisma driver/version.

## Prisma boundary

Compose the managed `playstack-rate-limit.prisma` artifact with `playstack database sync`, generate the application client, and run application-owned migrations. The structural client contract requires `$transaction`, bucket `createMany`/`update`, and parameterized raw query support.

The adapter does not generate or disconnect clients, select a Prisma runtime, own pools, or run migrations. Use [`@playstack/prisma-runtime`](/docs/packages/foundation/prisma-runtime) when an application explicitly selects among generated clients.

{/* package-reference:start */}

## API entry points and requirements

Reference snapshot: `@playstack/rate-limit-prisma@0.1.0-beta.1`. Import only the entry point your runtime needs. Paths below are relative to the installed package; use **Go to Definition** in your editor to inspect exact parameters, return types and overloads. Do not import the declaration-file paths directly.

| Public entry point | Declaration file |
| --- | --- |
| `@playstack/rate-limit-prisma` | `./dist/index.d.ts` |
| `@playstack/rate-limit-prisma/playstack.artifacts.json` | No TypeScript declaration (asset or metadata export). |
| `@playstack/rate-limit-prisma/package.json` | No TypeScript declaration (asset or metadata export). |

Node.js engine requirement: `>=20`. This is not a claim that every entry point works in browsers or Workers.

### Peer dependencies

This package declares no peer dependencies. Its ordinary dependencies are resolved by the package manager.

For a complete first program, start with [Getting started](/docs/getting-started). For API lookup and partial-example conventions, see [Reading the reference](/docs/packages#reading-the-reference). Provider failures, lifecycle requirements and application responsibilities remain described in the guide above; types alone do not establish production safety.

{/* package-reference:end */}
