diff --git a/backend/public/dashboard.js b/backend/public/dashboard.js
index a774950564c479ccb6398e34813b865fc24683d2..b3e8b087a758fdbee0f1b697cb3dce29b77259c3 100644
--- a/backend/public/dashboard.js
+++ b/backend/public/dashboard.js
@@ -104,3 +104,57 @@ new Chart(
   document.getElementById("shotsByDurationChart"),
   shotsByDurationConfig,
 );
+
+//=[ Devices behaviour ]========================================================
+
+const devicesBehaviourData = JSON.parse(
+  document.getElementById("devicesBehaviourData").textContent,
+)
+  .filter((item) => item.device_id)
+  .map((item) => [
+    item.ended_count,
+    item.interrupted_count,
+    parseFloat((item.time_spent / 100000).toFixed(2)),
+  ]);
+
+console.log(devicesBehaviourData);
+
+const devicesBehaviourConfig = {
+  type: "bubble",
+  data: {
+    datasets: [
+      {
+        data: devicesBehaviourData,
+        backgroundColor: "blue",
+      },
+    ],
+  },
+  options: {
+    // maintainAspectRatio: true,
+    // aspectRatio: 1,
+    scales: {
+      x: {
+        type: "logarithmic",
+        title: {
+          display: true,
+          text: "Finished games",
+        },
+      },
+      y: {
+        type: "logarithmic",
+        title: {
+          display: true,
+          text: "Interrupted games",
+        },
+      },
+    },
+    plugins: {
+      legend: { display: false },
+    },
+  },
+};
+
+new Chart(
+  document.getElementById("devicesBehaviourChart"),
+  devicesBehaviourConfig,
+);
diff --git a/backend/src/index.ts b/backend/src/index.ts
index 59ebc954e5d2cf2097beb9ccfd250c331bdee2da..f69aecb56b5c182df2bafd33c7ae66a7f1c5a20f 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -64,6 +64,25 @@ server.get("/", async (request, reply) => {
   const cluesCount = (await connection.table("clues").count())[0].count;
   const shotsCount = (await connection.table("shots").count())[0].count;
 
+  const normalizedGames = connection
+    .table("games")
+    .select(
+      connection.raw(
+        "games.id, games.device_id, games.began_at_gmtm, games.ended_at_gmtm, max(shots.ended_at_gmtm) as last_shot_ended_at_gmtm",
+      ),
+    )
+    .fullOuterJoin("shots", "games.id", "shots.game_id")
+    .groupBy("games.id");
+
+  const devicesBehaviour = await connection
+    .select(
+      connection.raw(
+        "sum(coalesce (ended_at_gmtm, last_shot_ended_at_gmtm) - began_at_gmtm) as time_spent, count(case when ended_at_gmtm is not null then 1 end) as ended_count, count(case when ended_at_gmtm is null then 1 end) as interrupted_count, device_id",
+      ),
+    )
+    .from(normalizedGames.as("g"))
+    .groupBy("device_id");
+
   const devicesByDate = await connection
     .table("games")
     .select(connection.raw("COUNT(DISTINCT device_id), DATE(began_at)"))
@@ -96,13 +115,13 @@ server.get("/", async (request, reply) => {
     devicesByDate,
     gamesByDate,
     shotsByDuration,
+    devicesBehaviour,
   });
 });
 
 // TODO: this is an horrible kludge
 import fastifyStatic from "fastify-static";
 import path from "path";
-import { connect } from "http2";
 server.register(fastifyStatic, {
   root: path.join(__dirname, "../public"),
   prefix: "/public/",
diff --git a/backend/templates/dashboard.ejs b/backend/templates/dashboard.ejs
index a56ed484d249c896ba44197afc459c6b071e86ac..669bee2c75625b62be53d04c529530b8679394b7 100644
--- a/backend/templates/dashboard.ejs
+++ b/backend/templates/dashboard.ejs
@@ -88,6 +88,11 @@
                 <h1>Shot count by duration [ms]</h1>
                 <script id="shotsByDurationData" type="application/json"><%- JSON.stringify(shotsByDuration) %></script>
                 <canvas id="shotsByDurationChart"></canvas>
+
+                <h1>Total gametime per device [m]</h1>
+                <script id="devicesBehaviourData"
+                    type="application/json"><%- JSON.stringify(devicesBehaviour) %></script>
+                <canvas id="devicesBehaviourChart"></canvas>
             </main>
         </div>
     </div>