Skip to main content

What is stored in the DB

The LiteLLM Proxy uses a PostgreSQL database to store various information. Here's are the main features the DB is used for:

  • Virtual Keys, Organizations, Teams, Users, Budgets, and more.
  • Per request Usage Tracking

You can see the full DB Schema here

DB Tables​

Organizations, Teams, Users, End Users​

Table NameDescriptionRow Insert Frequency
LiteLLM_OrganizationTableManages organization-level configurations. Tracks organization spend, model access, and metadata. Links to budget configurations and teams.Low
LiteLLM_TeamTableHandles team-level settings within organizations. Manages team members, admins, and their roles. Controls team-specific budgets, rate limits, and model access.Low
LiteLLM_UserTableStores user information and their settings. Tracks individual user spend, model access, and rate limits. Manages user roles and team memberships.Low
LiteLLM_EndUserTableManages end-user configurations. Controls model access and regional requirements. Tracks end-user spend.Low
LiteLLM_TeamMembershipTracks user participation in teams. Manages team-specific user budgets and spend.Low
LiteLLM_OrganizationMembershipManages user roles within organizations. Tracks organization-specific user permissions and spend.Low
LiteLLM_InvitationLinkHandles user invitations. Manages invitation status and expiration. Tracks who created and accepted invitations.Low
LiteLLM_UserNotificationsHandles model access requests. Tracks user requests for model access. Manages approval status.Low

Authentication​

Table NameDescriptionRow Insert Frequency
LiteLLM_VerificationTokenManages Virtual Keys and their permissions. Controls token-specific budgets, rate limits, and model access. Tracks key-specific spend and metadata.Medium - stores all Virtual Keys

Model (LLM) Management​

Table NameDescriptionRow Insert Frequency
LiteLLM_ProxyModelTableStores model configurations. Defines available models and their parameters. Contains model-specific information and settings.Low - Configuration only

Budget Management​

Table NameDescriptionRow Insert Frequency
LiteLLM_BudgetTableStores budget and rate limit configurations for organizations, keys, and end users. Tracks max budgets, soft budgets, TPM/RPM limits, and model-specific budgets. Handles budget duration and reset timing.Low - Configuration only

Tracking & Logging​

Table NameDescriptionRow Insert Frequency
LiteLLM_SpendLogsDetailed logs of all API requests. Records token usage, spend, and timing information. Tracks which models and keys were used.Medium - this is a batch process that runs on an interval.
LiteLLM_DailyUserSpend and siblings (DailyTeamSpend, DailyOrgSpend, DailyTagSpend, DailyEndUserSpend, DailyAgentSpend)Pre-aggregated daily spend rollups per user, team, org, tag, end user, and agent; the Admin UI Usage views read these aggregates rather than scanning SpendLogs.Low - one row per entity per day, updated in batches
LiteLLM_DailyGatewayRequestsSuccessful and failed request counts recorded at the ASGI edge by the request-metrics middleware, keyed by date, category and route. Backs the Successful Requests and Failed Requests tiles and the Gateway Requests by Endpoint chart on the Usage page; see gateway request counts.Low - one row per route per day, updated in batches
LiteLLM_AuditLogTracks changes to system configuration. Records who made changes and what was modified. Maintains history of updates to teams, users, and models.Off by default, High - Runs on every change to an entity

Disable LiteLLM_SpendLogs​

Set disable_spend_logs: True or disable_error_logs: True under general_settings to stop writing those tables. With spend logs disabled you lose per-request log detail in the UI but keep cost metrics in your logging integrations (s3, Prometheus, Langfuse); with error logs disabled you lose the Errors view in the UI but keep errors in application logs and other logging integrations. See keeping error logs out of the database in the production checklist.

Migrating Databases​

If you need to migrate Databases the following Tables should be copied to ensure continuation of services and no downtime

Table NameDescription
LiteLLM_VerificationTokenRequired to ensure existing virtual keys continue working
LiteLLM_UserTableRequired to ensure existing virtual keys continue working
LiteLLM_TeamTableRequired to ensure Teams are migrated
LiteLLM_TeamMembershipRequired to ensure Teams member budgets are migrated
LiteLLM_BudgetTableRequired to migrate existing budgeting settings
LiteLLM_OrganizationTableOptional Only migrate if you use Organizations in DB
LiteLLM_OrganizationMembershipOptional Only migrate if you use Organizations in DB
LiteLLM_ProxyModelTableOptional Only migrate if you store your LLMs in the DB (i.e you set STORE_MODEL_IN_DB=True)
LiteLLM_SpendLogsOptional Only migrate if you want historical data on LiteLLM UI
LiteLLM_ErrorLogsOptional Only migrate if you want historical data on LiteLLM UI

Replicating the database with logical replication​

Postgres logical replication only carries the columns of the replica identity when a row is updated or deleted. Prisma creates every LiteLLM table at the Postgres default, which is the primary key, so a downstream consumer sees the new row but not the previous one. Sinks such as Neon's lakehouse sync require REPLICA IDENTITY FULL and reject tables that do not have it.

Set LITELLM_SET_REPLICA_IDENTITY_FULL=True to have LiteLLM run

ALTER TABLE "LiteLLM_..." REPLICA IDENTITY FULL;

on every LiteLLM table at the end of each migration run, including tables that a future upgrade adds, so the setting survives upgrades instead of having to be re-applied by hand. Tables that are already FULL are skipped, and tables in the same schema that LiteLLM does not own are left alone.

export LITELLM_SET_REPLICA_IDENTITY_FULL=True
litellm --config /path/to/config.yaml

The database user running the migrations has to own the tables. If it does not, the ALTER is rejected, LiteLLM logs the Postgres error and starts anyway, since replication metadata is not needed to serve requests.

REPLICA IDENTITY FULL makes Postgres write the entire old row into the WAL for every UPDATE and DELETE, so leave it off unless a replication consumer needs it.