diff --git a/broker/src/asapo_broker/server/monitoring.go b/broker/src/asapo_broker/server/monitoring.go
index 5e197e2fbfcc7280f96332bbf6f25fc43cd325cc..936450507b5fb6ebb32d0a4df8b83a0a79121742 100644
--- a/broker/src/asapo_broker/server/monitoring.go
+++ b/broker/src/asapo_broker/server/monitoring.go
@@ -8,25 +8,26 @@ import (
 )
 
 type brokerMonitoring struct {
-	Sender BrokerMonitoringDataSender
-	BrokerName              string
+	Sender     BrokerMonitoringDataSender
+	BrokerName string
 
 	toBeSendMutex      sync.Mutex
 	toBeSendDataPoints []*pb.BrokerRequestDataPoint
 
 	sendingThreadRunningCtx context.Context
 
-	discoveredMonitoringServerUrl 	string
+	discoveredMonitoringServerUrl string
 }
 
-func (m *brokerMonitoring) getBrokerToConsumerTransfer(consumerInstanceId string, pipelineStepId string, op string, beamtime string, source string, stream string) *pb.BrokerRequestDataPoint {
+func (m *brokerMonitoring) getBrokerToConsumerTransfer(consumerInstanceId string, pipelineStepId string, op string, beamtime string, source string, stream string, groupId string) *pb.BrokerRequestDataPoint {
 	for _, element := range m.toBeSendDataPoints {
 		if element.ConsumerInstanceId == consumerInstanceId &&
 			element.PipelineStepId == pipelineStepId &&
 			element.Command == op &&
 			element.Beamtime == beamtime &&
 			element.Source == source &&
-			element.Stream == stream {
+			element.Stream == stream &&
+			element.GroupId == groupId {
 			return element
 		}
 	}
@@ -38,8 +39,10 @@ func (m *brokerMonitoring) getBrokerToConsumerTransfer(consumerInstanceId string
 		Beamtime:           beamtime,
 		Source:             source,
 		Stream:             stream,
+		GroupId:            groupId,
 		FileCount:          0,
 		TotalFileSize:      0,
+		DelayMs:            0,
 	}
 
 	// Need to insert element
@@ -56,7 +59,6 @@ func (m *brokerMonitoring) sendNow() error {
 	m.toBeSendDataPoints = nil
 	m.toBeSendMutex.Unlock()
 
-
 	dataContainer := pb.BrokerDataPointContainer{
 		BrokerName:            m.BrokerName,
 		TimestampMs:           uint64(time.Now().UnixNano() / int64(time.Millisecond)),
@@ -73,13 +75,16 @@ func (m *brokerMonitoring) sendNow() error {
 
 func (m *brokerMonitoring) SendBrokerRequest(
 	consumerInstanceId string, pipelineStepId string,
-	op string, beamtimeId string, datasource string, stream string, size uint64) {
+	op string, beamtimeId string, datasource string, stream string, groupId string, size uint64, delayMs uint64) {
 
 	m.toBeSendMutex.Lock()
 
-	group := m.getBrokerToConsumerTransfer(consumerInstanceId, pipelineStepId, op, beamtimeId, datasource, stream)
+	group := m.getBrokerToConsumerTransfer(consumerInstanceId, pipelineStepId, op, beamtimeId, datasource, stream, groupId)
 	group.FileCount++
 	group.TotalFileSize += size
+	if group.DelayMs == 0 || group.DelayMs > delayMs {
+		group.DelayMs = delayMs
+	}
 
 	m.toBeSendMutex.Unlock()
 }
diff --git a/broker/src/asapo_broker/server/monitoring_test.go b/broker/src/asapo_broker/server/monitoring_test.go
index af499cd3a315a89b608c50dc8b13c44ae4179a53..03f2ca442f693b57d417ece5f289afe474edbdca 100644
--- a/broker/src/asapo_broker/server/monitoring_test.go
+++ b/broker/src/asapo_broker/server/monitoring_test.go
@@ -11,6 +11,7 @@ import (
 type mockRpc struct {
 	LastSendContainer *pb.BrokerDataPointContainer
 }
+
 func (m *mockRpc) Send(container *pb.BrokerDataPointContainer) error {
 	m.LastSendContainer = container
 	return nil
@@ -24,6 +25,7 @@ func (m *mockRpc) IsInitialized() bool {
 
 type mockErrorRpc struct {
 }
+
 func (m *mockErrorRpc) Send(container *pb.BrokerDataPointContainer) error {
 	return errors.New("MyMockError from Send")
 }
@@ -41,15 +43,15 @@ func TestMonitoringCycle(t *testing.T) {
 
 	// Send one file
 	monitoring.SendBrokerRequest(
-		"consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream",
-		123)
+		"consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream", "groupId",
+		123, 456)
 
 	monitoring.sendNow()
 
 	assert.NotNil(t, mockRpc.LastSendContainer)
 	assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker")
-	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000)
-	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)))
+	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond))-1000)
+	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond)))
 	assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 1)
 	assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].PipelineStepId, "pipelineStep")
 	assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].ConsumerInstanceId, "consumerId")
@@ -64,28 +66,27 @@ func TestMonitoringCycle(t *testing.T) {
 	monitoring.sendNow()
 	assert.NotNil(t, mockRpc.LastSendContainer)
 	assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker")
-	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000)
-	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)))
+	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond))-1000)
+	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond)))
 	assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 0)
 
-
 	// Send 3 files in 2 groups
 	monitoring.SendBrokerRequest(
-		"consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream",
-		564)
+		"consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream", "groupId",
+		564, 123)
 	monitoring.SendBrokerRequest(
-		"consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream",
-		32)
+		"consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream", "groupId",
+		32, 45)
 	monitoring.SendBrokerRequest(
-		"consumerId", "pipelineStep", "push", "beamtime2", "datasource", "stream",
-		401)
+		"consumerId", "pipelineStep", "push", "beamtime2", "datasource", "stream", "groupId",
+		401, 546)
 
 	monitoring.sendNow()
 
 	assert.NotNil(t, mockRpc.LastSendContainer)
 	assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker")
-	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000)
-	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)))
+	assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond))-1000)
+	assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano()/int64(time.Millisecond)))
 	assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 2)
 
 	assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].PipelineStepId, "pipelineStep")
@@ -114,8 +115,8 @@ func TestSendNowErrorForwarding(t *testing.T) {
 
 	// Send one file
 	monitoring.SendBrokerRequest(
-		"consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream",
-		123)
+		"consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream", "groupId",
+		123, 234)
 
 	assert.Equal(t, monitoring.sendNow().Error(), "MyMockError from Send")
 }
diff --git a/broker/src/asapo_broker/server/process_request.go b/broker/src/asapo_broker/server/process_request.go
index 76f85640bfad25a8daa68b8ab0d54d64afd3821c..f3ac333dfaf6018c85fdfa50368354c65406e854 100644
--- a/broker/src/asapo_broker/server/process_request.go
+++ b/broker/src/asapo_broker/server/process_request.go
@@ -10,32 +10,33 @@ import (
 	"github.com/gorilla/mux"
 	"net/http"
 	"net/url"
+	"time"
 )
 
