For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Database
Set up the SQLite or PostgreSQL database that the Analytics page, the Logs page, hybrid storage, and API key budgets need.
Verified Code examples on this page have been automatically tested and verified.About
Agentgateway reads a configuration file at startup, and that file alone is enough for the proxy to route traffic. Some features need a database as well. The two hold different things. The configuration file describes how the proxy behaves. The database holds the data that these features accumulate while agentgateway runs, such as one record for each LLM request.
You set the database in the config.database field of your configuration file. Because the field is in the config section, agentgateway applies it at startup only, so a change to it takes effect after a restart.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
config:
database:
url: sqlite://./data.db
gateways:
default:
port: 4000
ui:
gateways: defaultFeatures that need a database
The proxy can route traffic with no database, so traffic use cases work by default.
The following features do not work without a database. When you set up a database, the features also share that database.
| Feature | Description | What happens without a database |
|---|---|---|
| LLM analytics and logs | The UI shows Analytics and Logs for LLM requests (not other proxy traffic such as HTTP routes to a backend service). The Analytics page is also the cost dashboard. To show spend in dollars instead of tokens and calls, add a model cost catalog as well as a database. For the controls on the page, see Cost dashboard. | Agentgateway starts, but each UI page reports request log database is not configured and the admin API returns a 500 response. |
hybrid configuration storage | When enabled, hybrid mode stores UI edit to agentgateway configuration in the database. | Agentgateway does not start: config.storage.mode=hybrid requires config.database.url. |
| LLM API key budgets | API key budgets let you track LLM spend across restarts | Agentgateway does not start: API key budgets require config.database to be configured. |
Access logging database
Optionally, to keep request logs in a different database from the rest, you can set the config.logging.database field. Then, agentgateway writes request logs to the database in config.logging.database, and uses config.database for the other features.
For more information, see Store logs in a database.
Important
The config.logging.database field covers request logs only. It does not satisfy hybrid storage or API key budgets, because both features use the primary database. If you configure either feature with config.logging.database alone, agentgateway fails to start with the error in the preceding table.
Choose a database backend
Agentgateway selects the backend from the URL. A URL that starts with postgres:// or postgresql:// is PostgreSQL. Every other value is a SQLite database file.
| Backend | Example URL | Use it when |
|---|---|---|
| SQLite | sqlite://./data.db | You run a single agentgateway instance and want no external service. |
| PostgreSQL | postgres://user:password@host:5432/dbname | You run more than one replica, or you want the data to outlive the instance. |
SQLite writes to a file, so agentgateway needs a writable directory for it. PostgreSQL needs a reachable server and a user that can create tables.
Warning
Do not point more than one agentgateway instance at the same SQLite file. Give each instance its own file instead, or use PostgreSQL. With one file for each instance, the Analytics page shows the traffic of the instance that you are connected to, not the traffic of the whole deployment.
Before you begin
Install agentgateway as a binary, a Docker container, or a Kubernetes Deployment with Helm.
Binary and Docker
In the binary and Docker installations, agentgateway writes the SQLite file to a directory that you control, so SQLite needs no extra service.
Use the generated database
When you start agentgateway with no configuration file, the generated configuration already sets a SQLite database, so no extra step is needed. The binary writes both files to your user config directory. A container writes both to the directory that you mount at the /config path.
Start agentgateway with no configuration file.
agentgatewayReview the generated configuration. The
config.database.urlfield points at a SQLite file next to the configuration file. The following example is the file that a container generates. The binary generates the same file, with the absolute path of your user config directory in the URL.# yaml-language-server: $schema=https://agentgateway.dev/schema/config config: database: url: sqlite:///config/data.db gateways: default: port: 4000 ui: gateways: default
Because the generated configuration attaches the UI to the default gateway, the Analytics page is served on the gateway port, such as http://localhost:4000/ui/llm/analytics. The generated configuration has no llm section yet, so the LLM section of the navigation appears only after you add a model.
Add a database to your own configuration file
A configuration file that you write yourself has no database until you add one. Add the config.database field, then restart agentgateway.
Add the
config.database.urlfield to your configuration file.The path is relative to the directory that you start agentgateway from.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config config: database: url: sqlite://./data.db gateways: default: port: 4000 ui: gateways: default llm: models: - name: gpt-4o-mini provider: openAI params: model: gpt-4o-mini apiKey: "$OPENAI_API_KEY"Restart agentgateway with the updated file.
Stop the current process, such as with
ctrl+c, then start it again.agentgateway -f config.yaml
Important
If agentgateway cannot create the SQLite file, the process exits with failed to initialize request log database. In a container, this error usually means that the directory in the URL is not mounted, or that the mount is read-only. Point the URL at a directory that agentgateway can write to, and mount that directory into the container.
Helm
The Helm chart renders your configuration into a ConfigMap and mounts it read-only, and the chart sets no database for you. As a result, a default installation starts with no database, and the Analytics and Logs pages report request log database is not configured.
To add a database, choose one of the following options.
| Option | Storage mode | Use it when |
|---|---|---|
| SQLite on a volume | The chart’s default readonly mode | You want the Analytics and Logs pages, and you keep your Helm values as the only source of configuration. |
| PostgreSQL in database mode | The chart’s database mode | You also want the UI to save configuration changes, or you run more than one replica. |
Add SQLite on a volume
In the default readonly mode, the chart sets the storage mode and nothing else, so a config.database field in your Helm values reaches the rendered ConfigMap unchanged. SQLite needs a writable directory, and the proxy container runs with a read-only root filesystem, so mount a volume for the database file.
Note
The chart’s own config value says not to set config.storage or config.database yourself. That restriction applies to database mode, where the chart derives both fields from the mode and database.postgres.url values and overwrites what you set. In readonly mode, the chart sets config.storage only, so your config.database value is preserved.
Create a values file that sets the database URL and mounts a volume for it.
Review the following table to understand this configuration.cat <<'EOF' > values.yaml mode: readonly config: config: database: url: sqlite:///data/data.db gateways: default: port: 4000 llm: models: [] mcp: targets: [] ui: {} extraVolumes: - name: agw-data emptyDir: {} extraVolumeMounts: - name: agw-data mountPath: /data EOFSetting Description config.config.database.urlThe agentgateway config.database.urlfield. The outerconfigvalue is the whole configuration file, so the agentgatewayconfigsection is nested inside it.extraVolumesandextraVolumeMountsA writable directory for the SQLite file. The proxy container mounts the ConfigMap read-only and runs with a read-only root filesystem, so no other path accepts a write. Warning
An
emptyDirvolume exists only for the lifetime of the pod. When the pod restarts, the request log data is lost. To keep the data, back the volume with a PersistentVolumeClaim, or use PostgreSQL instead.Upgrade the release with your values file.
helm upgrade -i agentgateway-standalone \ oci://cr.agentgateway.dev/charts/agentgateway-standalone \ --namespace agentgateway-system \ --version v1.5.0 \ --reuse-values \ -f values.yamlConfirm that the chart rendered the database into the ConfigMap.
kubectl get configmap agentgateway-standalone-config \ -n agentgateway-system -o jsonpath='{.data.config\.yaml}'Example output:
config: database: url: sqlite:///data/data.db storage: mode: file gateways: default: port: 4000 llm: models: [] mcp: targets: [] ui: {}
Note
This option gives the Analytics and Logs pages a database, but it does not make the UI writable. The ConfigMap stays read-only, so a UI save still fails. To make the UI writable, see Configuration storage.
Add PostgreSQL in database mode
The chart’s database mode sets both config.database.url and config.storage.mode: hybrid for you. One PostgreSQL instance then serves the request log, the configuration overlay, and API key budgets.
Deploy PostgreSQL. For the example manifests, see Deploy PostgreSQL.
Create a values file that sets the mode and the connection URL.
cat <<'EOF' > values.yaml mode: database database: postgres: url: postgres://agw:[email protected]:5432/agw config: gateways: default: port: 4000 llm: models: [] mcp: targets: [] ui: {} EOFNote
Do not set
config.config.databaseindatabasemode. The chart derives the field from themodeanddatabase.postgres.urlvalues, and overwrites anything that you set for it yourself.Upgrade the release with your values file.
helm upgrade -i agentgateway-standalone \ oci://cr.agentgateway.dev/charts/agentgateway-standalone \ --namespace agentgateway-system \ --version v1.5.0 \ --reuse-values \ -f values.yamlConfirm that the tables exist. Agentgateway creates them on the first startup.
kubectl exec -n agentgateway-system deploy/postgres \ -- psql -U agw -d agw -c '\dt'Example output: The
request_logsandrequest_log_payloadstables hold the data for the Analytics page,budget_usageholds API key budgets, andagw_config_resourcesholds the configuration that you save in the UI.List of relations Schema | Name | Type | Owner --------+----------------------+-------+------- public | agw_config_resources | table | agw public | budget_usage | table | agw public | request_log_payloads | table | agw public | request_logs | table | agw (4 rows)
Verify that agentgateway records requests
Agentgateway records LLM requests only, so send a request to an LLM model to confirm that the database works. These steps need at least one model in the llm section of your configuration. For the steps to add one, see the LLM quickstart.
Make the gateway port and the admin address reachable from your machine.
Both addresses are already local. The gateway listens on port 4000, and the admin address on port 15000.Send a request to an LLM model through agentgateway.
curl -s http://localhost:4000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "Say hello in one sentence."}] }' | jq .Review the request log. The admin API is served in the same places as the UI, so use the admin address or the gateway port that serves the UI. For more information, see Launch the UI.
curl -s -X POST http://localhost:15000/api/logs/search \ -H 'Content-Type: application/json' -d '{}' | jq .Example output: Agentgateway records the model, the token counts, and the duration for each request.
{ "logs": [ { "id": "01a03f23-f49e-7b31-90f8-0ba440d7c8fa", "startedAt": "2026-08-26T17:35:09.010434Z", "completedAt": "2026-08-26T17:35:16.123561Z", "durationMs": 7113, "httpStatus": 200, "genAi": { "operationName": "chat", "providerName": "openai", "requestModel": "gpt-4o-mini", "responseModel": "gpt-4o-mini-2024-07-18" }, "usage": {"inputTokens": 14, "outputTokens": 5, "totalTokens": 19} } ], "nextCursor": null }Open the LLM > Analytics page in the UI, such as http://localhost:15000/ui/llm/analytics. The request appears in the chart and in the breakdown. For more information about the controls on the page, see Cost dashboard.
Next steps
- Choose where configuration is stored so that the UI can save your changes.
- View LLM spend in the cost dashboard.
- Set API key budgets that persist across restarts.
- Review what agentgateway stores in each request log record.