How to Monitor Usage Analytics and Request Logs in FreeLLMAPI

FreeLLMAPI captures every proxy request in an internal SQLite database and exposes aggregated metrics through authenticated REST endpoints under /api/analytics.

FreeLLMAPI provides built-in observability through comprehensive request logging and analytics. The system automatically records every proxy interaction—including token usage, latency, model selection, and error details—to a local SQLite database. This article explains how to access and configure these monitoring capabilities using the platform's analytics API and retention settings.

Understanding the Logging Architecture

The Core Logging Function

Every request passing through the FreeLLMAPI proxy triggers the logRequest function in server/src/lib/request-log.ts. This utility inserts a detailed row into the requests table, capturing success status, failure reasons, token consumption, latency metrics, and whether the client explicitly pinned a specific model or accepted an auto-selection.

Data Retention Management

To prevent unbounded database growth, FreeLLMAPI implements automatic pruning via server/src/services/request-retention.ts. The helper getRequestAnalyticsRetentionConfig reads two environment variables that control the lifecycle of logged data:

  • REQUEST_ANALYTICS_RETENTION_DAYS: Maximum age of rows before deletion (default: 90)
  • REQUEST_ANALYTICS_MAX_ROWS: Hard cap on total rows retained (default: 100000)

The pruning logic executes on every log write or on a timed interval to enforce these limits, ensuring the SQLite table remains performant.

Available Analytics Endpoints

All analytics are exposed through a dedicated router in server/src/routes/analytics.ts mounted under the prefix /api/analytics. These read-only endpoints require authentication via the requireAuth middleware attached in server/src/app.ts.

High-Level Summary Statistics

The GET /api/analytics/summary endpoint provides rolling aggregates including total requests, success rates, token totals, average latency, estimated cost savings, and counts of pinned versus auto-selected models. The underlying SQL joins the requests table with model pricing data to calculate savings estimates.

Model and Platform Breakdowns

For granular cost and performance analysis:

  • GET /api/analytics/by-model: Groups statistics by platform and model_id, returning request counts, success percentages, average latency, token totals, and pinned counts per model
  • GET /api/analytics/by-platform: Aggregates metrics by provider (e.g., OpenAI, Anthropic) to compare platform-level performance and costs

Timeline and Error Analysis

Time-series monitoring is available through GET /api/analytics/timeline, which uses SQLite's strftime function to bucket request volume, success counts, and failure counts into hourly or daily intervals.

For debugging, two specialized endpoints expose error data:

  • GET /api/analytics/error-distribution: Categorizes errors by type (rate-limit, authentication, timeout) using CASE WHEN logic on the error message strings
  • GET /api/analytics/errors: Returns raw recent error rows with full request details for deep investigation

Querying Analytics via API

All endpoints accept authentication headers and optional range parameters. Below are practical examples for common monitoring tasks.

Fetch a summary of the last 7 days (default range):

curl -H "Authorization: Bearer <YOUR_API_KEY>" \
     https://<your-host>/api/analytics/summary

Get model-level stats for the past 24 hours:

curl -H "Authorization: Bearer <YOUR_API_KEY>" \
     "https://<your-host>/api/analytics/by-model?range=24h"

Show hourly timeline for the last day:

curl -H "Authorization: Bearer <YOUR_API_KEY>" \
     "https://<your-host>/api/analytics/timeline?range=24h&interval=hour"

Inspect recent errors:

curl -H "Authorization: Bearer <YOUR_API_KEY>" \
     "https://<your-host>/api/analytics/errors?range=7d"

Configuring Data Retention

Adjust retention policies by setting environment variables before starting the service. Create or modify your .env file:

REQUEST_ANALYTICS_RETENTION_DAYS=30
REQUEST_ANALYTICS_MAX_ROWS=50000

After restarting the service, the next logRequest invocation will trigger the new retention policy defined in server/src/services/request-retention.ts.

Direct Database Access

Because analytics data persists in a local SQLite file within the runtime data directory, you can bypass the API for custom reporting. Connect directly to the database using standard SQLite tools to run ad-hoc queries against the requests table, join with custom tables, or export data to external business intelligence systems.

Summary

  • Request logging is handled by logRequest in server/src/lib/request-log.ts, which writes every proxy interaction to the SQLite requests table
  • Data retention is controlled via REQUEST_ANALYTICS_RETENTION_DAYS and REQUEST_ANALYTICS_MAX_ROWS, enforced by server/src/services/request-retention.ts
  • Analytics endpoints under /api/analytics provide summary, model-specific, platform-specific, timeline, and error-distribution views
  • Authentication is mandatory for all analytics routes via the requireAuth middleware in server/src/app.ts
  • Direct SQL access is possible for operators requiring custom analysis beyond the built-in JSON endpoints

Frequently Asked Questions

How long does FreeLLMAPI retain request logs by default?

By default, FreeLLMAPI retains request logs for 90 days and maintains a maximum of 100,000 rows in the requests table. These defaults are defined in server/src/services/request-retention.ts and can be overridden using the REQUEST_ANALYTICS_RETENTION_DAYS and REQUEST_ANALYTICS_MAX_ROWS environment variables.

What authentication is required to access analytics endpoints?

All analytics endpoints require Bearer token authentication via the Authorization header. The requireAuth middleware in server/src/app.ts guards these routes, ensuring only authenticated users can view sensitive usage data and error logs.

Can I export FreeLLMAPI analytics data to external systems?

Yes. Since FreeLLMAPI stores data in a local SQLite file, you can connect external tools directly to the database or build automated scripts that query the /api/analytics endpoints. The JSON responses from endpoints like /api/analytics/timeline and /api/analytics/by-model are designed for easy integration with monitoring platforms and data warehouses.

How does the retention service handle reaching the maximum row limit?

When the row count exceeds REQUEST_ANALYTICS_MAX_ROWS, the retention service prunes the oldest entries based on timestamp. This cleanup occurs either on every write operation or on a timed interval, ensuring the database never grows beyond the configured hard cap while preserving the most recent analytics data.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →