Connection Statistics
KasmVNC provides real-time connection and performance statistics that cover server resource usage, transport-layer health, and end-to-end input latency. These metrics are available via a REST endpoint for server-side tooling and as postMessage events for host applications that embed KasmVNC in a Kasm VDI iframe.
Overview
The KasmVNC server refreshes its cached resource snapshot every second. When performance statistics are enabled, the client polls for bottleneck, network, and system statistics on a 5000 ms interval and forwards each response to the parent window via window.postMessage. Input latency is measured entirely on the client side and forwarded after each qualifying input event.
Key Features
- Server resource monitoring: CPU utilisation, memory breakdown (total, free, used, cached), per-disk I/O throughput, and — when running under cgroup v1/v2 — the container's CPU/memory limits and CPU throttling state, via
/api/system/stats.iowaitis a single system-wide CPU value repeated under each disk entry, not measured per disk. - Transport-layer metrics: RTT, smoothed jitter (RFC 6298 RTTVAR), and estimated available bandwidth, delivered approximately every five seconds.
- Sampled input-to-canvas latency: Measures the path from a user input event to the resulting frame being committed to canvas, broken down into network time and client render time, with rolling window statistics (average, min, max, p50, p95, p99). This is not true on-screen (motion-to-photon) latency.
- Host application integration: All four metric categories are forwarded as
postMessageevents when KasmVNC is embedded in an iframe. The two statistics groups are independent —enable_perf_statsdispatchesnetwork_stats,system_stats, andbottleneck_stats, whileenable_latency_statsdispatchesinput_latency— either can be enabled on its own; see Enabling Statistics below.
Enabling Statistics
Statistics are controlled by two independent settings, both of which default to off.
| Setting | Controls | Default |
|---|---|---|
enable_perf_stats | network_stats, system_stats, and bottleneck_stats postMessage events; also the /api/system/stats polling interval | false |
enable_latency_stats | input_latency postMessage events | false |
Enabling from the host application
The host application can enable either statistics group before or after the iframe loads by sending a set_perf_stats or set_latency_stats postMessage:
const kasmFrame = document.getElementById('kasm-frame');
// Enable network, system, and bottleneck stats
kasmFrame.contentWindow.postMessage({ action: 'set_perf_stats', value: true }, '*');
// Enable input latency stats
kasmFrame.contentWindow.postMessage({ action: 'set_latency_stats', value: true }, '*');
Send value: false for either action to disable that statistics group again.
Enabling via the Settings panel
Users can toggle both settings directly in the KasmVNC client:
- Open the KasmVNC control panel.
- Navigate to Settings.
- Enable Enable Performance Stats to start receiving
network_stats,system_stats, andbottleneck_statsevents. - Enable Enable Latency Stats to start receiving
input_latencyevents.
REST API
The /api/system/stats endpoint returns a snapshot of current server resource usage. See the Developer API page for the full field reference.
GET /api/system/stats
Example response:
{
"cpu": {
"usage_percent": 12.4,
"has_cgroup_usage": true,
"cgroup_usage_percent": 45.2,
"cgroup_available_percent": 50.0,
"cgroup_effective_cores": 1.0,
"cgroup_usage_usec": 10951883573,
"cgroup_user_usec": 5962863246,
"cgroup_system_usec": 4989020327
},
"memory": {
"total": 2147483648,
"free": 536870912,
"used": 1610612736,
"cached": 402653184
},
"cgroup": {
"has_mem_limit": true,
"mem_limit": 2147483648,
"has_cpu_limit": true,
"cpu_limit_cores": 1.0,
"has_cpu_weight": true,
"cpu_weight": 512,
"has_cpu_affinity": false,
"cpu_affinity": ""
},
"cpu_throttling": {
"available": true,
"has_throttling": true,
"nr_periods": 534616,
"nr_throttled": 479,
"throttled_usec": 387776426,
"throttled_percent": 0.4
},
"io_stats": {
"sda": {
"bytes_read": 104857600,
"bytes_read_per_sec": 1048576.0,
"bytes_written": 52428800,
"bytes_written_per_sec": 524288.0,
"iowait": 0.3
}
}
}
When running outside a cgroup (e.g. a bare-metal install), has_cgroup_usage/cpu_throttling.available are false and the cgroup/cpu_throttling fields fall back to their zero defaults. See the Developer API page for the full field reference.
postMessage Events
When KasmVNC runs inside a Kasm VDI iframe it sends performance data to the parent window using window.postMessage. All messages use the same envelope:
{ action: string, value: object }
A host application can receive all statistics with a single listener. Always validate event.origin and event.source before reading event.data to avoid accepting forged messages from other frames:
const kasmFrame = document.getElementById('kasm-frame');
const KASM_ORIGIN = 'https://your-kasm-instance.example.com';
window.addEventListener('message', (event) => {
// Reject messages from unexpected origins or frames.
if (event.origin !== KASM_ORIGIN || event.source !== kasmFrame.contentWindow) {
return;
}
const { action, value } = event.data;
switch (action) {
case 'system_stats':
// value — same structure as /api/system/stats
console.log('CPU:', value.cpu.usage_percent, '%');
break;
case 'network_stats':
// value.rtt — baseline RTT in ms
// value.jitter — smoothed RTT variation in ms (RFC 6298 RTTVAR)
// value.bandwidth — estimated bandwidth in bytes/second
console.log('RTT:', value.rtt, 'ms', '| jitter:', value.jitter, 'ms');
break;
case 'input_latency':
// value.latest — most recent end-to-end sample in ms
// value.p95 — 95th percentile over the last 50 samples
// value.networkP95, value.renderP95 — breakdown
console.log('Latency p95:', value.p95, 'ms');
break;
case 'bottleneck_stats':
// value.stats — server bottleneck JSON
// value.fps — rendered frames per second
// value.droppedFps
break;
}
});
Replace KASM_ORIGIN with the actual origin of the KasmVNC server (scheme + host + port). Events are only sent when the client is running inside an iframe (window.self !== window.top). In standalone mode the same data is shown in the in-page performance overlay.
See the Developer API page for full field references for each event type.
Input Latency Measurement
KasmVNC reports sampled input-to-canvas latency: the path from the moment the user presses a key or clicks the mouse to the moment the resulting frame's draw is committed to the canvas. It is broken into two components:
- Network time — the round-trip between the browser sending the input event and the server echo arriving back.
- Client render time — the time from the echo arriving to
requestAnimationFramecompleting the canvas draw.
This is not true on-screen (motion-to-photon) latency. The browser's compositing and OS presentation pipeline that turns a committed canvas draw into displayed pixels runs after requestAnimationFrame returns and is not observable from JavaScript, so that time is not included in these values.
The input_latency postMessage event fires after each qualifying input once at least 3 samples have been collected. The p95 field is the recommended threshold for session quality decisions because it captures sustained degradation without being skewed by isolated spikes.
latest ≈ networkTime + renderTime
Use Cases
Session quality dashboard — subscribe to network_stats and input_latency events and surface p95 latency and jitter to operators in a management console.
Adaptive quality control — when input_latency.p95 exceeds a threshold, lower the stream quality preset via the KasmVNC API to recover headroom.
Resource alerting — poll /api/system/stats from a monitoring agent or subscribe to system_stats postMessage events to alert when server CPU or memory crosses a threshold.