-func readFromMapUnescaped(key string, vars map[string]string) (val string,ok bool) {
-	if val, ok = vars[key];!ok {
+func readFromMapUnescaped(key string, vars map[string]string) (val string, ok bool) {
+	if val, ok = vars[key]; !ok {
 		return
 	}
 	var err error
-	if val, err = url.PathUnescape(val);err!=nil {
-		return "",false
+	if val, err = url.PathUnescape(val); err != nil {
+		return "", false
 	}
 	return
 }
 
 func extractRequestParameters(r *http.Request, needGroupID bool) (
-	string/*instanceid*/, string/*pipelinestep*/,
-	string/*beamtime*/, string/*datasource*/, string /*stream*/, string /*groupid*/, bool, /*was okay*/
-	) {
+	string /*instanceid*/, string, /*pipelinestep*/
+	string /*beamtime*/, string /*datasource*/, string /*stream*/, string /*groupid*/, bool, /*was okay*/
+) {
 	vars := mux.Vars(r)
 	db_name, ok1 := vars["beamtime"]
-	datasource, ok3 := readFromMapUnescaped("datasource",vars)
-	stream, ok4 := readFromMapUnescaped("stream",vars)
+	datasource, ok3 := readFromMapUnescaped("datasource", vars)
+	stream, ok4 := readFromMapUnescaped("stream", vars)
 
 	ok2 := true
 	group_id := ""
 	if needGroupID {
-		group_id, ok2 = readFromMapUnescaped("groupid",vars)
+		group_id, ok2 = readFromMapUnescaped("groupid", vars)
 	}
 
 	instanceid := r.URL.Query().Get("instanceid")
@@ -48,7 +49,7 @@ func extractRequestParameters(r *http.Request, needGroupID bool) (
 
 func IsLetterOrNumbers(s string) bool {
 	for _, r := range s {
-		if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r<'0' || r>'9') {
+		if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r < '0' || r > '9') {
 			return false
 		}
 	}
@@ -61,7 +62,7 @@ func checkBrokerApiVersion(w http.ResponseWriter, r *http.Request) bool {
 }
 
 func needWriteAccess(op string) bool {
-	return op=="delete_stream";
+	return op == "delete_stream"
 }
 
 func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_param string, needGroupID bool) {
@@ -69,11 +70,10 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
 		return
 	}
 
-
 	w.Header().Set("Access-Control-Allow-Origin", "*")
 	consumerInstanceId, pipelineStepId, beamtimeId, datasource, stream, group_id, ok := extractRequestParameters(r, needGroupID)
 	if !ok {
-		log.WithFields(map[string]interface{}{"request":r.RequestURI}).Error("cannot extract request parameters")
+		log.WithFields(map[string]interface{}{"request": r.RequestURI}).Error("cannot extract request parameters")
 		w.WriteHeader(http.StatusBadRequest)
 		return
 	}
@@ -95,23 +95,27 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
 		request.MinDatasetSize = minSize
 	}
 
-	rlog:=request.Logger()
+	rlog := request.Logger()
 	rlog.Debug("got request")
-	answer, code := processRequestInDb(request,rlog)
+	answer, code := processRequestInDb(request, rlog)
 	w.WriteHeader(code)
 	_, err := w.Write(answer)
 
-	type SizeStruct struct {
-		Size uint64 `bson:"size" json:"size"`
+	type StatsStruct struct {
+		Size      uint64 `bson:"size" json:"size"`
+		Timestamp uint64 `bson:"timestamp" json:"timestamp"`
 	}
 
 	if err == nil && code == 200 && len(consumerInstanceId) > 0 && len(pipelineStepId) > 0 {
-		var sized SizeStruct
-		err = json.Unmarshal(answer, &sized)
+		var ansStats StatsStruct
+		err = json.Unmarshal(answer, &ansStats)
 		if err == nil {
+			delay := (uint64(time.Now().UnixNano()) / uint64(time.Millisecond)) - ansStats.Timestamp
 			switch op {
-			case "next": fallthrough
-			case "id": fallthrough
+			case "next":
+				fallthrough
+			case "id":
+				fallthrough
 			case "last":
 				monitoring.SendBrokerRequest(
 					consumerInstanceId,
@@ -120,7 +124,9 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
 					beamtimeId,
 					datasource,
 					stream,
-					sized.Size,
+					group_id,
+					ansStats.Size,
+					delay,
 				)
 			}
 		}
@@ -129,10 +135,10 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par
 
 func returnError(err error, rlog logger.Logger) (answer []byte, code int) {
 	code = database.GetStatusCodeFromError(err)
-	if code != utils.StatusNoData && code != utils.StatusPartialData{
-		rlog.WithFields(map[string]interface{}{"cause":err.Error()}).Error("cannot process request")
+	if code != utils.StatusNoData && code != utils.StatusPartialData {
+		rlog.WithFields(map[string]interface{}{"cause": err.Error()}).Error("cannot process request")
 	} else {
-		rlog.WithFields(map[string]interface{}{"cause":err.Error()}).Debug("no data or partial data")
+		rlog.WithFields(map[string]interface{}{"cause": err.Error()}).Debug("no data or partial data")
 	}
 	return []byte(err.Error()), code
 }
@@ -144,13 +150,13 @@ func reconnectIfNeeded(db_error error) {
 	}
 
 	if err := ReconnectDb(); err != nil {
-		log.WithFields(map[string]interface{}{"address":settings.GetDatabaseServer(),"cause": err.Error()}).Error("cannot reconnect to database")
+		log.WithFields(map[string]interface{}{"address": settings.GetDatabaseServer(), "cause": err.Error()}).Error("cannot reconnect to database")
 	} else {
-		log.WithFields(map[string]interface{}{"address":settings.GetDatabaseServer()}).Debug("reconnected to database")
+		log.WithFields(map[string]interface{}{"address": settings.GetDatabaseServer()}).Debug("reconnected to database")
 	}
 }
 
-func processRequestInDb(request database.Request,rlog logger.Logger) (answer []byte, code int) {
+func processRequestInDb(request database.Request, rlog logger.Logger) (answer []byte, code int) {
 	statistics.IncreaseCounter()
 	answer, err := db.ProcessRequest(request)
 	if err != nil {
diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go
index 070b5ebe4b62d828353c7ff54126f1fba6869d86..88e6c8379675c7ddd76bec07d60a94f20602bacf 100644
--- a/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go
+++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.26.0-devel
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringCommonService.proto
 
 package generated_proto
diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go
index 9977231872de70e0826bebc1193e61fadff8cff7..be5733a6c8e31252d650dd8765ccbfd93b5e3d6a 100644
--- a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go
+++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.26.0-devel
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringIngestService.proto
 
 package generated_proto
@@ -150,8 +150,10 @@ type BrokerRequestDataPoint struct {
 	Beamtime           string `protobuf:"bytes,4,opt,name=beamtime,proto3" json:"beamtime,omitempty"`
 	Source             string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty"`
 	Stream             string `protobuf:"bytes,6,opt,name=stream,proto3" json:"stream,omitempty"`
-	FileCount          uint64 `protobuf:"varint,7,opt,name=fileCount,proto3" json:"fileCount,omitempty"`
-	TotalFileSize      uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"`
+	GroupId            string `protobuf:"bytes,7,opt,name=groupId,proto3" json:"groupId,omitempty"`
+	FileCount          uint64 `protobuf:"varint,8,opt,name=fileCount,proto3" json:"fileCount,omitempty"`
+	TotalFileSize      uint64 `protobuf:"varint,9,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"`
+	DelayMs            uint64 `protobuf:"varint,10,opt,name=delayMs,proto3" json:"delayMs,omitempty"`
 }
 
 func (x *BrokerRequestDataPoint) Reset() {
@@ -228,6 +230,13 @@ func (x *BrokerRequestDataPoint) GetStream() string {
 	return ""
 }
 
+func (x *BrokerRequestDataPoint) GetGroupId() string {
+	if x != nil {
+		return x.GroupId
+	}
+	return ""
+}
+
 func (x *BrokerRequestDataPoint) GetFileCount() uint64 {
 	if x != nil {
 		return x.FileCount
@@ -242,6 +251,13 @@ func (x *BrokerRequestDataPoint) GetTotalFileSize() uint64 {
 	return 0
 }
 
+func (x *BrokerRequestDataPoint) GetDelayMs() uint64 {
+	if x != nil {
+		return x.DelayMs
+	}
+	return 0
+}
+
 type RdsMemoryDataPoint struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -779,7 +795,7 @@ var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{
 	0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65,
 	0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x74, 0x6f, 0x74,
 	0x61, 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73,
-	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65,
 	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
 	0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65,
 	0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c,
@@ -793,123 +809,126 @@ var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{
 	0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61,
 	0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
-	0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a,
-	0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53,
-	0x69, 0x7a, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
-	0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79,
-	0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42,
-	0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74,
-	0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42,
-	0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f,
-	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12,
-	0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75,
-	0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74,
-	0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74,
-	0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
-	0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72,
-	0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65,
-	0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12,
-	0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65,
-	0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c,
-	0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72,
-	0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e,
-	0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f,
-	0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16, 0x46, 0x64, 0x73, 0x54,
-	0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74,
-	0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f,
-	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
-	0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f,
-	0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c,
-	0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74,
-	0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f,
-	0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54,
-	0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
-	0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72,
-	0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e,
-	0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a,
-	0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x72,
-	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d,
-	0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, 0x54,
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
-	0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69,
-	0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50,
-	0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72,
-	0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x64, 0x73, 0x54, 0x6f,
-	0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54,
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
-	0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xab, 0x01,
-	0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x72,
-	0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69,
-	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x4d, 0x0a, 0x15,
-	0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x42, 0x72,
-	0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50,
-	0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f,
-	0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x1f,
-	0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c,
+	0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69,
+	0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+	0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d,
+	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
+	0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d,
+	0x65, 0x6d, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a,
+	0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73,
+	0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75,
+	0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73,
+	0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
+	0x69, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53,
+	0x74, 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63,
+	0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
+	0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62,
+	0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62,
+	0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
+	0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d,
+	0x69, 0x73, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73,
+	0x73, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65,
+	0x53, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69,
+	0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d,
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16,
+	0x46, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
+	0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e,
+	0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a,
+	0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69,
+	0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66,
+	0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52,
+	0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50,
+	0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53,
+	0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65,
+	0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69,
+	0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
+	0x22, 0xce, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74,
 	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12,
-	0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d,
-	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
-	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46, 0x64, 0x73, 0x54, 0x6f,
-	0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61,
-	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x61, 0x70, 0x6f,
-	0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49, 0x6e, 0x73, 0x65, 0x72,
-	0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61,
-	0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
-	0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x16, 0x49, 0x6e,
-	0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
-	0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74,
-	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a,
-	0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x13, 0x49, 0x6e, 0x73,
-	0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73,
-	0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
-	0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-	0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11,
-	0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x22, 0x0a, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+	0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64,
+	0x50, 0x32, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x24, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52,
+	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44,
+	0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65,
+	0x64, 0x50, 0x32, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a,
+	0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52,
+	0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64,
+	0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61,
+	0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65,
+	0x6d, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74,
+	0x73, 0x22, 0xab, 0x01, 0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e,
+	0x0a, 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20,
+	0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73,
+	0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44,
+	0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65,
+	0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22,
+	0xa8, 0x01, 0x0a, 0x1f, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
+	0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a,
+	0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12,
+	0x49, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46,
+	0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64,
+	0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41,
+	0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e,
+	0x67, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49,
+	0x6e, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
+	0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61,
+	0x69, 0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d,
+	0x0a, 0x16, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61,
+	0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a,
+	0x13, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
+	0x69, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
+	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
index e59fc901bbc6386af668c7e1f080ae53227527a6..abe4edc729c568cc64d514a2b9f6bfaa3bcffe58 100644
--- a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
+++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
-// - protoc-gen-go-grpc v1.1.0
-// - protoc             v3.15.8
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
 // source: AsapoMonitoringIngestService.proto
 
 package generated_proto
diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go
index 95db885aad0be09288590cb4dd7a5f1d23c692b7..e5d6e3658c17ccc1e26a90815fb25542391e04ff 100644
--- a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go
+++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.26.0-devel
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringQueryService.proto
 
 package generated_proto
@@ -834,6 +834,171 @@ func (x *TopologyResponse) GetEdges() []*TopologyResponseEdge {
 	return nil
 }
 
+type GroupDelayQuery struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	FromTimestamp  uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"`
+	ToTimestamp    uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"`
+	BeamtimeFilter string `protobuf:"bytes,3,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"`
+}
+
+func (x *GroupDelayQuery) Reset() {
+	*x = GroupDelayQuery{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayQuery) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayQuery) ProtoMessage() {}
+
+func (x *GroupDelayQuery) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayQuery.ProtoReflect.Descriptor instead.
+func (*GroupDelayQuery) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *GroupDelayQuery) GetFromTimestamp() uint64 {
+	if x != nil {
+		return x.FromTimestamp
+	}
+	return 0
+}
+
+func (x *GroupDelayQuery) GetToTimestamp() uint64 {
+	if x != nil {
+		return x.ToTimestamp
+	}
+	return 0
+}
+
+func (x *GroupDelayQuery) GetBeamtimeFilter() string {
+	if x != nil {
+		return x.BeamtimeFilter
+	}
+	return ""
+}
+
+type GroupDelayResponseItem struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GroupId string `protobuf:"bytes,1,opt,name=groupId,proto3" json:"groupId,omitempty"`
+	DelayMs uint32 `protobuf:"varint,2,opt,name=delayMs,proto3" json:"delayMs,omitempty"`
+}
+
+func (x *GroupDelayResponseItem) Reset() {
+	*x = GroupDelayResponseItem{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayResponseItem) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayResponseItem) ProtoMessage() {}
+
+func (x *GroupDelayResponseItem) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayResponseItem.ProtoReflect.Descriptor instead.
+func (*GroupDelayResponseItem) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *GroupDelayResponseItem) GetGroupId() string {
+	if x != nil {
+		return x.GroupId
+	}
+	return ""
+}
+
+func (x *GroupDelayResponseItem) GetDelayMs() uint32 {
+	if x != nil {
+		return x.DelayMs
+	}
+	return 0
+}
+
+type GroupDelayResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GroupIds []*GroupDelayResponseItem `protobuf:"bytes,1,rep,name=groupIds,proto3" json:"groupIds,omitempty"`
+}
+
+func (x *GroupDelayResponse) Reset() {
+	*x = GroupDelayResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayResponse) ProtoMessage() {}
+
+func (x *GroupDelayResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayResponse.ProtoReflect.Descriptor instead.
+func (*GroupDelayResponse) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *GroupDelayResponse) GetGroupIds() []*GroupDelayResponseItem {
+	if x != nil {
+		return x.GroupIds
+	}
+	return nil
+}
+
 var File_AsapoMonitoringQueryService_proto protoreflect.FileDescriptor
 
 var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{
@@ -973,26 +1138,47 @@ var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{
 	0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65,
 	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f,
 	0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x52, 0x05,
-	0x65, 0x64, 0x67, 0x65, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79,
-	0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f,
-	0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09,
-	0x45, 0x78, 0x61, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a,
-	0x75, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70,
-	0x10, 0x02, 0x32, 0xb6, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69,
-	0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
-	0x61, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61,
-	0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31,
-	0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e,
-	0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54,
-	0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x73, 0x12, 0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51,
-	0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e,
-	0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x65, 0x64, 0x67, 0x65, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44,
+	0x65, 0x6c, 0x61, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x72, 0x6f,
+	0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
+	0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74,
+	0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x4c, 0x0a, 0x16, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49,
+	0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a,
+	0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
+	0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x49, 0x0a, 0x12, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a,
+	0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49,
+	0x64, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f,
+	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64,
+	0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x51, 0x55, 0x45,
+	0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x78, 0x61,
+	0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a, 0x75, 0x73, 0x74,
+	0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70, 0x10, 0x02, 0x32,
+	0xf0, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
+	0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
+	0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x06,
+	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+	0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0b, 0x47,
+	0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e, 0x54, 0x6f, 0x70,
+	0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54, 0x6f, 0x70, 0x6f,
+	0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38,
+	0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12,
+	0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72,
+	0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x47,
+	0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x10, 0x2e, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
+	0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1008,7 +1194,7 @@ func file_AsapoMonitoringQueryService_proto_rawDescGZIP() []byte {
 }
 
 var file_AsapoMonitoringQueryService_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
+var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
 var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{
 	(PipelineConnectionQueryMode)(0),   // 0: PipelineConnectionQueryMode
 	(*DataPointsQuery)(nil),            // 1: DataPointsQuery
@@ -1022,7 +1208,10 @@ var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{
 	(*TopologyResponseNode)(nil),       // 9: TopologyResponseNode
 	(*TopologyResponseEdge)(nil),       // 10: TopologyResponseEdge
 	(*TopologyResponse)(nil),           // 11: TopologyResponse
-	(*Empty)(nil),                      // 12: Empty
+	(*GroupDelayQuery)(nil),            // 12: GroupDelayQuery
+	(*GroupDelayResponseItem)(nil),     // 13: GroupDelayResponseItem
+	(*GroupDelayResponse)(nil),         // 14: GroupDelayResponse
+	(*Empty)(nil),                      // 15: Empty
 }
 var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{
 	0,  // 0: DataPointsQuery.pipelineQueryMode:type_name -> PipelineConnectionQueryMode
@@ -1032,17 +1221,20 @@ var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{
 	5,  // 4: DataPointsResponse.memoryUsages:type_name -> RdsMemoryUsageDataPoint
 	9,  // 5: TopologyResponse.nodes:type_name -> TopologyResponseNode
 	10, // 6: TopologyResponse.edges:type_name -> TopologyResponseEdge
-	12, // 7: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty
-	8,  // 8: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery
-	1,  // 9: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery
-	7,  // 10: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse
-	11, // 11: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse
-	6,  // 12: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse
-	10, // [10:13] is the sub-list for method output_type
-	7,  // [7:10] is the sub-list for method input_type
-	7,  // [7:7] is the sub-list for extension type_name
-	7,  // [7:7] is the sub-list for extension extendee
-	0,  // [0:7] is the sub-list for field type_name
+	13, // 7: GroupDelayResponse.groupIds:type_name -> GroupDelayResponseItem
+	15, // 8: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty
+	8,  // 9: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery
+	1,  // 10: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery
+	12, // 11: AsapoMonitoringQueryService.GetGroupDelay:input_type -> GroupDelayQuery
+	7,  // 12: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse
+	11, // 13: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse
+	6,  // 14: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse
+	14, // 15: AsapoMonitoringQueryService.GetGroupDelay:output_type -> GroupDelayResponse
+	12, // [12:16] is the sub-list for method output_type
+	8,  // [8:12] is the sub-list for method input_type
+	8,  // [8:8] is the sub-list for extension type_name
+	8,  // [8:8] is the sub-list for extension extendee
+	0,  // [0:8] is the sub-list for field type_name
 }
 
 func init() { file_AsapoMonitoringQueryService_proto_init() }
@@ -1184,6 +1376,42 @@ func file_AsapoMonitoringQueryService_proto_init() {
 				return nil
 			}
 		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayQuery); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayResponseItem); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -1191,7 +1419,7 @@ func file_AsapoMonitoringQueryService_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_AsapoMonitoringQueryService_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   11,
+			NumMessages:   14,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
index 85be8b748f685c311e28b9747c1faa4169ae4a9e..e8cf3493af77686d3d60aeca413274d400ae3cf7 100644
--- a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
+++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
 // versions:
-// - protoc-gen-go-grpc v1.1.0
-// - protoc             v3.15.8
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
 // source: AsapoMonitoringQueryService.proto
 
 package generated_proto
@@ -25,6 +25,7 @@ type AsapoMonitoringQueryServiceClient interface {
 	GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error)
 	GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error)
 	GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error)
+	GetGroupDelay(ctx context.Context, in *GroupDelayQuery, opts ...grpc.CallOption) (*GroupDelayResponse, error)
 }
 
 type asapoMonitoringQueryServiceClient struct {
@@ -62,6 +63,15 @@ func (c *asapoMonitoringQueryServiceClient) GetDataPoints(ctx context.Context, i
 	return out, nil
 }
 
+func (c *asapoMonitoringQueryServiceClient) GetGroupDelay(ctx context.Context, in *GroupDelayQuery, opts ...grpc.CallOption) (*GroupDelayResponse, error) {
+	out := new(GroupDelayResponse)
+	err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetGroupDelay", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // AsapoMonitoringQueryServiceServer is the server API for AsapoMonitoringQueryService service.
 // All implementations must embed UnimplementedAsapoMonitoringQueryServiceServer
 // for forward compatibility
@@ -69,6 +79,7 @@ type AsapoMonitoringQueryServiceServer interface {
 	GetMetadata(context.Context, *Empty) (*MetadataResponse, error)
 	GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error)
 	GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error)
+	GetGroupDelay(context.Context, *GroupDelayQuery) (*GroupDelayResponse, error)
 	mustEmbedUnimplementedAsapoMonitoringQueryServiceServer()
 }
 
@@ -85,6 +96,9 @@ func (UnimplementedAsapoMonitoringQueryServiceServer) GetTopology(context.Contex
 func (UnimplementedAsapoMonitoringQueryServiceServer) GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method GetDataPoints not implemented")
 }
+func (UnimplementedAsapoMonitoringQueryServiceServer) GetGroupDelay(context.Context, *GroupDelayQuery) (*GroupDelayResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetGroupDelay not implemented")
+}
 func (UnimplementedAsapoMonitoringQueryServiceServer) mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() {
 }
 
@@ -153,6 +167,24 @@ func _AsapoMonitoringQueryService_GetDataPoints_Handler(srv interface{}, ctx con
 	return interceptor(ctx, in, info, handler)
 }
 
+func _AsapoMonitoringQueryService_GetGroupDelay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GroupDelayQuery)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AsapoMonitoringQueryServiceServer).GetGroupDelay(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/AsapoMonitoringQueryService/GetGroupDelay",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AsapoMonitoringQueryServiceServer).GetGroupDelay(ctx, req.(*GroupDelayQuery))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // AsapoMonitoringQueryService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringQueryService service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -172,6 +204,10 @@ var AsapoMonitoringQueryService_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "GetDataPoints",
 			Handler:    _AsapoMonitoringQueryService_GetDataPoints_Handler,
 		},
+		{
+			MethodName: "GetGroupDelay",
+			Handler:    _AsapoMonitoringQueryService_GetGroupDelay_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "AsapoMonitoringQueryService.proto",
diff --git a/common/networking/monitoring/AsapoMonitoringIngestService.proto b/common/networking/monitoring/AsapoMonitoringIngestService.proto
index cc3101df697998ffc1060c0c29af093b3831512e..a19e026972ddbbeb9841f2cf2c9d9a01a7a52238 100644
--- a/common/networking/monitoring/AsapoMonitoringIngestService.proto
+++ b/common/networking/monitoring/AsapoMonitoringIngestService.proto
@@ -32,10 +32,12 @@ message BrokerRequestDataPoint { // send by broker
     string beamtime = 4;
     string source = 5;
     string stream = 6;
+    string groupId = 7;
 
-    uint64 fileCount = 7;
+    uint64 fileCount = 8;
 
-    uint64 totalFileSize = 8;
+    uint64 totalFileSize = 9;
+    uint64 delayMs = 10;
 }
 
 message RdsMemoryDataPoint { // Send by RDS in fixed interval
diff --git a/common/networking/monitoring/AsapoMonitoringQueryService.proto b/common/networking/monitoring/AsapoMonitoringQueryService.proto
index ed6c46f598ead0f15af55eb96be28fd77fdc45ae..91d1c21d757ad6c7a9f963c448cf38542f2527c9 100644
--- a/common/networking/monitoring/AsapoMonitoringQueryService.proto
+++ b/common/networking/monitoring/AsapoMonitoringQueryService.proto
@@ -106,8 +106,25 @@ message TopologyResponse {
     repeated TopologyResponseEdge edges = 2;
 }
 
+message GroupDelayQuery {
+    uint64 fromTimestamp = 1;
+    uint64 toTimestamp = 2;
+
+    string beamtimeFilter = 3;
+}
+
+message GroupDelayResponseItem {
+    string groupId = 1;
+    uint32 delayMs = 2;
+}
+    
+message GroupDelayResponse {
+   repeated GroupDelayResponseItem groupIds = 1;
+}
+
 service AsapoMonitoringQueryService {
     rpc GetMetadata(Empty) returns (MetadataResponse) {}
     rpc GetTopology(ToplogyQuery) returns (TopologyResponse) {}
     rpc GetDataPoints(DataPointsQuery) returns (DataPointsResponse) {}
+    rpc GetGroupDelay(GroupDelayQuery) returns (GroupDelayResponse) {}
 }
diff --git a/deploy/build_env/services-linux/Dockerfile b/deploy/build_env/services-linux/Dockerfile
index 9290686f3f122bfeb045f155021591d5c51660a3..fe167ecf3a5d68dd084eb0701cd667c443787336 100644
--- a/deploy/build_env/services-linux/Dockerfile
+++ b/deploy/build_env/services-linux/Dockerfile
@@ -69,9 +69,6 @@ addresses =  {\n\
 "http" =  \"0.0.0.0\"\n\
 }\n\
 advertise_addr = \"127.0.0.1\"\n\
-node_meta = {\n\
-  ib_address = \"10.10.0.1\"\n\
-}\n\
 server=true\n\
 bootstrap_expect=1\n\
 telemetry = {\n\
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go
index 73a921332c5a3688c4edd12589de388d8737723e..88e6c8379675c7ddd76bec07d60a94f20602bacf 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.27.1
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringCommonService.proto
 
 package generated_proto
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go
index f9a471f2f64dbd955a0ccda10a06163e5958eac9..be5733a6c8e31252d650dd8765ccbfd93b5e3d6a 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.27.1
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringIngestService.proto
 
 package generated_proto
@@ -150,8 +150,10 @@ type BrokerRequestDataPoint struct {
 	Beamtime           string `protobuf:"bytes,4,opt,name=beamtime,proto3" json:"beamtime,omitempty"`
 	Source             string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty"`
 	Stream             string `protobuf:"bytes,6,opt,name=stream,proto3" json:"stream,omitempty"`
-	FileCount          uint64 `protobuf:"varint,7,opt,name=fileCount,proto3" json:"fileCount,omitempty"`
-	TotalFileSize      uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"`
+	GroupId            string `protobuf:"bytes,7,opt,name=groupId,proto3" json:"groupId,omitempty"`
+	FileCount          uint64 `protobuf:"varint,8,opt,name=fileCount,proto3" json:"fileCount,omitempty"`
+	TotalFileSize      uint64 `protobuf:"varint,9,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"`
+	DelayMs            uint64 `protobuf:"varint,10,opt,name=delayMs,proto3" json:"delayMs,omitempty"`
 }
 
 func (x *BrokerRequestDataPoint) Reset() {
@@ -228,6 +230,13 @@ func (x *BrokerRequestDataPoint) GetStream() string {
 	return ""
 }
 
+func (x *BrokerRequestDataPoint) GetGroupId() string {
+	if x != nil {
+		return x.GroupId
+	}
+	return ""
+}
+
 func (x *BrokerRequestDataPoint) GetFileCount() uint64 {
 	if x != nil {
 		return x.FileCount
@@ -242,6 +251,13 @@ func (x *BrokerRequestDataPoint) GetTotalFileSize() uint64 {
 	return 0
 }
 
+func (x *BrokerRequestDataPoint) GetDelayMs() uint64 {
+	if x != nil {
+		return x.DelayMs
+	}
+	return 0
+}
+
 type RdsMemoryDataPoint struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -779,7 +795,7 @@ var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{
 	0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65,
 	0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x74, 0x6f, 0x74,
 	0x61, 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73,
-	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65,
 	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
 	0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65,
 	0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c,
@@ -793,123 +809,126 @@ var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{
 	0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61,
 	0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
-	0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a,
-	0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53,
-	0x69, 0x7a, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72,
-	0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79,
-	0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42,
-	0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74,
-	0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42,
-	0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f,
-	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12,
-	0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49,
-	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75,
-	0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73,
-	0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74,
-	0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74,
-	0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73,
-	0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72,
-	0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65,
-	0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12,
-	0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65,
-	0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c,
-	0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72,
-	0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e,
-	0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01,
-	0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f,
-	0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16, 0x46, 0x64, 0x73, 0x54,
-	0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74,
-	0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f,
-	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
-	0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65,
-	0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16,
-	0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f,
-	0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43,
-	0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c,
-	0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74,
-	0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f,
-	0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54,
-	0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
-	0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72,
-	0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e,
-	0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a,
-	0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x72,
-	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
-	0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d,
-	0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, 0x54,
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
-	0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69,
-	0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50,
-	0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72,
-	0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x64, 0x73, 0x54, 0x6f,
-	0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54,
-	0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75,
-	0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79,
-	0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70,
-	0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xab, 0x01,
-	0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x72,
-	0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
-	0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69,
-	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
-	0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x4d, 0x0a, 0x15,
-	0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x42, 0x72,
-	0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50,
-	0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f,
-	0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x1f,
-	0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c,
+	0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69,
+	0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c,
+	0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d,
+	0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07,
+	0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d,
+	0x65, 0x6d, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a,
+	0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73,
+	0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75,
+	0x73, 0x65, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f,
+	0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73,
+	0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
+	0x69, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53,
+	0x74, 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63,
+	0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
+	0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62,
+	0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62,
+	0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
+	0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d,
+	0x69, 0x73, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73,
+	0x73, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65,
+	0x53, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69,
+	0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d,
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16,
+	0x46, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
+	0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e,
+	0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+	0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a,
+	0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
+	0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
+	0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69,
+	0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66,
+	0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61,
+	0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52,
+	0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50,
+	0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53,
+	0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65,
+	0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74,
+	0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69,
+	0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
+	0x22, 0xce, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74,
 	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12,
-	0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d,
-	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b,
-	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x67,
-	0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65,
-	0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46, 0x64, 0x73, 0x54, 0x6f,
-	0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61,
-	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x61, 0x70, 0x6f,
-	0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49, 0x6e, 0x73, 0x65, 0x72,
-	0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69,
-	0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61,
-	0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
-	0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x16, 0x49, 0x6e,
-	0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
-	0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74,
-	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a,
-	0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x13, 0x49, 0x6e, 0x73,
-	0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73,
-	0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72,
-	0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-	0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11,
-	0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x22, 0x0a, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+	0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64,
+	0x50, 0x32, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x24, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52,
+	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44,
+	0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65,
+	0x64, 0x50, 0x32, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a,
+	0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52,
+	0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64,
+	0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12,
+	0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61,
+	0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65,
+	0x6d, 0x6f, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67,
+	0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74,
+	0x73, 0x22, 0xab, 0x01, 0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e,
+	0x0a, 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0a, 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20,
+	0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73,
+	0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44,
+	0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65,
+	0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22,
+	0xa8, 0x01, 0x0a, 0x1f, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
+	0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a,
+	0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12,
+	0x49, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61,
+	0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46,
+	0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61,
+	0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64,
+	0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41,
+	0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e,
+	0x67, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49,
+	0x6e, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74,
+	0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76,
+	0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61,
+	0x69, 0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d,
+	0x0a, 0x16, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61,
+	0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65,
+	0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
+	0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a,
+	0x13, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f,
+	0x69, 0x6e, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73,
+	0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
+	0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
index 1176122762f618cec5eed92d1a57fa68f4d693fd..abe4edc729c568cc64d514a2b9f6bfaa3bcffe58 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: AsapoMonitoringIngestService.proto
 
 package generated_proto
 
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go
index a5e1eaf6db5634718e811b73779409db8015c564..e5d6e3658c17ccc1e26a90815fb25542391e04ff 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go
@@ -1,7 +1,7 @@
 // Code generated by protoc-gen-go. DO NOT EDIT.
 // versions:
-// 	protoc-gen-go v1.27.1
-// 	protoc        v3.15.8
+// 	protoc-gen-go v1.28.1
+// 	protoc        v3.19.4
 // source: AsapoMonitoringQueryService.proto
 
 package generated_proto
@@ -834,6 +834,171 @@ func (x *TopologyResponse) GetEdges() []*TopologyResponseEdge {
 	return nil
 }
 
+type GroupDelayQuery struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	FromTimestamp  uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"`
+	ToTimestamp    uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"`
+	BeamtimeFilter string `protobuf:"bytes,3,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"`
+}
+
+func (x *GroupDelayQuery) Reset() {
+	*x = GroupDelayQuery{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayQuery) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayQuery) ProtoMessage() {}
+
+func (x *GroupDelayQuery) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayQuery.ProtoReflect.Descriptor instead.
+func (*GroupDelayQuery) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *GroupDelayQuery) GetFromTimestamp() uint64 {
+	if x != nil {
+		return x.FromTimestamp
+	}
+	return 0
+}
+
+func (x *GroupDelayQuery) GetToTimestamp() uint64 {
+	if x != nil {
+		return x.ToTimestamp
+	}
+	return 0
+}
+
+func (x *GroupDelayQuery) GetBeamtimeFilter() string {
+	if x != nil {
+		return x.BeamtimeFilter
+	}
+	return ""
+}
+
+type GroupDelayResponseItem struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GroupId string `protobuf:"bytes,1,opt,name=groupId,proto3" json:"groupId,omitempty"`
+	DelayMs uint32 `protobuf:"varint,2,opt,name=delayMs,proto3" json:"delayMs,omitempty"`
+}
+
+func (x *GroupDelayResponseItem) Reset() {
+	*x = GroupDelayResponseItem{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayResponseItem) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayResponseItem) ProtoMessage() {}
+
+func (x *GroupDelayResponseItem) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayResponseItem.ProtoReflect.Descriptor instead.
+func (*GroupDelayResponseItem) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *GroupDelayResponseItem) GetGroupId() string {
+	if x != nil {
+		return x.GroupId
+	}
+	return ""
+}
+
+func (x *GroupDelayResponseItem) GetDelayMs() uint32 {
+	if x != nil {
+		return x.DelayMs
+	}
+	return 0
+}
+
+type GroupDelayResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	GroupIds []*GroupDelayResponseItem `protobuf:"bytes,1,rep,name=groupIds,proto3" json:"groupIds,omitempty"`
+}
+
+func (x *GroupDelayResponse) Reset() {
+	*x = GroupDelayResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_AsapoMonitoringQueryService_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GroupDelayResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GroupDelayResponse) ProtoMessage() {}
+
+func (x *GroupDelayResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_AsapoMonitoringQueryService_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GroupDelayResponse.ProtoReflect.Descriptor instead.
+func (*GroupDelayResponse) Descriptor() ([]byte, []int) {
+	return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *GroupDelayResponse) GetGroupIds() []*GroupDelayResponseItem {
+	if x != nil {
+		return x.GroupIds
+	}
+	return nil
+}
+
 var File_AsapoMonitoringQueryService_proto protoreflect.FileDescriptor
 
 var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{
@@ -973,26 +1138,47 @@ var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{
 	0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65,
 	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f,
 	0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x52, 0x05,
-	0x65, 0x64, 0x67, 0x65, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79,
-	0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f,
-	0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09,
-	0x45, 0x78, 0x61, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a,
-	0x75, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70,
-	0x10, 0x02, 0x32, 0xb6, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69,
-	0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
-	0x61, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61,
-	0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31,
-	0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e,
-	0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54,
-	0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-	0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e,
-	0x74, 0x73, 0x12, 0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51,
-	0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e,
-	0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x65, 0x64, 0x67, 0x65, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44,
+	0x65, 0x6c, 0x61, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x72, 0x6f,
+	0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04,
+	0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
+	0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74,
+	0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x4c, 0x0a, 0x16, 0x47, 0x72, 0x6f,
+	0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x49,
+	0x74, 0x65, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x18, 0x0a,
+	0x07, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
+	0x64, 0x65, 0x6c, 0x61, 0x79, 0x4d, 0x73, 0x22, 0x49, 0x0a, 0x12, 0x47, 0x72, 0x6f, 0x75, 0x70,
+	0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a,
+	0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49,
+	0x64, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f,
+	0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64,
+	0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x51, 0x55, 0x45,
+	0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x45, 0x78, 0x61,
+	0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a, 0x75, 0x73, 0x74,
+	0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70, 0x10, 0x02, 0x32,
+	0xf0, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72,
+	0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
+	0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x06,
+	0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+	0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0b, 0x47,
+	0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e, 0x54, 0x6f, 0x70,
+	0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54, 0x6f, 0x70, 0x6f,
+	0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38,
+	0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12,
+	0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72,
+	0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x47,
+	0x72, 0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x10, 0x2e, 0x47, 0x72, 0x6f, 0x75,
+	0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x47, 0x72,
+	0x6f, 0x75, 0x70, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+	0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
+	0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -1008,7 +1194,7 @@ func file_AsapoMonitoringQueryService_proto_rawDescGZIP() []byte {
 }
 
 var file_AsapoMonitoringQueryService_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
+var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
 var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{
 	(PipelineConnectionQueryMode)(0),   // 0: PipelineConnectionQueryMode
 	(*DataPointsQuery)(nil),            // 1: DataPointsQuery
@@ -1022,7 +1208,10 @@ var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{
 	(*TopologyResponseNode)(nil),       // 9: TopologyResponseNode
 	(*TopologyResponseEdge)(nil),       // 10: TopologyResponseEdge
 	(*TopologyResponse)(nil),           // 11: TopologyResponse
-	(*Empty)(nil),                      // 12: Empty
+	(*GroupDelayQuery)(nil),            // 12: GroupDelayQuery
+	(*GroupDelayResponseItem)(nil),     // 13: GroupDelayResponseItem
+	(*GroupDelayResponse)(nil),         // 14: GroupDelayResponse
+	(*Empty)(nil),                      // 15: Empty
 }
 var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{
 	0,  // 0: DataPointsQuery.pipelineQueryMode:type_name -> PipelineConnectionQueryMode
@@ -1032,17 +1221,20 @@ var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{
 	5,  // 4: DataPointsResponse.memoryUsages:type_name -> RdsMemoryUsageDataPoint
 	9,  // 5: TopologyResponse.nodes:type_name -> TopologyResponseNode
 	10, // 6: TopologyResponse.edges:type_name -> TopologyResponseEdge
-	12, // 7: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty
-	8,  // 8: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery
-	1,  // 9: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery
-	7,  // 10: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse
-	11, // 11: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse
-	6,  // 12: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse
-	10, // [10:13] is the sub-list for method output_type
-	7,  // [7:10] is the sub-list for method input_type
-	7,  // [7:7] is the sub-list for extension type_name
-	7,  // [7:7] is the sub-list for extension extendee
-	0,  // [0:7] is the sub-list for field type_name
+	13, // 7: GroupDelayResponse.groupIds:type_name -> GroupDelayResponseItem
+	15, // 8: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty
+	8,  // 9: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery
+	1,  // 10: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery
+	12, // 11: AsapoMonitoringQueryService.GetGroupDelay:input_type -> GroupDelayQuery
+	7,  // 12: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse
+	11, // 13: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse
+	6,  // 14: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse
+	14, // 15: AsapoMonitoringQueryService.GetGroupDelay:output_type -> GroupDelayResponse
+	12, // [12:16] is the sub-list for method output_type
+	8,  // [8:12] is the sub-list for method input_type
+	8,  // [8:8] is the sub-list for extension type_name
+	8,  // [8:8] is the sub-list for extension extendee
+	0,  // [0:8] is the sub-list for field type_name
 }
 
 func init() { file_AsapoMonitoringQueryService_proto_init() }
@@ -1184,6 +1376,42 @@ func file_AsapoMonitoringQueryService_proto_init() {
 				return nil
 			}
 		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayQuery); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayResponseItem); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_AsapoMonitoringQueryService_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GroupDelayResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -1191,7 +1419,7 @@ func file_AsapoMonitoringQueryService_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_AsapoMonitoringQueryService_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   11,
+			NumMessages:   14,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
index a3ac238cdfe811a76e3c447369996f5990b289aa..e8cf3493af77686d3d60aeca413274d400ae3cf7 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go
@@ -1,4 +1,8 @@
 // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.2.0
+// - protoc             v3.19.4
+// source: AsapoMonitoringQueryService.proto
 
 package generated_proto
 
@@ -21,6 +25,7 @@ type AsapoMonitoringQueryServiceClient interface {
 	GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error)
 	GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error)
 	GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error)
+	GetGroupDelay(ctx context.Context, in *GroupDelayQuery, opts ...grpc.CallOption) (*GroupDelayResponse, error)
 }
 
 type asapoMonitoringQueryServiceClient struct {
@@ -58,6 +63,15 @@ func (c *asapoMonitoringQueryServiceClient) GetDataPoints(ctx context.Context, i
 	return out, nil
 }
 
+func (c *asapoMonitoringQueryServiceClient) GetGroupDelay(ctx context.Context, in *GroupDelayQuery, opts ...grpc.CallOption) (*GroupDelayResponse, error) {
+	out := new(GroupDelayResponse)
+	err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetGroupDelay", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // AsapoMonitoringQueryServiceServer is the server API for AsapoMonitoringQueryService service.
 // All implementations must embed UnimplementedAsapoMonitoringQueryServiceServer
 // for forward compatibility
@@ -65,6 +79,7 @@ type AsapoMonitoringQueryServiceServer interface {
 	GetMetadata(context.Context, *Empty) (*MetadataResponse, error)
 	GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error)
 	GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error)
+	GetGroupDelay(context.Context, *GroupDelayQuery) (*GroupDelayResponse, error)
 	mustEmbedUnimplementedAsapoMonitoringQueryServiceServer()
 }
 
@@ -81,6 +96,9 @@ func (UnimplementedAsapoMonitoringQueryServiceServer) GetTopology(context.Contex
 func (UnimplementedAsapoMonitoringQueryServiceServer) GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method GetDataPoints not implemented")
 }
+func (UnimplementedAsapoMonitoringQueryServiceServer) GetGroupDelay(context.Context, *GroupDelayQuery) (*GroupDelayResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetGroupDelay not implemented")
+}
 func (UnimplementedAsapoMonitoringQueryServiceServer) mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() {
 }
 
@@ -149,6 +167,24 @@ func _AsapoMonitoringQueryService_GetDataPoints_Handler(srv interface{}, ctx con
 	return interceptor(ctx, in, info, handler)
 }
 
+func _AsapoMonitoringQueryService_GetGroupDelay_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GroupDelayQuery)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(AsapoMonitoringQueryServiceServer).GetGroupDelay(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/AsapoMonitoringQueryService/GetGroupDelay",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(AsapoMonitoringQueryServiceServer).GetGroupDelay(ctx, req.(*GroupDelayQuery))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // AsapoMonitoringQueryService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringQueryService service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -168,6 +204,10 @@ var AsapoMonitoringQueryService_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "GetDataPoints",
 			Handler:    _AsapoMonitoringQueryService_GetDataPoints_Handler,
 		},
+		{
+			MethodName: "GetGroupDelay",
+			Handler:    _AsapoMonitoringQueryService_GetGroupDelay_Handler,
+		},
 	},
 	Streams:  []grpc.StreamDesc{},
 	Metadata: "AsapoMonitoringQueryService.proto",
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go
index 376cbd9a1d9913b79991872f57eb024b47607208..49374fc621b516e6551897d2ec88f00db0143bcf 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go
@@ -37,9 +37,9 @@ func (s *IngestServer) InsertReceiverDataPoints(ctx context.Context, data *pb.Re
 				"receiverName":       data.ReceiverName,
 				"pipelineStepId":     dataPoint.PipelineStepId,
 				"producerInstanceId": dataPoint.ProducerInstanceId,
-				"beamtime": dataPoint.Beamtime,
-				"source":   dataPoint.Source,
-				"stream":   dataPoint.Stream,
+				"beamtime":           dataPoint.Beamtime,
+				"source":             dataPoint.Source,
+				"stream":             dataPoint.Stream,
 			},
 			map[string]interface{}{
 				"totalInputFileSize":       int64(dataPoint.TotalFileSize),
@@ -125,10 +125,12 @@ func (s *IngestServer) InsertBrokerDataPoints(ctx context.Context, data *pb.Brok
 				"beamtime": dataPoint.Beamtime,
 				"source":   dataPoint.Source,
 				"stream":   dataPoint.Stream,
+				"groupId":  dataPoint.GroupId,
 			},
 			map[string]interface{}{
 				"requestedFileCount":     int64(dataPoint.FileCount),
 				"totalRequestedFileSize": int64(dataPoint.TotalFileSize),
+				"delayMs":                int64(dataPoint.DelayMs),
 			},
 			timestamp,
 		)
diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go
index e35fd11ab803c65d94b3243b3d45e730b9615d86..e5911d61d3b6b9acb5752d838d28f51168ee17ac 100644
--- a/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go
+++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go
@@ -9,6 +9,7 @@ import (
 	"github.com/influxdata/influxdb-client-go/v2/api"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
+	"sort"
 	"strconv"
 	"strings"
 )
@@ -21,13 +22,13 @@ type QueryServer struct {
 }
 
 func (s *QueryServer) GetMetadata(ctx context.Context, _ *pb.Empty) (*pb.MetadataResponse, error) {
-	result, err := s.dbQueryApi.Query(ctx, "" +
-		"tagValues = (bucket, tag, predicate=(r) => true, start=-30d) =>\n" +
-		" from(bucket: bucket)\n" +
-		"  |> range(start: start)\n" +
-		"  |> filter(fn: predicate)\n" +
-		"  |> keep(columns: [tag])\n" +
-		"  |> group()\n" +
+	result, err := s.dbQueryApi.Query(ctx, ""+
+		"tagValues = (bucket, tag, predicate=(r) => true, start=-30d) =>\n"+
+		" from(bucket: bucket)\n"+
+		"  |> range(start: start)\n"+
+		"  |> filter(fn: predicate)\n"+
+		"  |> keep(columns: [tag])\n"+
+		"  |> group()\n"+
 		"  |> distinct(column: tag)"+
 		"tagValues(bucket: \""+s.settings.InfluxDbDatabase+"\", tag: \"beamtime\", predicate: (r) => true, start: -30d)")
 
@@ -49,8 +50,9 @@ func (s *QueryServer) GetMetadata(ctx context.Context, _ *pb.Empty) (*pb.Metadat
 }
 
 func createFilterElement(tagName string, tagValue string) string {
-	return "r[\"" + tagName + "\"] == \""+tagValue+"\""
+	return "r[\"" + tagName + "\"] == \"" + tagValue + "\""
 }
+
 type filterGenerator func(*pb.DataPointsQuery) string
 
 func createFilter(query *pb.DataPointsQuery, generator filterGenerator) string {
@@ -171,7 +173,6 @@ func (s *QueryServer) GetDataPoints(ctx context.Context, query *pb.DataPointsQue
 	endTime := strconv.FormatUint(query.ToTimestamp, 10)
 	intervalInSec := 5
 
-
 	if query.BeamtimeFilter == "" {
 		return nil, status.Errorf(codes.InvalidArgument, "Beamtime is required")
 	}
@@ -229,7 +230,7 @@ func queryTransferSpeed(s *QueryServer, ctx context.Context, startTime string, e
 		" |> range(start: "+startTime+", stop: "+endTime+")"+
 		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\" or r._measurement == \""+dbMeasurementRdsFileRequests+"\" or r._measurement == \""+dbMeasurementFtsTransfers+"\")"+
 		" |> filter(fn: (r) => r._field == \"totalInputFileSize\" or r._field == \"totalRequestedFileSize\" or r._field == \"totalRdsOutputFileSize\" or r._field == \"totalFtsTransferredFileSize\")"+
-		filter +
+		filter+
 		" |> group(columns: [\"_field\"])"+
 		" |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+
 		" |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
@@ -280,7 +281,7 @@ func queryFileRate(s *QueryServer, ctx context.Context, startTime string, endTim
 		" |> range(start: "+startTime+", stop: "+endTime+")"+
 		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementRdsFileRequests+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\" or r._measurement == \""+dbMeasurementFtsTransfers+"\")"+
 		" |> filter(fn: (r) => r._field == \"totalRdsHits\" or r._field == \"totalRdsMisses\" or r._field == \"requestedFileCount\" or r._field == \"ftsFileCount\")"+
-		filter +
+		filter+
 		" |> group(columns: [\"_field\"])"+
 		" |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+
 		" |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
@@ -330,7 +331,7 @@ func queryTaskTime(s *QueryServer, ctx context.Context, startTime string, endTim
 		" |> range(start: "+startTime+", stop: "+endTime+")"+
 		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementRdsFileRequests+"\")"+
 		" |> filter(fn: (r) => r._field == \"avgTransferReceiveTimeUs\" or r._field == \"avgWriteIoTimeUs\" or r._field == \"avgDbTimeUs\" or r._field == \"avgRdsOutputTransferTimeUs\")"+
-		filter +
+		filter+
 		" |> group(columns: [\"_field\"])"+
 		" |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: mean, createEmpty: true)"+
 		" |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
@@ -380,7 +381,7 @@ func queryMemoryUsage(s *QueryServer, ctx context.Context, startTime string, end
 		" |> range(start: "+startTime+", stop: "+endTime+")"+
 		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementRdsCacheMemoryUsage+"\")"+
 		" |> filter(fn: (r) => r._field == \"rdsCacheUsedBytes\")"+
-		filter +
+		filter+
 		" |> group(columns: [\"_field\"])"+
 		" |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+
 		" |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")",
@@ -418,9 +419,9 @@ func (s *QueryServer) GetTopology(ctx context.Context, query *pb.ToplogyQuery) (
 
 	result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+
 		" |> range(start: "+startTime+", stop: "+endTime+")"+
-		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\")" +
-		" |> filter(fn: (r) => " + createFilterElement("beamtime", query.BeamtimeFilter) + ")" +
-		" |> keep(columns: [\"receiverName\", \"brokerName\", \"pipelineStepId\", \"source\", \"producerInstanceId\", \"consumerInstanceId\"])" +
+		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\")"+
+		" |> filter(fn: (r) => "+createFilterElement("beamtime", query.BeamtimeFilter)+")"+
+		" |> keep(columns: [\"receiverName\", \"brokerName\", \"pipelineStepId\", \"source\", \"producerInstanceId\", \"consumerInstanceId\"])"+
 		" |> group()",
 	)
 
@@ -456,7 +457,7 @@ func (s *QueryServer) GetTopology(ctx context.Context, query *pb.ToplogyQuery) (
 
 	for result.Next() {
 		if result.Record().Values()["receiverName"] != nil { // data is coming from receiver => means it must be a producer
-			stepId,ok := result.Record().Values()["pipelineStepId"].(string)
+			stepId, ok := result.Record().Values()["pipelineStepId"].(string)
 			if !ok {
 				stepId = "defaultStep"
 			}
@@ -612,9 +613,9 @@ func (s *QueryServer) GetTopology(ctx context.Context, query *pb.ToplogyQuery) (
 
 				for sourceId := range step.consumesSourceId {
 					edges = append(edges, PipelineEdgeInfo{
-						fromStepId: unkStep,
-						toStepId:   stepId,
-						sourceId:   sourceId,
+						fromStepId:        unkStep,
+						toStepId:          stepId,
+						sourceId:          sourceId,
 						involvedReceivers: nil,
 					})
 				}
@@ -674,3 +675,47 @@ func (s *QueryServer) GetTopology(ctx context.Context, query *pb.ToplogyQuery) (
 
 	return &response, nil
 }
+
+func (s *QueryServer) GetGroupDelay(ctx context.Context, query *pb.GroupDelayQuery) (*pb.GroupDelayResponse, error) {
+
+	if query.BeamtimeFilter == "" {
+		return nil, status.Errorf(codes.InvalidArgument, "Beamtime is required")
+	}
+
+	if doesStringContainsDangerousElements(query.BeamtimeFilter) {
+		return nil, errors.New("some input characters are not allowed")
+	}
+
+	startTime := strconv.FormatUint(query.FromTimestamp, 10)
+	endTime := strconv.FormatUint(query.ToTimestamp, 10)
+
+	result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+
+		" |> range(start: "+startTime+", stop: "+endTime+")"+
+		" |> filter(fn: (r) => r._measurement == \""+dbMeasurementBrokerFileRequests+"\""+" and r.brokerCommand == \"next\")"+
+		" |> filter(fn: (r) => r.beamtime == \""+query.BeamtimeFilter+"\" r._field == \"delayMs\""+
+		" |> group(columns: [\"groupId\"])"+
+		" |> last()"+
+		" |> keep(columns: [\"groupId\", \"_value\"])"+
+		" |> group()",
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	response := pb.GroupDelayResponse{}
+	for result.Next() {
+		if result.Record().Values()["groupId"] != nil && result.Record().Value() != nil {
+			item := pb.GroupDelayResponseItem{
+				GroupId: result.Record().Values()["groupId"].(string),
+				DelayMs: result.Record().Value().(uint32),
+			}
+			response.GroupIds = append(response.GroupIds, &item)
+		}
+	}
+
+	sort.SliceStable(response.GroupIds, func(i, j int) bool {
+		return response.GroupIds[i].DelayMs > response.GroupIds[j].DelayMs
+	})
+
+	return &response, nil
+}
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts
index 2af6b22ec9c58aa1fc67722489e204127b779c25..367558e9f5d978b83347238dcb03eb2e73ab13a2 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts
@@ -76,12 +76,18 @@ export class BrokerRequestDataPoint extends jspb.Message {
   getStream(): string;
   setStream(value: string): BrokerRequestDataPoint;
 
+  getGroupid(): string;
+  setGroupid(value: string): BrokerRequestDataPoint;
+
   getFilecount(): number;
   setFilecount(value: number): BrokerRequestDataPoint;
 
   getTotalfilesize(): number;
   setTotalfilesize(value: number): BrokerRequestDataPoint;
 
+  getDelayms(): number;
+  setDelayms(value: number): BrokerRequestDataPoint;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): BrokerRequestDataPoint.AsObject;
   static toObject(includeInstance: boolean, msg: BrokerRequestDataPoint): BrokerRequestDataPoint.AsObject;
@@ -98,8 +104,10 @@ export namespace BrokerRequestDataPoint {
     beamtime: string,
     source: string,
     stream: string,
+    groupid: string,
     filecount: number,
     totalfilesize: number,
+    delayms: number,
   }
 }
 
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js
index 74007ae8ee9e708271df16b6059bdc37322c1ed0..d6e2633642221957fabc9efabc551cdc304aa6f9 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js
@@ -631,8 +631,10 @@ proto.BrokerRequestDataPoint.toObject = function(includeInstance, msg) {
     beamtime: jspb.Message.getFieldWithDefault(msg, 4, ""),
     source: jspb.Message.getFieldWithDefault(msg, 5, ""),
     stream: jspb.Message.getFieldWithDefault(msg, 6, ""),
-    filecount: jspb.Message.getFieldWithDefault(msg, 7, 0),
-    totalfilesize: jspb.Message.getFieldWithDefault(msg, 8, 0)
+    groupid: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    filecount: jspb.Message.getFieldWithDefault(msg, 8, 0),
+    totalfilesize: jspb.Message.getFieldWithDefault(msg, 9, 0),
+    delayms: jspb.Message.getFieldWithDefault(msg, 10, 0)
   };
 
   if (includeInstance) {
@@ -694,13 +696,21 @@ proto.BrokerRequestDataPoint.deserializeBinaryFromReader = function(msg, reader)
       msg.setStream(value);
       break;
     case 7:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGroupid(value);
+      break;
+    case 8:
       var value = /** @type {number} */ (reader.readUint64());
       msg.setFilecount(value);
       break;
-    case 8:
+    case 9:
       var value = /** @type {number} */ (reader.readUint64());
       msg.setTotalfilesize(value);
       break;
+    case 10:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setDelayms(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -772,17 +782,31 @@ proto.BrokerRequestDataPoint.serializeBinaryToWriter = function(message, writer)
       f
     );
   }
+  f = message.getGroupid();
+  if (f.length > 0) {
+    writer.writeString(
+      7,
+      f
+    );
+  }
   f = message.getFilecount();
   if (f !== 0) {
     writer.writeUint64(
-      7,
+      8,
       f
     );
   }
   f = message.getTotalfilesize();
   if (f !== 0) {
     writer.writeUint64(
-      8,
+      9,
+      f
+    );
+  }
+  f = message.getDelayms();
+  if (f !== 0) {
+    writer.writeUint64(
+      10,
       f
     );
   }
@@ -898,11 +922,29 @@ proto.BrokerRequestDataPoint.prototype.setStream = function(value) {
 
 
 /**
- * optional uint64 fileCount = 7;
+ * optional string groupId = 7;
+ * @return {string}
+ */
+proto.BrokerRequestDataPoint.prototype.getGroupid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.BrokerRequestDataPoint} returns this
+ */
+proto.BrokerRequestDataPoint.prototype.setGroupid = function(value) {
+  return jspb.Message.setProto3StringField(this, 7, value);
+};
+
+
+/**
+ * optional uint64 fileCount = 8;
  * @return {number}
  */
 proto.BrokerRequestDataPoint.prototype.getFilecount = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0));
 };
 
 
@@ -911,16 +953,16 @@ proto.BrokerRequestDataPoint.prototype.getFilecount = function() {
  * @return {!proto.BrokerRequestDataPoint} returns this
  */
 proto.BrokerRequestDataPoint.prototype.setFilecount = function(value) {
-  return jspb.Message.setProto3IntField(this, 7, value);
+  return jspb.Message.setProto3IntField(this, 8, value);
 };
 
 
 /**
- * optional uint64 totalFileSize = 8;
+ * optional uint64 totalFileSize = 9;
  * @return {number}
  */
 proto.BrokerRequestDataPoint.prototype.getTotalfilesize = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0));
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
 };
 
 
@@ -929,7 +971,25 @@ proto.BrokerRequestDataPoint.prototype.getTotalfilesize = function() {
  * @return {!proto.BrokerRequestDataPoint} returns this
  */
 proto.BrokerRequestDataPoint.prototype.setTotalfilesize = function(value) {
-  return jspb.Message.setProto3IntField(this, 8, value);
+  return jspb.Message.setProto3IntField(this, 9, value);
+};
+
+
+/**
+ * optional uint64 delayMs = 10;
+ * @return {number}
+ */
+proto.BrokerRequestDataPoint.prototype.getDelayms = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 10, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.BrokerRequestDataPoint} returns this
+ */
+proto.BrokerRequestDataPoint.prototype.setDelayms = function(value) {
+  return jspb.Message.setProto3IntField(this, 10, value);
 };
 
 
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts
index 9cf0303ad5c20b969e1ff629757da3cf301237e8..2a969296842f974f7ec573a98aea65a4a2ff2847 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts
@@ -30,6 +30,13 @@ export class AsapoMonitoringQueryServiceClient {
                response: AsapoMonitoringQueryService_pb.DataPointsResponse) => void
   ): grpcWeb.ClientReadableStream<AsapoMonitoringQueryService_pb.DataPointsResponse>;
 
+  getGroupDelay(
+    request: AsapoMonitoringQueryService_pb.GroupDelayQuery,
+    metadata: grpcWeb.Metadata | undefined,
+    callback: (err: grpcWeb.Error,
+               response: AsapoMonitoringQueryService_pb.GroupDelayResponse) => void
+  ): grpcWeb.ClientReadableStream<AsapoMonitoringQueryService_pb.GroupDelayResponse>;
+
 }
 
 export class AsapoMonitoringQueryServicePromiseClient {
@@ -52,5 +59,10 @@ export class AsapoMonitoringQueryServicePromiseClient {
     metadata?: grpcWeb.Metadata
   ): Promise<AsapoMonitoringQueryService_pb.DataPointsResponse>;
 
+  getGroupDelay(
+    request: AsapoMonitoringQueryService_pb.GroupDelayQuery,
+    metadata?: grpcWeb.Metadata
+  ): Promise<AsapoMonitoringQueryService_pb.GroupDelayResponse>;
+
 }
 
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js
index 5243339d99c51883d019c756e83b073cd61b2109..ab80ef904e423e31fe60a0276a97834f50d8c2f7 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js
@@ -311,5 +311,85 @@ proto.AsapoMonitoringQueryServicePromiseClient.prototype.getDataPoints =
 };
 
 
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.GroupDelayQuery,
+ *   !proto.GroupDelayResponse>}
+ */
+const methodDescriptor_AsapoMonitoringQueryService_GetGroupDelay = new grpc.web.MethodDescriptor(
+  '/AsapoMonitoringQueryService/GetGroupDelay',
+  grpc.web.MethodType.UNARY,
+  proto.GroupDelayQuery,
+  proto.GroupDelayResponse,
+  /**
+   * @param {!proto.GroupDelayQuery} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GroupDelayResponse.deserializeBinary
+);
+
+
+/**
+ * @const
+ * @type {!grpc.web.AbstractClientBase.MethodInfo<
+ *   !proto.GroupDelayQuery,
+ *   !proto.GroupDelayResponse>}
+ */
+const methodInfo_AsapoMonitoringQueryService_GetGroupDelay = new grpc.web.AbstractClientBase.MethodInfo(
+  proto.GroupDelayResponse,
+  /**
+   * @param {!proto.GroupDelayQuery} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.GroupDelayResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.GroupDelayQuery} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.Error, ?proto.GroupDelayResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.GroupDelayResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.AsapoMonitoringQueryServiceClient.prototype.getGroupDelay =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/AsapoMonitoringQueryService/GetGroupDelay',
+      request,
+      metadata || {},
+      methodDescriptor_AsapoMonitoringQueryService_GetGroupDelay,
+      callback);
+};
+
+
+/**
+ * @param {!proto.GroupDelayQuery} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.GroupDelayResponse>}
+ *     Promise that resolves to the response
+ */
+proto.AsapoMonitoringQueryServicePromiseClient.prototype.getGroupDelay =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/AsapoMonitoringQueryService/GetGroupDelay',
+      request,
+      metadata || {},
+      methodDescriptor_AsapoMonitoringQueryService_GetGroupDelay);
+};
+
+
 module.exports = proto;
 
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts
index c0268750ce019be7d06ea82688a4055bd35720e9..c267fcff9f90510eaade72e893e3944319d3a7f7 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts
@@ -16,9 +16,6 @@ export class DataPointsQuery extends jspb.Message {
   getSourcefilter(): string;
   setSourcefilter(value: string): DataPointsQuery;
 
-  getStreamfilter(): string;
-  setStreamfilter(value: string): DataPointsQuery;
-
   getReceiverfilter(): string;
   setReceiverfilter(value: string): DataPointsQuery;
 
@@ -28,8 +25,8 @@ export class DataPointsQuery extends jspb.Message {
   getTopipelinestepfilter(): string;
   setTopipelinestepfilter(value: string): DataPointsQuery;
 
-  getPipelinequerymode(): ipelineConnectionQueryMode;
-  setPipelinequerymode(value: ipelineConnectionQueryMode): DataPointsQuery;
+  getPipelinequerymode(): PipelineConnectionQueryMode;
+  setPipelinequerymode(value: PipelineConnectionQueryMode): DataPointsQuery;
 
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): DataPointsQuery.AsObject;
@@ -45,11 +42,10 @@ export namespace DataPointsQuery {
     totimestamp: number,
     beamtimefilter: string,
     sourcefilter: string,
-    streamfilter: string,
     receiverfilter: string,
     frompipelinestepfilter: string,
     topipelinestepfilter: string,
-    pipelinequerymode: ipelineConnectionQueryMode,
+    pipelinequerymode: PipelineConnectionQueryMode,
   }
 }
 
@@ -349,6 +345,74 @@ export namespace TopologyResponse {
   }
 }
 
+export class GroupDelayQuery extends jspb.Message {
+  getFromtimestamp(): number;
+  setFromtimestamp(value: number): GroupDelayQuery;
+
+  getTotimestamp(): number;
+  setTotimestamp(value: number): GroupDelayQuery;
+
+  getBeamtimefilter(): string;
+  setBeamtimefilter(value: string): GroupDelayQuery;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): GroupDelayQuery.AsObject;
+  static toObject(includeInstance: boolean, msg: GroupDelayQuery): GroupDelayQuery.AsObject;
+  static serializeBinaryToWriter(message: GroupDelayQuery, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): GroupDelayQuery;
+  static deserializeBinaryFromReader(message: GroupDelayQuery, reader: jspb.BinaryReader): GroupDelayQuery;
+}
+
+export namespace GroupDelayQuery {
+  export type AsObject = {
+    fromtimestamp: number,
+    totimestamp: number,
+    beamtimefilter: string,
+  }
+}
+
+export class GroupDelayResponseItem extends jspb.Message {
+  getGroupid(): string;
+  setGroupid(value: string): GroupDelayResponseItem;
+
+  getDelayms(): number;
+  setDelayms(value: number): GroupDelayResponseItem;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): GroupDelayResponseItem.AsObject;
+  static toObject(includeInstance: boolean, msg: GroupDelayResponseItem): GroupDelayResponseItem.AsObject;
+  static serializeBinaryToWriter(message: GroupDelayResponseItem, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): GroupDelayResponseItem;
+  static deserializeBinaryFromReader(message: GroupDelayResponseItem, reader: jspb.BinaryReader): GroupDelayResponseItem;
+}
+
+export namespace GroupDelayResponseItem {
+  export type AsObject = {
+    groupid: string,
+    delayms: number,
+  }
+}
+
+export class GroupDelayResponse extends jspb.Message {
+  getGroupidsList(): Array<GroupDelayResponseItem>;
+  setGroupidsList(value: Array<GroupDelayResponseItem>): GroupDelayResponse;
+  clearGroupidsList(): GroupDelayResponse;
+  addGroupids(value?: GroupDelayResponseItem, index?: number): GroupDelayResponseItem;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): GroupDelayResponse.AsObject;
+  static toObject(includeInstance: boolean, msg: GroupDelayResponse): GroupDelayResponse.AsObject;
+  static serializeBinaryToWriter(message: GroupDelayResponse, writer: jspb.BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): GroupDelayResponse;
+  static deserializeBinaryFromReader(message: GroupDelayResponse, reader: jspb.BinaryReader): GroupDelayResponse;
+}
+
+export namespace GroupDelayResponse {
+  export type AsObject = {
+    groupidsList: Array<GroupDelayResponseItem.AsObject>,
+  }
+}
+
 export enum PipelineConnectionQueryMode { 
   INVALID_QUERY_MODE = 0,
   EXACTPATH = 1,
diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js
index cad97bb60ada849f9f2322e1f190a5c425dcd7bd..c3820257486ee969d9b75544777c1f81e48adaa3 100644
--- a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js
+++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js
@@ -19,6 +19,9 @@ var AsapoMonitoringCommonService_pb = require('./AsapoMonitoringCommonService_pb
 goog.object.extend(proto, AsapoMonitoringCommonService_pb);
 goog.exportSymbol('proto.DataPointsQuery', null, global);
 goog.exportSymbol('proto.DataPointsResponse', null, global);
+goog.exportSymbol('proto.GroupDelayQuery', null, global);
+goog.exportSymbol('proto.GroupDelayResponse', null, global);
+goog.exportSymbol('proto.GroupDelayResponseItem', null, global);
 goog.exportSymbol('proto.MetadataResponse', null, global);
 goog.exportSymbol('proto.PipelineConnectionQueryMode', null, global);
 goog.exportSymbol('proto.RdsMemoryUsageDataPoint', null, global);
@@ -260,6 +263,69 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.TopologyResponse.displayName = 'proto.TopologyResponse';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GroupDelayQuery = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GroupDelayQuery, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GroupDelayQuery.displayName = 'proto.GroupDelayQuery';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GroupDelayResponseItem = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.GroupDelayResponseItem, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GroupDelayResponseItem.displayName = 'proto.GroupDelayResponseItem';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.GroupDelayResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.GroupDelayResponse.repeatedFields_, null);
+};
+goog.inherits(proto.GroupDelayResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.GroupDelayResponse.displayName = 'proto.GroupDelayResponse';
+}
 
 
 
@@ -296,11 +362,10 @@ proto.DataPointsQuery.toObject = function(includeInstance, msg) {
     totimestamp: jspb.Message.getFieldWithDefault(msg, 2, 0),
     beamtimefilter: jspb.Message.getFieldWithDefault(msg, 4, ""),
     sourcefilter: jspb.Message.getFieldWithDefault(msg, 5, ""),
-    streamfilter: jspb.Message.getFieldWithDefault(msg, 6, ""),
-    receiverfilter: jspb.Message.getFieldWithDefault(msg, 7, ""),
-    frompipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 8, ""),
-    topipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 9, ""),
-    pipelinequerymode: jspb.Message.getFieldWithDefault(msg, 10, 0)
+    receiverfilter: jspb.Message.getFieldWithDefault(msg, 6, ""),
+    frompipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 7, ""),
+    topipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 8, ""),
+    pipelinequerymode: jspb.Message.getFieldWithDefault(msg, 9, 0)
   };
 
   if (includeInstance) {
@@ -354,22 +419,18 @@ proto.DataPointsQuery.deserializeBinaryFromReader = function(msg, reader) {
       msg.setSourcefilter(value);
       break;
     case 6:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setStreamfilter(value);
-      break;
-    case 7:
       var value = /** @type {string} */ (reader.readString());
       msg.setReceiverfilter(value);
       break;
-    case 8:
+    case 7:
       var value = /** @type {string} */ (reader.readString());
       msg.setFrompipelinestepfilter(value);
       break;
-    case 9:
+    case 8:
       var value = /** @type {string} */ (reader.readString());
       msg.setTopipelinestepfilter(value);
       break;
-    case 10:
+    case 9:
       var value = /** @type {!proto.PipelineConnectionQueryMode} */ (reader.readEnum());
       msg.setPipelinequerymode(value);
       break;
@@ -430,38 +491,31 @@ proto.DataPointsQuery.serializeBinaryToWriter = function(message, writer) {
       f
     );
   }
-  f = message.getStreamfilter();
-  if (f.length > 0) {
-    writer.writeString(
-      6,
-      f
-    );
-  }
   f = message.getReceiverfilter();
   if (f.length > 0) {
     writer.writeString(
-      7,
+      6,
       f
     );
   }
   f = message.getFrompipelinestepfilter();
   if (f.length > 0) {
     writer.writeString(
-      8,
+      7,
       f
     );
   }
   f = message.getTopipelinestepfilter();
   if (f.length > 0) {
     writer.writeString(
-      9,
+      8,
       f
     );
   }
   f = message.getPipelinequerymode();
   if (f !== 0.0) {
     writer.writeEnum(
-      10,
+      9,
       f
     );
   }
@@ -541,29 +595,11 @@ proto.DataPointsQuery.prototype.setSourcefilter = function(value) {
 
 
 /**
- * optional string streamFilter = 6;
- * @return {string}
- */
-proto.DataPointsQuery.prototype.getStreamfilter = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.DataPointsQuery} returns this
- */
-proto.DataPointsQuery.prototype.setStreamfilter = function(value) {
-  return jspb.Message.setProto3StringField(this, 6, value);
-};
-
-
-/**
- * optional string receiverFilter = 7;
+ * optional string receiverFilter = 6;
  * @return {string}
  */
 proto.DataPointsQuery.prototype.getReceiverfilter = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
 };
 
 
