Skip to content
(772) 200-4907
damore .ai
Menu
All articles

Token Usage Tracking & Rate Limiting for Open WebUI

A group-based token usage tracking and rate limiting filter for Open WebUI with PostgreSQL persistence, automatic schema creation, and zero PII storage.

Beau D'Amore 5 min read
beaudamore/openwebui-usage-tracking-filterView the source on GitHub

Know Exactly Where Your Tokens Go

When you’re running an Open WebUI instance for a team, a community, or a client-facing product, one question comes up fast: who’s using how many tokens, and how do you set limits?

Open WebUI doesn’t ship with built-in per-user token quotas. That means without a solution in place, a single user can burn through your entire API budget in an afternoon. The Usage Tracking Filter solves this by adding group-based token limits, real-time usage visibility, and graceful blocking — all backed by PostgreSQL and with zero PII stored.


How It Works

The filter hooks into Open WebUI’s inlet/outlet pipeline — the same mechanism used by safety filters and memory systems. Every request passes through two stages:

Inlet: Check Before Processing

Before the LLM ever sees a message, the inlet checks the user’s current token usage against their group’s limits. If they’re over their daily or monthly quota, the request is blocked with a friendly message explaining what happened and when their limit resets.

If they’re approaching their limit (configurable, default 80%), a warning is displayed but the request still goes through.

Outlet: Record After Response

After the LLM responds, the outlet extracts token counts from the response and records them to PostgreSQL. It also checks whether the user has now crossed a threshold and appends a usage warning directly to the chat response if needed.

This two-stage approach means usage checks are fast (a single database call before processing) and recording is non-blocking (happens after the user already has their response).


Group-Based Tiers

Instead of setting limits per user, the filter uses a group-based model. Users are assigned to a group, and each group defines its own daily and monthly token limits:

GroupDaily LimitMonthly Limit
Freemium50,000 tokens1,000,000 tokens
Pro500,000 tokens10,000,000 tokens
EnterpriseUnlimitedUnlimited

These are the defaults — you can customize them or add entirely new tiers by updating a single row in the usage_limits table. Moving a user between tiers is one SQL statement:

INSERT INTO user_groups (user_id, group_name, assigned_by)
VALUES ('user-uuid-here', 'pro', 'admin')
ON CONFLICT (user_id) DO UPDATE SET 
  group_name = EXCLUDED.group_name,
  assigned_at = NOW();

Users who haven’t been explicitly assigned default to the freemium tier automatically.


Auto-Schema Creation

One of the smoothest parts of this filter: you don’t need to run any SQL manually. On first request, the filter detects that the required tables don’t exist and creates the entire schema automatically — tables, indexes, views, and helper functions.

If you’re already running PostgreSQL for another filter (like the LangGraph Memory Filter), just point this filter at the same database. The schemas are independent and won’t conflict.


What Gets Stored

Privacy was a core design constraint. The filter stores only:

  • User UUIDs — the opaque identifiers Open WebUI assigns internally. No emails, names, or any other personal information.
  • Token counts — prompt tokens, completion tokens, and totals per request.
  • Metadata — model ID, chat ID, and timestamps.

No conversation content is ever logged or persisted. The database contains nothing that could identify a real person without access to Open WebUI’s own user database.


Built-In Analytics

The schema includes several PostgreSQL views for querying usage patterns without writing complex SQL:

  • usage_daily — Token totals per user per day
  • usage_monthly — Token totals per user per month
  • usage_summary — Current daily and monthly usage with percentage calculations
  • users_near_limit — All users currently above 80% of any limit

Check a specific user’s status:

SELECT * FROM usage_summary WHERE user_id = 'user-uuid-here';

See everyone approaching their limits:

SELECT * FROM users_near_limit;

A cleanup function is also included to purge records older than a configurable retention period (default 90 days):

SELECT cleanup_old_usage_records(90);

User Experience

The filter is designed to be transparent, not punitive. Users see their usage in real time via Open WebUI’s status bar:

  • 📊 Usage: 12.5K/50.0K today (25%) • 45.2K/1000.0K month (5%) — Normal usage
  • ⚠️ Usage: 42.0K/50.0K today (84%) • … — Approaching limit warning
  • ❌ Daily limit reached — Blocked, with a clear explanation and reset time

When a user is blocked, the response explains which limit was hit, how many tokens were used, and when the limit resets. No cryptic error codes.

Admin users can optionally bypass all limits (enabled by default) so you never accidentally lock yourself out while testing.


Configuration

All settings are exposed as Open WebUI Valves — no code changes needed:

ValveDefaultDescription
priority5Filter execution order (lower = runs first)
postgres_hostlanggraph-postgresPostgreSQL host
postgres_port5432PostgreSQL port
postgres_databaselanggraph_memoryDatabase name
enable_blockingtrueBlock requests when over limit
show_usage_statustrueShow usage in status bar
warn_at_percent80Warning threshold percentage
admin_bypasstrueLet admins bypass limits
default_groupfreemiumGroup for unassigned users

Getting Started

  1. Go to Admin Panel → Functions in Open WebUI
  2. Click ”+ Add Function” and paste the filter code
  3. Save, enable, and set priority to 5 (so it runs before other filters)
  4. Configure your PostgreSQL connection in the Valves
  5. Send a message — the schema auto-creates and tracking begins immediately

If you need a dedicated PostgreSQL instance, a Docker Compose file is included in the repo to spin one up in seconds.


Open Source

The Usage Tracking Filter is MIT licensed and available on GitHub. Contributions, issues, and feature requests are welcome.