diff --git a/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb b/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
index dfcc905b3c39ad6b3d390b961754165332dad042..618ea7d979cb98a80f5e5e231f7edf24cf13971d 100644
--- a/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
+++ b/app/models/concerns/analytics/cycle_analytics/stage_event_model.rb
@@ -111,7 +111,8 @@ def column_list
             :author_id,
             :state_id,
             :start_event_timestamp,
-            :end_event_timestamp
+            :end_event_timestamp,
+            :duration_in_milliseconds
           ]
         end
 
@@ -125,7 +126,8 @@ def insert_column_list
             :author_id,
             :state_id,
             :start_event_timestamp,
-            :end_event_timestamp
+            :end_event_timestamp,
+            :duration_in_milliseconds
           ]
         end
 
diff --git a/db/migrate/20231116065541_add_duration_to_issue_stage_events.rb b/db/migrate/20231116065541_add_duration_to_issue_stage_events.rb
new file mode 100644
index 0000000000000000000000000000000000000000..aeb779fa82bc76da59cee5893b8638b664ed3af5
--- /dev/null
+++ b/db/migrate/20231116065541_add_duration_to_issue_stage_events.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddDurationToIssueStageEvents < Gitlab::Database::Migration[2.2]
+  milestone '16.7'
+
+  def change
+    add_column :analytics_cycle_analytics_issue_stage_events, :duration_in_milliseconds, :bigint
+  end
+end
diff --git a/db/migrate/20231116071027_add_duration_to_mr_stage_events.rb b/db/migrate/20231116071027_add_duration_to_mr_stage_events.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3bf40ba9d56db4c27cb241b2515328165c465add
--- /dev/null
+++ b/db/migrate/20231116071027_add_duration_to_mr_stage_events.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddDurationToMrStageEvents < Gitlab::Database::Migration[2.2]
+  milestone '16.7'
+
+  def change
+    add_column :analytics_cycle_analytics_merge_request_stage_events, :duration_in_milliseconds, :bigint
+  end
+end
diff --git a/db/schema_migrations/20231116065541 b/db/schema_migrations/20231116065541
new file mode 100644
index 0000000000000000000000000000000000000000..ef0f8471137844168ffea8058111261c26b36ec6
--- /dev/null
+++ b/db/schema_migrations/20231116065541
@@ -0,0 +1 @@
+6d5b44a7961e78b76c10453005e4fab6de12a106d5437a8ccc52312cf02d3d3d
\ No newline at end of file
diff --git a/db/schema_migrations/20231116071027 b/db/schema_migrations/20231116071027
new file mode 100644
index 0000000000000000000000000000000000000000..8a34c21549a0196e39c1ce688d11bfe53c00f6cb
--- /dev/null
+++ b/db/schema_migrations/20231116071027
@@ -0,0 +1 @@
+7a7b73d20d7048dae1b63651b5874702b474820325ecbcd22dd0af1c8529ba59
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index ff69fa709dc56cfd2fd5a477bd60ddcb7aeecff5..d35c24d2e0002db6a66928955954378c45840bc1 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1002,7 +1002,8 @@ CREATE TABLE analytics_cycle_analytics_issue_stage_events (
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 )
 PARTITION BY HASH (stage_event_hash_id);
 