@@ -572,16 +608,16 @@ proto.DataPointsQuery.prototype.getReceiverfilter = function() {
  * @return {!proto.DataPointsQuery} returns this
  */
 proto.DataPointsQuery.prototype.setReceiverfilter = function(value) {
-  return jspb.Message.setProto3StringField(this, 7, value);
+  return jspb.Message.setProto3StringField(this, 6, value);
 };
 
 
 /**
- * optional string fromPipelineStepFilter = 8;
+ * optional string fromPipelineStepFilter = 7;
  * @return {string}
  */
 proto.DataPointsQuery.prototype.getFrompipelinestepfilter = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
 };
 
 
@@ -590,16 +626,16 @@ proto.DataPointsQuery.prototype.getFrompipelinestepfilter = function() {
  * @return {!proto.DataPointsQuery} returns this
  */
 proto.DataPointsQuery.prototype.setFrompipelinestepfilter = function(value) {
-  return jspb.Message.setProto3StringField(this, 8, value);
+  return jspb.Message.setProto3StringField(this, 7, value);
 };
 
 
 /**
- * optional string toPipelineStepFilter = 9;
+ * optional string toPipelineStepFilter = 8;
  * @return {string}
  */
 proto.DataPointsQuery.prototype.getTopipelinestepfilter = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
 };
 
 
