OpenWebUI Monitor and putting a price tag on your own LLM instance
A dashboard for tracking user activity and enforcing usage limits in OpenWebUI. Set user quotas efficiently.
At a glance
- What is it?
- OpenWebUI Monitor is a Next.js dashboard and an OpenWebUI function that add per-user balances, per-model prices and token-based deduction to a self-hosted OpenWebUI deployment, so an instance shared by several people can be metered instead of being free for everyone. The interesting engineering is the split between the dashboard you deploy yourself and the function you install into OpenWebUI, and the interesting constraint is that the whole thing talks to OpenWebUI with an admin API key.
- Who is it for?
- OpenWebUI Monitor is a good fit for an operator running a shared OpenWebUI instance who needs per-user metering, because it adds balances, token-based deduction and usage charts without asking you to change the model server, and it deploys either to Vercel or as a Docker container with its own Postgres.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 153 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the tool adds to OpenWebUI
OpenWebUI Monitor is described as a dashboard for tracking user activity and enforcing usage limits in OpenWebUI, and the README frames it as a monitoring dashboard that tracks usage and manages user balances. The integration method is a function: you add a function to OpenWebUI and you get a unified panel of user activity and balances.
The feature list is four items. You can set prices for each model in OpenWebUI. You can set a balance for each user, deduct based on token consumption and model prices, with notifications at the end of each chat. You can view user data and visualisations. And there is a one-click test for all model availability.
Those four features are the accounting layer, and they depend on a model of usage that OpenWebUI itself does not have. OpenWebUI knows which models exist and who is chatting. It does not know that a user with a balance of four dollars has spent two of them, because that requires prices and a ledger, and prices differ per model.
The notification at the end of each chat is the detail that makes the accounting visible rather than theoretical. A user sees their remaining balance when the conversation ends, which is the point of a quota system and also the point where a wrong price configuration becomes obvious.
The one-click model availability test is the odd one out and the most useful for an administrator. Checking every configured model by hand is tedious and the failure mode is confusing, because a model that does not load looks the same as a model that is not reachable from the current context.
The primary language is TypeScript, the licence is MIT, the default branch is main, and the recent releases are v0.3.8 from 2026-01-13, v0.3.7 from 2025-04-08 and v0.3.6 from 2025-03-24. The last push was on 2026-05-23 and the repository is not archived. The hosted demo is at openwebui-usage-monitor.vercel.app.
The audience is the operator of a shared instance, and the licence permits commercial use of the tool itself, though the pricing of the models is the operator's own decision.
The deployment split: a dashboard you run, a function you install
The architecture has two halves, and understanding which is which explains most of the configuration.
The dashboard is a separate application. It is a Next.js app, given away by the scripts in package.json: dev runs next dev, build runs next build and start runs next start. It has its own database, its own authentication and its own user interface, with Radix UI components, Ant Design icons and plots, a components.json file for shadcn, Tailwind with both a tailwind.config.ts and a postcss.config.mjs, an i18n.config.ts and a locales/ directory for translations, a drizzle.config.ts, and a middleware.ts.
The function is a Python file, openwebui_monitor.py, that you install into OpenWebUI itself. It takes three parameters: an Api Endpoint, which is your deployed monitor backend domain or IP address accessible within the OpenWebUI container, an Api Key, which is the API_KEY environment variable set in the backend deployment, and a Language, which is the message display language, either en or zh.
So the flow is that OpenWebUI calls out to the monitor on every chat to record usage, and the monitor is the thing that holds the balances and the prices and the charts.
Deployment is supported on Vercel with a one-click button, and with Docker. For Vercel, the button is pre-configured with the environment variable names the project needs: OPENWEBUI_DOMAIN, OPENWEBUI_API_KEY, ACCESS_TOKEN and API_KEY.
Updates are simpler than the initial setup, and the two paths differ. For Vercel you sync the fork and redeploy your project. For Docker you pull the latest image and restart the container:
sudo docker compose pull
sudo docker compose up -dThe compose file itself is worth reading for what it reveals about the shape. There is an app service from the image docker.io/variantconst/openwebui-monitor:latest with the port mapping 7878 to 3000, reading a .env file, and a set of POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DATABASE environment variables that default to a db host, port 5432, the postgres user, the password openwebui and the database openwebui_monitor. The app service depends on the db service with the condition service_healthy, and the db service is postgres:15-alpine with a healthcheck running pg_isready against the configured user on a five second interval with five retries, and a named volume for the data directory.
The healthcheck and the service_healthy condition are the part that matters operationally. A container that starts before its database is ready will crash, and the healthcheck plus the dependency condition is what turns that into a wait rather than a failure.
The pricing model and the environment variables that drive it
The billing model has two layers: a per-user balance, and a per-model price.
The required environment variables are four. OPENWEBUI_DOMAIN is the OpenWebUI domain, and OPENWEBUI_API_KEY is the OpenWebUI API key, found in Personal Settings, Account, API Key. API_KEY is for API request verification and must be less than 56 characters, and ACCESS_TOKEN is for page access verification.
Those last two are the security boundary, and both are things you generate yourself. The example values in the readme are your-access-token-here and your-api-key-here, and the .env.example repeats them. The API_KEY length limit of 56 characters is not arbitrary decoration, it is a constraint inherited from somewhere in the stack, and it is a useful reminder that this value travels as a header on every request the OpenWebUI function makes.
The optional variables are where the accounting policy lives. DEFAULT_MODEL_INPUT_PRICE is the default model input price in USD per million tokens, defaulting to 60, and DEFAULT_MODEL_OUTPUT_PRICE is the same for output, also 60. DEFAULT_MODEL_PER_MSG_PRICE is a default price for each message in USD, defaulting to -1, and the negative value is meaningful because the .env.example comments that -1 means charging by tokens. So a model is either priced per message or priced by token consumption, and the per-message price is what the negative default is telling you.
INIT_BALANCE is the initial user balance, defaulting to 0, which means new users start with nothing unless you change it. COST_ON_INLET is the pre-deduction amount on inlet, and it can be a fixed number for all models, for example 0.1, or a model-specific format such as gpt-4:0.32,gpt-3.5:0.01. The pre-deduction idea is that a small amount is taken before the request runs, so a user cannot run out of balance mid-generation, and the model-specific form lets you charge more for an expensive model at the door.
The database connection variables are optional for the same reason they are listed separately, with the .env.example noting they configure these if you use an external database. The compose file uses them to point at its own Postgres service, and the profiles mechanism on the db service, with a ${POSTGRES_HOST:+never} entry, is what lets you disable the bundled database when an external one is supplied.
The networking rule that trips people up
There is a FAQ entry about the OPENWEBUI_DOMAIN variable, and the question it answers is worth more attention than its position in the document suggests.
The principle stated is that this address should be accessible from within the OpenWebUI Monitor container. The recommendation is to fill in the public domain name of OpenWebUI, for example https://chat.example.com. If the monitor is deployed on the same machine, you can also fill in http://[Docker host local ip]:[OpenWebUI backend service port], and you can get the host's local IP through ifconfig with a grep for inet.
And then the constraint: you cannot fill in http://127.0.0.1:port or omit http://.
That is the whole networking story in two sentences. Inside a container, 127.0.0.1 is the container's own loopback, so a monitor trying to reach OpenWebUI at 127.0.0.1 would be talking to itself. And the scheme has to be explicit, because a bare hostname would be resolved as a path or treated as a relative URL by whatever client is doing the request.
The second FAQ entry is the mirror image of the first, and it covers the function side. The Api Endpoint function parameter is your deployed monitor backend domain or IP address accessible within the OpenWebUI container, for example http://[host local ip]:7878, where 7878 is the default port for OpenWebUI Monitor. That matches the compose port mapping, where the host port 7878 maps to the container port 3000.
The third FAQ entry answers a question that will come up the first time you open the dashboard, and the answer is behavioural rather than a bug. If you cannot see users in the user management page, it is because OpenWebUI Monitor only starts tracking a user's information after the user makes their first chat request. There is no user list until somebody talks to a model, which means the admin page looks empty on a fresh instance no matter how correctly it is configured.
Where this is the wrong tool
Three limits follow from what the project is.
The first is the administrative key requirement. The monitor reads the OpenWebUI user list and the model list with an OpenWebUI admin API key, and that key has to be reachable by the monitor. For a shared instance that is a reasonable requirement, but it does mean the monitor is granted the same administrative reach as OpenWebUI itself. If your policy separates the components, that is a policy conversation to have before deployment rather than after.
The second is that the accounting is only as good as the price table. Token counts come from what OpenWebUI reports, and the prices are whatever you type in, so a stale price list produces plausible-looking wrong numbers. There is no documented mechanism for importing the model price list from a provider, and the README actually recommends a separate third-party tool, openwebui-monitor-sync by Yeraze, whose description is auto-syncing OpenAI and Claude model prices to your instance. So the price data is expected to come from somewhere else, and the monitor is where you spend it.
The third is the scope of what is metered. The model is per-user balance, per-model price and per-message or per-token charge. It does not do team quotas, role-based limits, rate limiting per request, or reporting that a finance team would accept as a record. If you are running OpenWebUI for a small group and want to see who used what, this is the tool. If you are running it as a metered product with contractual entitlements, you need the accounting in your own application layer.
The alternative worth comparing against is building the deduction into an OpenWebUI function of your own, with a webhook on the chat completion and a small database of balances. The difference in approach is that this project gives you the dashboard, the price configuration UI and the charts as a ready-made application, whereas a custom function gives you exactly the enforcement you need and nothing else, at the cost of writing the ledger yourself.
Editorial conclusion
OpenWebUI Monitor is a good fit for an operator running a shared OpenWebUI instance who needs per-user metering, because it adds balances, token-based deduction and usage charts without asking you to change the model server, and it deploys either to Vercel or as a Docker container with its own Postgres. It is a poor fit for a single-user instance, where the accounting is overhead with no recipient, and a poor fit if you cannot expose OpenWebUI's admin API key to the monitor, since that key is what lets it read the user list and model list. Before deploying, set API_KEY and ACCESS_TOKEN to your own values rather than the example strings, and read the OPENWEBUI_DOMAIN guidance, because 127.0.0.1 inside a container is the monitor's own loopback and will not reach the OpenWebUI backend.
Frequently asked questions
What does OpenWebUI Monitor do?
It is a monitoring dashboard for OpenWebUI that tracks usage and manages user balances. It lets you set prices for each model, set a balance for each user and deduct based on token consumption and model prices, with a notification at the end of each chat, plus usage visualisations and a one-click test for model availability.
How is OpenWebUI Monitor deployed?
Either with a one-click Vercel deployment or with Docker. The compose file runs the image docker.io/variantconst/openwebui-monitor:latest on host port 7878 mapping to container port 3000, alongside a postgres:15-alpine service that the app waits on through a service_healthy condition.
Which environment variables does OpenWebUI Monitor require?
OPENWEBUI_DOMAIN for the OpenWebUI domain, OPENWEBUI_API_KEY for the key found in Personal Settings, Account, API Key, API_KEY for API request verification which must be less than 56 characters, and ACCESS_TOKEN for page access verification. Prices, initial balance and pre-deduction are optional and have documented defaults.
Why does the user management page show no users?
OpenWebUI Monitor only starts tracking a user's information after the user makes their first chat request, so the admin page is empty on a fresh instance until somebody talks to a model.
Can I use 127.0.0.1 for the OpenWebUI domain in OpenWebUI Monitor?
No. The address has to be reachable from within the OpenWebUI Monitor container, so 127.0.0.1 inside a container points at the container itself. Use the public domain, or the Docker host local IP with the OpenWebUI backend service port, and always include the http:// or https:// scheme.
How do I update an OpenWebUI Monitor deployment?
For Vercel, sync the fork and redeploy the project. For Docker, pull the latest image and restart the container with `sudo docker compose pull` and `sudo docker compose up -d`. OpenWebUI version 0.5.8 or above also requires updating the installed function to the latest version.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/variantconst-openwebui-monitor)