Data Model
This page describes the telemetry data collected and sent by the Framedash SDKs.
Every event is a single GameTelemetryEvent, serialized with Protobuf and sent in a TelemetryBatch to POST /v1/events. Each event maps to one row in the ClickHouse events table. The schema is fixed (defined in telemetry.proto); game-specific data goes into flexible attributes and metrics maps, so adding new data never requires a schema change as long as values stay within the ingest limits below.
Event fields
Section titled “Event fields”Identity and context
Section titled “Identity and context”| Field | Type | Description |
|---|---|---|
event_name | string | Event identifier, e.g. player_death, or the automatic session_start / perf_heartbeat. |
timestamp_us | int64 | Event time as a Unix epoch in microseconds (stored as DateTime64(6)). |
session_id | string | Game session identifier. |
player_id | string | Explicit player identifier; the only PII the SDK collects, cleared under COPPA mode. |
map_id | string | Map / level identifier for spatial analytics. |
build_id | string | Build version. |
platform | string | Engine-reported platform name (Unity Application.platform, UE IniPlatformName, Godot OS.GetName()). |
engine_version | string | Engine version (Unity Application.unityVersion, UE FEngineVersion, Godot Engine.GetVersionInfo()["string"]). |
source | enum | Origin of the event: player, automated, or unspecified. |
Position and camera
Section titled “Position and camera”| Field | Type | Description |
|---|---|---|
position | Vector3 (x, y, z floats) | World-space position. Stored as position_x / position_y / position_z. |
camera_yaw | float (optional) | Horizontal camera rotation in degrees: 0 = North, clockwise, range [0, 360). Absent when the SDK does not capture camera. |
camera_pitch | float (optional) | Vertical camera rotation in degrees: -90 = straight down, +90 = straight up. |
camera_yaw and camera_pitch are sent together or not at all, so a missing value means “not captured” rather than zero.
Performance metrics
Section titled “Performance metrics”Collected automatically by the SDK, most importantly on the perf_heartbeat event, emitted every 10 seconds:
| Field | Type | Unit / Notes |
|---|---|---|
fps | float | frames per second |
frame_time_ms | float | milliseconds |
gpu_time_ms | float | milliseconds |
game_thread_ms | float | CPU game-thread time in ms (0 = not collected) |
render_thread_ms | float | CPU render-thread time in ms (0 = not collected) |
memory_used_bytes | int64 | bytes |
Load-time and disk-I/O metrics
Section titled “Load-time and disk-I/O metrics”Two more automatic performance signals ship in Unity SDK 0.1.3, UE5 SDK 0.1.6, and Godot SDK 0.1.4. Both feed the perf-diff / build-comparison regression gate and the dashboard charts.
map_load: a dedicated auto event thatBeginMapLoad/EndMapLoadorReportMapLoademits when a map or level finishes loading. It carriesmetrics["load_time_ms"]andattributes["map_name"], and it deliberately leavesmap_idempty so it stays out of spatial heatmaps and the activation gate.io.read_bytes/io.read_time_ms/io.read_ops: disk-read counters attached to theperf_heartbeatmetricsmap as deltas since the previous heartbeat. They appear only after a real sample has landed. The automatic source is Editor / Development-build only on Unity (AsyncReadManagerMetrics), opt-in on UE5 (bTrackDiskIo), and manual-only on Godot (ReportIoSample).
See each SDK guide for the per-engine API and threading rules.
Memory-category metrics
Section titled “Memory-category metrics”Supported SDKs attach memory-category usage as mem.* metrics on perf_heartbeat and position-qualified events. The available keys and how they are collected differ per engine.
- UE5 SDK 0.1.7 and later:
mem.vramplus the LLM-dependentmem.textures/mem.meshes/mem.audio. All are opt-in (bTrackMemoryDetail, off by default);mem.vramneeds no LLM but is absent on headless /-nullrhiruns (which emit an absent key, not0). - Unity SDK 0.1.4 and later:
mem.vramandmem.heap. Collected automatically, no opt-in. - Godot SDK 0.1.5 and later:
mem.vram,mem.textures, andmem.buffers. Collected automatically, no opt-in.
All ride in the metrics map, and an untracked category leaves its key absent (which means “not collected”, distinct from a collected 0). mem.vram is also a perf-diff (build-comparison) metric. See the UE5 SDK, Unity SDK, and Godot SDK guides for per-engine details.
Custom data
Section titled “Custom data”Game-specific context travels in two flexible maps, with no schema change required:
| Field | Type | Description |
|---|---|---|
attributes | map<string, string> | String key-value pairs, e.g. weapon: "rifle". Dropped entirely under COPPA mode. |
metrics | map<string, double> | Numeric measurements, e.g. damage: 42.5. |
Ingest validation limits
Section titled “Ingest validation limits”The ingest pipeline validates every decoded event. If any event in a batch is outside these limits, the batch can be rejected at request time or dropped during async processing, so custom SDKs and raw Protobuf senders should clamp values before flushing. The official Unity, UE5, and Godot SDKs apply these clamps client-side.
| Field | Limit |
|---|---|
timestamp_us | Must be within the last 30 days and no more than 48 hours in the future. |
event_name / session_id | Required and non-empty. event_name is max 128 chars; session_id is max 64 chars. |
player_id, map_id, build_id | Max 128 chars each. |
source, platform, engine_version | Max 64 chars each. |
position_x / position_y / position_z | Finite numbers with absolute value at or below 1e9. |
fps | Finite number from 0 to 1000. |
frame_time_ms / gpu_time_ms / game_thread_ms / render_thread_ms | Finite milliseconds from 0 to 10000. |
memory_used_bytes | Integer from 0 to 64 GiB. |
attributes | Max 50 entries; keys max 64 chars; values max 512 chars. |
metrics | Max 50 entries; keys max 64 chars; values must be finite numbers. |
camera_yaw / camera_pitch | Both present or both absent. Yaw is normalized to [0, 360) and pitch to [-90, 90]. |
Batch envelope
Section titled “Batch envelope”SDKs send a TelemetryBatch, which is simply a list of GameTelemetryEvent values. The API key and SDK version travel in HTTP headers (X-API-Key, X-SDK-Version), not in the payload body.
Custom senders should keep the HTTP request body as sent (after gzip compression, if used) at or below 126,000 bytes. Larger production ingest bodies are rejected with 413; the official SDKs flush well below that cap.
Next Steps
Section titled “Next Steps”- API Reference: Access this data via the REST API
- Heatmaps: Visualizing position data