@@ -608,16 +644,16 @@ proto.DataPointsQuery.prototype.getTopipelinestepfilter = function() {
  * @return {!proto.DataPointsQuery} returns this
  */
 proto.DataPointsQuery.prototype.setTopipelinestepfilter = function(value) {
-  return jspb.Message.setProto3StringField(this, 9, value);
+  return jspb.Message.setProto3StringField(this, 8, value);
 };
 
 
 /**
- * optional PipelineConnectionQueryMode pipelineQueryMode = 10;
+ * optional PipelineConnectionQueryMode pipelineQueryMode = 9;
  * @return {!proto.PipelineConnectionQueryMode}
  */
 proto.DataPointsQuery.prototype.getPipelinequerymode = function() {
-  return /** @type {!proto.PipelineConnectionQueryMode} */ (jspb.Message.getFieldWithDefault(this, 10, 0));
+  return /** @type {!proto.PipelineConnectionQueryMode} */ (jspb.Message.getFieldWithDefault(this, 9, 0));
 };
 
 
@@ -626,7 +662,7 @@ proto.DataPointsQuery.prototype.getPipelinequerymode = function() {
  * @return {!proto.DataPointsQuery} returns this
  */
 proto.DataPointsQuery.prototype.setPipelinequerymode = function(value) {
-  return jspb.Message.setProto3EnumField(this, 10, value);
+  return jspb.Message.setProto3EnumField(this, 9, value);
 };
 
 
@@ -2899,6 +2935,516 @@ proto.TopologyResponse.prototype.clearEdgesList = function() {
 };
 
 
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GroupDelayQuery.prototype.toObject = function(opt_includeInstance) {
+  return proto.GroupDelayQuery.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GroupDelayQuery} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayQuery.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    fromtimestamp: jspb.Message.getFieldWithDefault(msg, 1, 0),
+    totimestamp: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    beamtimefilter: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GroupDelayQuery}
+ */
+proto.GroupDelayQuery.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GroupDelayQuery;
+  return proto.GroupDelayQuery.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GroupDelayQuery} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GroupDelayQuery}
+ */
+proto.GroupDelayQuery.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setFromtimestamp(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readUint64());
+      msg.setTotimestamp(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setBeamtimefilter(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GroupDelayQuery.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GroupDelayQuery.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GroupDelayQuery} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayQuery.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getFromtimestamp();
+  if (f !== 0) {
+    writer.writeUint64(
+      1,
+      f
+    );
+  }
+  f = message.getTotimestamp();
+  if (f !== 0) {
+    writer.writeUint64(
+      2,
+      f
+    );
+  }
+  f = message.getBeamtimefilter();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional uint64 fromTimestamp = 1;
+ * @return {number}
+ */
+proto.GroupDelayQuery.prototype.getFromtimestamp = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.GroupDelayQuery} returns this
+ */
+proto.GroupDelayQuery.prototype.setFromtimestamp = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+/**
+ * optional uint64 toTimestamp = 2;
+ * @return {number}
+ */
+proto.GroupDelayQuery.prototype.getTotimestamp = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.GroupDelayQuery} returns this
+ */
+proto.GroupDelayQuery.prototype.setTotimestamp = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+/**
+ * optional string beamtimeFilter = 3;
+ * @return {string}
+ */
+proto.GroupDelayQuery.prototype.getBeamtimefilter = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.GroupDelayQuery} returns this
+ */
+proto.GroupDelayQuery.prototype.setBeamtimefilter = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GroupDelayResponseItem.prototype.toObject = function(opt_includeInstance) {
+  return proto.GroupDelayResponseItem.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GroupDelayResponseItem} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayResponseItem.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    groupid: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    delayms: jspb.Message.getFieldWithDefault(msg, 2, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GroupDelayResponseItem}
+ */
+proto.GroupDelayResponseItem.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GroupDelayResponseItem;
+  return proto.GroupDelayResponseItem.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GroupDelayResponseItem} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GroupDelayResponseItem}
+ */
+proto.GroupDelayResponseItem.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setGroupid(value);
+      break;
+    case 2:
+      var value = /** @type {number} */ (reader.readUint32());
+      msg.setDelayms(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GroupDelayResponseItem.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GroupDelayResponseItem.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GroupDelayResponseItem} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayResponseItem.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getGroupid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getDelayms();
+  if (f !== 0) {
+    writer.writeUint32(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string groupId = 1;
+ * @return {string}
+ */
+proto.GroupDelayResponseItem.prototype.getGroupid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.GroupDelayResponseItem} returns this
+ */
+proto.GroupDelayResponseItem.prototype.setGroupid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional uint32 delayMs = 2;
+ * @return {number}
+ */
+proto.GroupDelayResponseItem.prototype.getDelayms = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.GroupDelayResponseItem} returns this
+ */
+proto.GroupDelayResponseItem.prototype.setDelayms = function(value) {
+  return jspb.Message.setProto3IntField(this, 2, value);
+};
+
+
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.GroupDelayResponse.repeatedFields_ = [1];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.GroupDelayResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.GroupDelayResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.GroupDelayResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    groupidsList: jspb.Message.toObjectList(msg.getGroupidsList(),
+    proto.GroupDelayResponseItem.toObject, includeInstance)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.GroupDelayResponse}
+ */
+proto.GroupDelayResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.GroupDelayResponse;
+  return proto.GroupDelayResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.GroupDelayResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.GroupDelayResponse}
+ */
+proto.GroupDelayResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.GroupDelayResponseItem;
+      reader.readMessage(value,proto.GroupDelayResponseItem.deserializeBinaryFromReader);
+      msg.addGroupids(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.GroupDelayResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.GroupDelayResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.GroupDelayResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.GroupDelayResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getGroupidsList();
+  if (f.length > 0) {
+    writer.writeRepeatedMessage(
+      1,
+      f,
+      proto.GroupDelayResponseItem.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * repeated GroupDelayResponseItem groupIds = 1;
+ * @return {!Array<!proto.GroupDelayResponseItem>}
+ */
+proto.GroupDelayResponse.prototype.getGroupidsList = function() {
+  return /** @type{!Array<!proto.GroupDelayResponseItem>} */ (
+    jspb.Message.getRepeatedWrapperField(this, proto.GroupDelayResponseItem, 1));
+};
+
+
+/**
+ * @param {!Array<!proto.GroupDelayResponseItem>} value
+ * @return {!proto.GroupDelayResponse} returns this
+*/
+proto.GroupDelayResponse.prototype.setGroupidsList = function(value) {
+  return jspb.Message.setRepeatedWrapperField(this, 1, value);
+};
+
+
+/**
+ * @param {!proto.GroupDelayResponseItem=} opt_value
+ * @param {number=} opt_index
+ * @return {!proto.GroupDelayResponseItem}
+ */
+proto.GroupDelayResponse.prototype.addGroupids = function(opt_value, opt_index) {
+  return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.GroupDelayResponseItem, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.GroupDelayResponse} returns this
+ */
+proto.GroupDelayResponse.prototype.clearGroupidsList = function() {
+  return this.setGroupidsList([]);
+};
+
+
 /**
  * @enum {number}
  */
diff --git a/monitoring/monitoring_ui/src/store/connectionStore.ts b/monitoring/monitoring_ui/src/store/connectionStore.ts
index e442b897c9e025f7174d5a443c5e6a8d3b9e6939..0f5561a9281206d194c004139810885141a7d38c 100644
--- a/monitoring/monitoring_ui/src/store/connectionStore.ts
+++ b/monitoring/monitoring_ui/src/store/connectionStore.ts
@@ -1,3 +1,5 @@
+import {groupDelayStore} from "./groupDelayStore";
+
 interface HitMissDataPoint {
     timestamp: number;
     hit: number;
@@ -39,7 +41,14 @@ export interface ReceiverInfo {
     totalMemory: number;
 }
 
-import { DataPointsQuery, DataPointsResponse, MetadataResponse, PipelineConnectionQueryMode, ToplogyQuery } from '../generated_proto/AsapoMonitoringQueryService_pb';
+import {
+    DataPointsQuery,
+    DataPointsResponse,
+    GroupDelayQuery,
+    MetadataResponse,
+    PipelineConnectionQueryMode,
+    ToplogyQuery
+} from '../generated_proto/AsapoMonitoringQueryService_pb';
 import { Empty } from '../generated_proto/AsapoMonitoringCommonService_pb';
 import { timeStore } from './timeStore';
 import { selectionFilterStore } from './selectionFilterStore';
@@ -48,6 +57,7 @@ interface ConnectionStoreState {
     isFetchingMetaData: boolean;
     isFetchingData: boolean;
     isFetchingToplogyData: boolean;
+    isFetchingGroupDelayData: boolean;
 
     // metadata
     clusterName: string;
@@ -71,6 +81,7 @@ class ConnectionStore {
         isFetchingMetaData: false,
         isFetchingData: false,
         isFetchingToplogyData: false,
+        isFetchingGroupDelayData: false,
 
         clusterName: '<NOT SET>',
         availableBeamtimes: [],
@@ -97,6 +108,10 @@ class ConnectionStore {
         this.internalState.isFetchingToplogyData = mode;
     }
 
+    public setIsFetchingGroupDelayData(mode: boolean): void {
+        this.internalState.isFetchingGroupDelayData = mode;
+    }
+
     public triggerToplogyRefresh(): void {
         if (this.state.isFetchingToplogyData) {
             console.warn('Unable to fetch toplogy: Already fetching toplogy data.');
@@ -139,6 +154,48 @@ class ConnectionStore {
         });
     }
 
+    public triggerGroupDelayRefresh(): void {
+        if (this.state.isFetchingGroupDelayData) {
+            console.warn('Unable to fetch group delay: Already fetching group delay data.');
+            return; // already fetching data
+        }
+
+        if (!selectionFilterStore.isValidFilterOrSetError()) {
+            return;
+        }
+
+        this.setIsFetchingGroupDelayData(true);
+
+        const query = new GroupDelayQuery();
+
+        const range = timeStore.state.lastFixedTimeRange;
+        query.setFromtimestamp(range.fromUnixSec);
+        query.setTotimestamp(range.toUnixSec);
+        query.setBeamtimefilter(selectionFilterStore.state.beamtime!);
+
+        errorStore.clearGroupDelayConnectionError();
+        client.getGroupDelay(query, undefined, (err, groupDelayData) => {
+            if (err) {
+                errorStore.setGroupDelayConnectionErrorText(err.message);
+                console.error('getGroupDelay error: ', err);
+                this.setIsFetchingGroupDelayData(false);
+                return;
+            }
+
+            try {
+                groupDelayStore.parseServerResponse(groupDelayData);
+            }
+            catch(e) {
+                errorStore.setGroupDelayConnectionErrorText('internal: ' + e.message);
+                console.error('getGroupDelay internal error: ', e);
+            }
+            finally {
+                this.setIsFetchingGroupDelayData(false);
+            }
+
+        });
+    }
+
     public triggerMetaDataRefresh(): void {
         if (this.state.isFetchingMetaData) {
             console.warn('Unable to fetch metadata: Already fetching metadata.');
@@ -188,6 +245,10 @@ class ConnectionStore {
             this.triggerToplogyRefresh();
         }
 
+        if (groupDelayStore.couldBeOutdated()) {
+            this.triggerGroupDelayRefresh();
+        }
+
         this.setIsFetchingData(true);
         
         const query = new DataPointsQuery();
@@ -239,5 +300,6 @@ connection.triggerMetaDataRefresh();
 if (selectionFilterStore.state.beamtime) {
     connection.triggerMetricsRefresh();
     connection.triggerToplogyRefresh();
+    connection.triggerGroupDelayRefresh();
 }
 
diff --git a/monitoring/monitoring_ui/src/store/errorStore.ts b/monitoring/monitoring_ui/src/store/errorStore.ts
index 8a70ae2571a5958669e71ccfed9398ced7afaf25..b83900cd59d2ba57d3652dff03585573de75ef39 100644
--- a/monitoring/monitoring_ui/src/store/errorStore.ts
+++ b/monitoring/monitoring_ui/src/store/errorStore.ts
@@ -4,6 +4,7 @@ export interface ErrorStoreState {
     connectionMetadataErrorText: string | null;
     connectionMetricsErrorText: string | null;
     connectionToplogyErrorText: string | null;
+    connectionGroupDelayErrorText: string | null;
     filterErrorText: string | null;
     timeErrorText: string | null;
 }
@@ -13,6 +14,7 @@ class ErrorStore {
         connectionMetadataErrorText: null,
         connectionMetricsErrorText: null,
         connectionToplogyErrorText: null,
+        connectionGroupDelayErrorText: null,
         filterErrorText: null,
         timeErrorText: null,
     });
@@ -41,6 +43,12 @@ class ErrorStore {
     public clearToplogyConnectionError(): void {
         this.internalState.connectionToplogyErrorText = null;
     }
+    public setGroupDelayConnectionErrorText(text: string): void {
+        this.internalState.connectionGroupDelayErrorText = text;
+    }
+    public clearGroupDelayConnectionError(): void {
+        this.internalState.connectionGroupDelayErrorText = null;
+    }
 
     public setFilterErrorText(text: string): void {
         this.internalState.filterErrorText = text;
@@ -73,7 +81,9 @@ class ErrorStore {
         if (this.state.connectionToplogyErrorText) {
             return `Toplogy: ${this.state.connectionToplogyErrorText}`;
         }
-        
+        if (this.state.connectionGroupDelayErrorText) {
+            return `Group Delays: ${this.state.connectionGroupDelayErrorText}`;
+        }
         // possible other errors here
 
         return null;
diff --git a/monitoring/monitoring_ui/src/store/groupDelayStore.ts b/monitoring/monitoring_ui/src/store/groupDelayStore.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3aef2f34108c675921b55b00e92d6f43e1b2237c
--- /dev/null
+++ b/monitoring/monitoring_ui/src/store/groupDelayStore.ts
@@ -0,0 +1,57 @@
+import { reactive } from "vue";
+import { GroupDelayResponse } from "../generated_proto/AsapoMonitoringQueryService_pb";
+import { FixedTimeRange } from "../lib/TimeRange";
+import { timeStore } from "./timeStore";
+import {PipelineNode} from "../lib/ToplogyPipelineDefinitions";
+
+export interface GroupDelayStoreState {
+    lastUpdateRange: FixedTimeRange,
+    GroupIdList: string[];
+}
+
+class GroupDelayStore {
+    private internalState: GroupDelayStoreState = reactive({
+        lastUpdateRange: {
+            fromUnixSec: 0,
+            toUnixSec: 0
+        },
+        GroupIdList: [],
+    });
+
+    public get state(): Readonly<GroupDelayStoreState> {
+        return this.internalState;
+    }
+
+    private beautifyDelayMs(delayMs: number): string {
+        if (delayMs > 60 * 60 * 1000) {
+            return ">1H"
+        } else if (delayMs > 60 * 1000) {
+            return Math.floor(delayMs / 60*1000).toString() + "mins"
+        } else if (delayMs > 1000) {
+            return Math.floor(delayMs / 1000).toString() + "secs"
+        }
+        return "0."+delayMs.toString().padStart(4, '0')+"millis"
+    }
+
+    public parseServerResponse(groupDelayData: GroupDelayResponse): void {
+        const newGroupIds: string[] = [];
+        for(const groupId of groupDelayData.getGroupidsList()) {
+            const value: string = groupId.getGroupid() + groupId.getDelayms()
+            newGroupIds.push( groupId.getGroupid().padEnd(25, ' ') + this.beautifyDelayMs(groupId.getDelayms()) )
+        }
+
+        this.internalState.GroupIdList = newGroupIds
+
+        this.internalState.lastUpdateRange.fromUnixSec = timeStore.state.lastFixedTimeRange.fromUnixSec;
+        this.internalState.lastUpdateRange.toUnixSec = timeStore.state.lastFixedTimeRange.toUnixSec;
+    }
+
+    public couldBeOutdated(): boolean {
+        const maxPipelineToplogyOldnessInSec = 60;
+        
+        return  Math.abs(this.internalState.lastUpdateRange.fromUnixSec - timeStore.state.lastFixedTimeRange.fromUnixSec) > maxPipelineToplogyOldnessInSec ||
+                Math.abs(this.internalState.lastUpdateRange.toUnixSec - timeStore.state.lastFixedTimeRange.toUnixSec) > maxPipelineToplogyOldnessInSec
+    }
+}
+
+export const groupDelayStore = new GroupDelayStore();
diff --git a/monitoring/monitoring_ui/src/views/Dashboard.vue b/monitoring/monitoring_ui/src/views/Dashboard.vue
index 7a6575f96f34f934bc1d46687aa32a9c8ec91e76..2a6e532120c4d86210d3ee8bd1e07448c1f9ee02 100644
--- a/monitoring/monitoring_ui/src/views/Dashboard.vue
+++ b/monitoring/monitoring_ui/src/views/Dashboard.vue
@@ -29,6 +29,7 @@
                         ]}" />
                     <GenericListChart class="inline-flex" label="Producers" :elements="involvedProducers" />
                     <GenericListChart class="inline-flex" label="Consumers" :elements="involvedConsumers" />
+                    <GenericListChart class="inline-flex" label="Group IDs" :elements="involvedGroupIds" />
                 </div>
                 
                 <h2 class="ml-1 mt-2">Advanced stats</h2>
@@ -76,6 +77,7 @@ import { connection } from '../store/connectionStore';
 import { DataPointsResponse } from '../generated_proto/AsapoMonitoringQueryService_pb';
 import { selectionFilterStore } from '../store/selectionFilterStore';
 import { toplogyStore } from '../store/toplogyStore';
+import { groupDelayStore } from "../store/groupDelayStore";
 import { metricData, MetricDataComplete } from '../store/metricDataStore';
 
 
@@ -147,6 +149,10 @@ export default class Dashboard extends Vue {
         return nodes.flatMap(node => node.consumers);
     }
 
+    private get involvedGroupIds(): string[] {
+      return groupDelayStore.state.GroupIdList
+    }
+
     private get involvedReceiverList(): string[] {
         let edges = toplogyStore.state.pipeline.edges;