@@ -1017,7 +1018,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_01 (
@@ -1031,7 +1033,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_02 (
@@ -1045,7 +1048,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_03 (
@@ -1059,7 +1063,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_04 (
@@ -1073,7 +1078,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_05 (
@@ -1087,7 +1093,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_06 (
@@ -1101,7 +1108,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_07 (
@@ -1115,7 +1123,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_08 (
@@ -1129,7 +1138,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_09 (
@@ -1143,7 +1153,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_10 (
@@ -1157,7 +1168,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_11 (
@@ -1171,7 +1183,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_12 (
@@ -1185,7 +1198,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_13 (
@@ -1199,7 +1213,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_14 (
@@ -1213,7 +1228,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_15 (
@@ -1227,7 +1243,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_16 (
@@ -1241,7 +1258,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_17 (
@@ -1255,7 +1273,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_18 (
@@ -1269,7 +1288,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_19 (
@@ -1283,7 +1303,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_20 (
@@ -1297,7 +1318,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_21 (
@@ -1311,7 +1333,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_22 (
@@ -1325,7 +1348,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_23 (
@@ -1339,7 +1363,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_24 (
@@ -1353,7 +1378,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_25 (
@@ -1367,7 +1393,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_26 (
@@ -1381,7 +1408,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_27 (
@@ -1395,7 +1423,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28 (
@@ -1409,7 +1438,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_29 (
@@ -1423,7 +1453,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_30 (
@@ -1437,7 +1468,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_31 (
@@ -1451,7 +1483,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_issue_stage_even
     end_event_timestamp timestamp with time zone,
     state_id smallint DEFAULT 1 NOT NULL,
     weight integer,
-    sprint_id bigint
+    sprint_id bigint,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE analytics_cycle_analytics_merge_request_stage_events (
@@ -1463,7 +1496,8 @@ CREATE TABLE analytics_cycle_analytics_merge_request_stage_events (
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 )
 PARTITION BY HASH (stage_event_hash_id);
 
@@ -1476,7 +1510,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_01 (
@@ -1488,7 +1523,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_02 (
@@ -1500,7 +1536,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_03 (
@@ -1512,7 +1549,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_04 (
@@ -1524,7 +1562,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_05 (
@@ -1536,7 +1575,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_06 (
@@ -1548,7 +1588,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_07 (
@@ -1560,7 +1601,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_08 (
@@ -1572,7 +1614,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_09 (
@@ -1584,7 +1627,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_10 (
@@ -1596,7 +1640,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_11 (
@@ -1608,7 +1653,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_12 (
@@ -1620,7 +1666,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_13 (
@@ -1632,7 +1679,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_14 (
@@ -1644,7 +1692,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_15 (
@@ -1656,7 +1705,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_16 (
@@ -1668,7 +1718,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_17 (
@@ -1680,7 +1731,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_18 (
@@ -1692,7 +1744,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_19 (
@@ -1704,7 +1757,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_20 (
@@ -1716,7 +1770,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_21 (
@@ -1728,7 +1783,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_22 (
@@ -1740,7 +1796,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_23 (
@@ -1752,7 +1809,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_24 (
@@ -1764,7 +1822,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_25 (
@@ -1776,7 +1835,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_26 (
@@ -1788,7 +1848,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_27 (
@@ -1800,7 +1861,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_28 (
@@ -1812,7 +1874,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_29 (
@@ -1824,7 +1887,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_30 (
@@ -1836,7 +1900,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31 (
@@ -1848,7 +1913,8 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
     author_id bigint,
     start_event_timestamp timestamp with time zone NOT NULL,
     end_event_timestamp timestamp with time zone,
-    state_id smallint DEFAULT 1 NOT NULL
+    state_id smallint DEFAULT 1 NOT NULL,
+    duration_in_milliseconds bigint
 );
 
 CREATE TABLE issue_search_data (
diff --git a/ee/app/services/analytics/cycle_analytics/data_loader_service.rb b/ee/app/services/analytics/cycle_analytics/data_loader_service.rb
index d792205ff5e7dd81995c3d06566bcf8fff124b32..e4910d049589f8d3ce65bb19d64f0f98d97fe4da 100644
--- a/ee/app/services/analytics/cycle_analytics/data_loader_service.rb
+++ b/ee/app/services/analytics/cycle_analytics/data_loader_service.rb
@@ -115,6 +115,8 @@ def upsert_data(records)
             # Avoid negative duration values
             next if end_event && start_event > end_event
 
+            duration_in_milliseconds = end_event && (end_event - start_event).in_milliseconds
+
             data << {
               stage_event_hash_id: stage.stage_event_hash_id,
               issuable_id: record['id'],
@@ -125,6 +127,7 @@ def upsert_data(records)
               state_id: record['state_id'],
               start_event_timestamp: start_event,
               end_event_timestamp: end_event,
+              duration_in_milliseconds: duration_in_milliseconds,
               weight: record['weight'],
               sprint_id: record['sprint_id']
             }
diff --git a/ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb b/ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb
index 43fd7f20cbcb91bed448e4b91dcc7692a0f80690..5542eb06651338521e533ac315c1a190f9338926 100644
--- a/ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb
+++ b/ee/spec/services/analytics/cycle_analytics/data_loader_service_spec.rb
@@ -93,9 +93,18 @@
     end
 
     context 'when MergeRequest data is present' do
-      let_it_be(:mr1) { create(:merge_request, :unique_branches, :with_merged_metrics, updated_at: 2.days.ago, source_project: project1) }
-      let_it_be(:mr2) { create(:merge_request, :unique_branches, :with_merged_metrics, updated_at: 5.days.ago, source_project: project1) }
-      let_it_be(:mr3) { create(:merge_request, :unique_branches, :with_merged_metrics, updated_at: 10.days.ago, source_project: project2) }
+      let_it_be(:current_time) { Time.current }
+      let_it_be(:mr1) { create(:merge_request, :unique_branches, :with_merged_metrics, created_at: current_time, updated_at: current_time + 2.days, source_project: project1) }
+      let_it_be(:mr2) { create(:merge_request, :unique_branches, :with_merged_metrics, created_at: current_time, updated_at: current_time + 5.days, source_project: project1) }
+      let_it_be(:mr3) { create(:merge_request, :unique_branches, :with_merged_metrics, created_at: current_time, updated_at: current_time + 10.days, source_project: project2) }
+
+      let(:durations) do
+        {
+          mr1 => 2.days.to_i * 1000,
+          mr2 => 5.days.to_i * 1000,
+          mr3 => 10.days.to_i * 1000
+        }
+      end
 
       it 'inserts stage records' do
         expected_data = [mr1, mr2, mr3].map do |mr|
@@ -196,11 +205,20 @@
 
     context 'when Issue data is present' do
       let_it_be(:iteration) { create(:iteration, group: top_level_group) }
-      let_it_be(:issue1) { create(:issue, project: project1, closed_at: 5.minutes.from_now, weight: 5) }
-      let_it_be(:issue2) { create(:issue, project: project1, closed_at: 5.minutes.from_now) }
-      let_it_be(:issue3) { create(:issue, project: project2, closed_at: 5.minutes.from_now, weight: 2, iteration: iteration) }
+      let_it_be(:creation_time) { Time.current }
+      let_it_be(:issue1) { create(:issue, project: project1, created_at: creation_time, closed_at: creation_time + 5.minutes, weight: 5) }
+      let_it_be(:issue2) { create(:issue, project: project1, created_at: creation_time, closed_at: creation_time + 10.minutes) }
+      let_it_be(:issue3) { create(:issue, project: project2, created_at: creation_time, closed_at: creation_time + 15.minutes, weight: 2, iteration: iteration) }
       # invalid the creation time would be later than closed_at, this should not be aggregated
-      let_it_be(:issue4) { create(:issue, project: project2, closed_at: 5.minutes.ago) }
+      let_it_be(:issue4) { create(:issue, project: project2, created_at: creation_time, closed_at: creation_time - 5.minutes) }
+
+      let(:durations) do
+        {
+          issue1 => 5.minutes.to_i * 1000,
+          issue2 => 10.minutes.to_i * 1000,
+          issue3 => 15.minutes.to_i * 1000
+        }
+      end
 
       it 'inserts stage records' do
         expected_data = [issue1, issue2, issue3].map do |issue|
@@ -213,7 +231,8 @@
             issue.closed_at,
             issue.state_id,
             issue.weight,
-            issue.sprint_id
+            issue.sprint_id,
+            durations.fetch(issue)
           ]
         end
 
@@ -229,7 +248,8 @@
             event.end_event_timestamp,
             Analytics::CycleAnalytics::IssueStageEvent.states[event.state_id],
             event.weight,
-            event.sprint_id
+            event.sprint_id,
+            event.duration_in_milliseconds
           ]
         end
 
diff --git a/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
index 52f0e7847b09027e49985291862d9af93a631c79..13a7f71fdb27041a17e4f5953fe45b22fa6c388a 100644
--- a/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
+++ b/spec/support/shared_examples/models/concerns/analytics/cycle_analytics/stage_event_model_examples.rb
@@ -14,7 +14,8 @@
           milestone_id: 6,
           state_id: 1,
           start_event_timestamp: time,
-          end_event_timestamp: time
+          end_event_timestamp: time,
+          duration_in_milliseconds: 3
         },
         {
           stage_event_hash_id: 7,
@@ -25,7 +26,8 @@
           milestone_id: 13,
           state_id: 1,
           start_event_timestamp: time,
-          end_event_timestamp: time
+          end_event_timestamp: time,
+          duration_in_milliseconds: 5
         }
       ]
     end
@@ -40,7 +42,8 @@
         :milestone_id,
         :state_id,
         :start_event_timestamp,
-        :end_event_timestamp
+        :end_event_timestamp,
+        :duration_in_milliseconds
       ]
     end