
# Data handling and retention

The Gateway provides configurable data handling to match your project's privacy and compliance requirements.

## Request logging

Every Gateway request produces a **request log record** containing:

| Field | Description | Stored by default |
|---|---|---|
| Request ID | Unique Gateway-internal identifier (`gwrun_*`) | Yes |
| Trace ID | Shared trace identifier (`gwtrace_*`) | Yes |
| Model | The model ID requested | Yes |
| Provider | The provider that served the request | Yes |
| Status code | HTTP status returned to the client | Yes |
| Latency | Total round-trip time in milliseconds | Yes |
| Tokens | Input and output token counts | Yes |
| Estimated cost | Computed cost in USD | Yes |
| Fallback used | Whether a secondary provider was used | Yes |
| Error code | Machine-readable error on failures | Yes |

**Request and response content is never stored** in the Gateway logging pipeline unless a separate content-logging configuration is enabled.

## Logging modes

Projects can configure a `loggingMode` through the Gateway settings:

| Mode | Effect |
|---|---|
| `metadata_only` | Logs metadata fields only (tokens, latency, cost, status, error codes). No message content or model responses are recorded. **Default.** |
| `content` | Logs request messages and response content in addition to metadata. |
| `off` | Disables request logging entirely. Usage tracking and budgets still operate from in-memory counters. |

## Content retention

When a project configures `contentRetentionDays`, logged content (messages and responses) is retained for that number of days before automatic deletion. A `null` value means content is retained indefinitely.

Metadata-only fields (request IDs, timestamps, tokens, cost) are not subject to content retention — they follow the project's audit log retention policy.

## Zero-data-retention mode

Set `zeroDataRetention: true` in the Gateway settings payload to minimise data persistence:

- Request logs are written with metadata only regardless of the `loggingMode` setting.
- Provider attempt logs do not store error message details.
- Usage summaries continue to aggregate token and cost counts for billing, but individual request detail is not recoverable past the current aggregation window.

## Usage tracking

Even with logging off, the Gateway records **usage events** for billing and budgeting:

- Count of requests per project, model, and provider.
- Input and output token totals.
- Estimated cost in USD.

Usage data is stored in the `gateway_usage_events` table and aggregated for dashboard display. Individual usage events cannot be linked back to specific request content.

## Budget enforcement

Projects can configure spending limits (`daily_usd`, `monthly_usd`, `monthly_tokens`). When a limit is exceeded:

- The Gateway rejects subsequent chat completion requests from that project.
- The response includes the exceeded limit type and current spend.
- The request log records the block with an error code.

When Supabase storage is unavailable and a project has budget configuration, the Gateway cannot determine spend status and **fails closed** — requests are denied unless `GATEWAY_BYPASS_BUDGET_CHECK=true` is set (local development only).

## Fail-closed data handling

The Gateway applies a consistent fail-closed policy for data-handling features:

| Feature | When storage unavailable |
|---|---|
| Budget enforcement | Deny requests (bypassable in dev with env var) |
| Provider allowlist enforcement | Deny requests (bypassable in dev with env var) |
| BYOK credential lookup | Credentials unavailable; fall back to server-level env vars |

## See also

- [Gateway overview](/docs/gateway/overview)
- [BYOK operational guide](/docs/security/byok-operations)
- [Credential management](/docs/security/credential-management)
- [Usage and logs](/docs/gateway/usage-logs)
