AI Usage Tracking
GitLab stores AI usage data to provide usage analytics for our customers. AI usage tracking have been generalized to make it easy for developers to add new usage events and metrics.
Usage event record structure
Usage records have mandatory and optional fields as described below:
| Field | Description |
|---|---|
timestamp | Time (to milliseconds) when the event happened. |
user_id | User who triggered the event. |
event | Event type ID as declared in the AiTracking class. |
namespace_id (optional) | Reference to associated namespace. For project events it should correspond to the project namespace ID. |
extras (optional) | Any additional metadata related to specific event type. |
Events are stored in the ai_usage_events table in Postgres and in the ai_usage_events table in ClickHouse, if it is available and
enabled for analytics.
Adding new event for tracking
If you prefer to follow along an example, see MR 197139 which contains all the required steps to add a new event to the AI tracking system.
To add a new event you must first declare the corresponding event in the InternalEvents subsystem.
See Internal Event Quick Start guide
After you have defined the event, you must register it for AI tracking:
Add the event name and unique ID to
Gitlab::Tracking::AiTracking:events(troubleshoot_job: 7)The event type ID must be unique and will be stored in databases. If you change the ID for an existing event, ensure proper migration of existing data.
If your event has additional metadata that should be stored, you need to declare the event with a transformation.
events(troubleshoot_job: 7) do |context| { job_id: context['job'].id } endYou can declare additional transformation blocks with the
transformationmethod.Your transformation blocks must return a serializable hash, because it will be serialized to the
jsonbcolumn in the database.Invoke
InternalEvents.track_eventwith your new event in appropriate codebase places to trigger the event.
Removing an event from AI usage tracking
If you like to be guided by example you can check MR 199111 which contains all required steps to remove an event from AI tracking system.
To remove your event from the AI usage tracking system:
- Remove all transformation blocks from the
AiTrackingdefinition. - Change the event definition to
deprecated_events(troubleshoot_job: 7), which will reserve ID and name for old data. - Regenerate the GraphQL docs with
bundle exec rake gitlab:graphql:compile_docs.
You can completely remove definition in AiTracking only if you are sure no data with such ID exists anymore in databases or buffers.
GraphQL exposure
All events declared for AI tracking can be automatically exposed
in the AiUsageData.all GraphQL field.
To make this field support your new event type:
- Add your event type to
enumof types inee/app/graphql/types/analytics/ai_usage/ai_usage_event_type_enum.rb. - Regenerate the GraphQL docs with
bundle exec rake gitlab:graphql:compile_docs.
You must perform this action manually to prevent occasional breaking changes to the API when editing or removing events. If you want to completely remove an event type from GraphQL, you should follow the GraphQL field deprecation process.
External calls exposure
All events declared for AI tracking are automatically exposed for external event tracking. That can be useful
when tracking for events outside of Rails app. For example in IDE extension. External events can be tracked by calling
/api/v4/usage_data/track_event endpoint with corresponding payload in “addition_properties” field. For example:
curl "https://gitlab.com/api/v4/usage_data/track_event" --request POST --header "Authorization: Bearer glpat-XXX" --header 'Content-Type: application/json' --data '{"event": "code_suggestion_accepted_in_ide", "additional_properties": {"language": "javascript", "suggestion_size": 9, "timestamp": "2025-07-02 12:55:11 UTC", "branch_name": "my-new-feature"}, "project_id": 4}'Since external events can pass any data in additional_properties hash, it’s recommended to whitelist related attributes in your event transformation block.