diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9b10ffeabbc08a1f25a88d2b351f3e8dd6309443..b7d75d5470d8073a2021e06428e9170f605ec7b3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -303,6 +303,32 @@ deploy-theodolite:
       allow_failure: true
 
 
+# Theodolite SLO Checker: Lag Trend
+
+deploy-slo-checker-lag-trend:
+  stage: deploy
+  extends:
+    - .dind
+  script:
+    - DOCKER_TAG_NAME=$(echo $CI_COMMIT_REF_SLUG- | sed 's/^master-$//')
+    - docker build --pull -t theodolite-slo-checker-lag-trend slope-evaluator
+    - "[ ! $CI_COMMIT_TAG ] && docker tag theodolite-slo-checker-lag-trend $CR_HOST/$CR_ORG/theodolite-slo-checker-lag-trend:${DOCKER_TAG_NAME}latest"
+    - "[ $CI_COMMIT_TAG ] && docker tag theodolite-slo-checker-lag-trend $CR_HOST/$CR_ORG/theodolite-slo-checker-lag-trend:$CI_COMMIT_TAG"
+    - echo $CR_PW | docker login $CR_HOST -u $CR_USER --password-stdin
+    - docker push $CR_HOST/$CR_ORG/theodolite-slo-checker-lag-trend
+    - docker logout
+  rules:
+    - if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW && $CI_COMMIT_TAG"
+      when: always
+    - changes:
+      - slope-evaluator/**/*
+      if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
+      when: always
+    - if: "$CR_HOST && $CR_ORG && $CR_USER && $CR_PW"
+      when: manual
+      allow_failure: true
+
+
 # Theodolite Random Scheduler
 
 deploy-random-scheduler:
diff --git a/execution/README.md b/execution/README.md
index ff94dfed2fa887c300e8449b7c41dc3f65c7a1e2..ca15111c0ad7000a200c0c50427a2c2aeb75e093 100644
--- a/execution/README.md
+++ b/execution/README.md
@@ -98,7 +98,7 @@ kubectl apply -f infrastructure/kafka/service-monitor.yaml
 Other Kafka deployments, for example, using Strimzi, should work in a similar way.
 
 *Please note that currently, even if installed differently, the corresponding services must run at
-*my-confluent-cp-kafka:9092*, *my-confluent-cp-zookeeper:2181* and *my-confluent-cp-schema-registry:8081*.
+`my-confluent-cp-kafka:9092`, `my-confluent-cp-zookeeper:2181` and `my-confluent-cp-schema-registry:8081`.*
 
 #### A Kafka Client Pod
 
diff --git a/execution/helm/README.md b/execution/helm/README.md
index 4cacd06c8181970e78cb4f62e93b77fa169fcdfa..6a2f083559fd0fe7b5674834e99a075e9bea1851 100644
--- a/execution/helm/README.md
+++ b/execution/helm/README.md
@@ -44,6 +44,31 @@ In development environments Kubernetes resources are often low. To reduce resour
 helm install theodolite . -f preconfigs/one-broker-values.yaml
 ```
 
+## Uninstall this Chart
+
+To uninstall/delete the `my-release` deployment:
+
+```sh
+helm delete my-release
+```
+
+This command does not remove the CRDs which are created by this chart. Remove them manually with:
+
+```sh
+# CRDs from Theodolite
+kubectl delete crd execution
+kubectl delete crd benchmark
+# CRDs from Prometheus operator (see https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack#uninstall-chart)
+kubectl delete crd alertmanagerconfigs.monitoring.coreos.com
+kubectl delete crd alertmanagers.monitoring.coreos.com
+kubectl delete crd podmonitors.monitoring.coreos.com
+kubectl delete crd probes.monitoring.coreos.com
+kubectl delete crd prometheuses.monitoring.coreos.com
+kubectl delete crd prometheusrules.monitoring.coreos.com
+kubectl delete crd servicemonitors.monitoring.coreos.com
+kubectl delete crd thanosrulers.monitoring.coreos.com
+```
+
 ## Development
 
 **Hints**:
diff --git a/execution/helm/preconfigs/one-broker-values.yaml b/execution/helm/preconfigs/one-broker-values.yaml
index fdbc3207ee37f49cf176645851d91e62ba354d28..c53c1f1eb8bc7a17f192d70a6f10f8cacc09c98f 100644
--- a/execution/helm/preconfigs/one-broker-values.yaml
+++ b/execution/helm/preconfigs/one-broker-values.yaml
@@ -9,7 +9,7 @@ cp-helm-charts:
   ## Kafka
   ## ------------------------------------------------------
     cp-kafka:
-        brokers: 1 # deauflt: 10
+        brokers: 1 # default: 10
 
         configurationOverrides:
           offsets.topic.replication.factor: "1"
\ No newline at end of file
diff --git a/execution/helm/templates/dashboard-config-map.yaml b/execution/helm/templates/grafana/dashboard-config-map.yaml
similarity index 99%
rename from execution/helm/templates/dashboard-config-map.yaml
rename to execution/helm/templates/grafana/dashboard-config-map.yaml
index 87e588f29df7446d0b12000eb53487a9bb88ea6c..1125d7833cc62e78c049436f38b854d926e2a216 100644
--- a/execution/helm/templates/dashboard-config-map.yaml
+++ b/execution/helm/templates/grafana/dashboard-config-map.yaml
@@ -2,7 +2,7 @@
 apiVersion: v1
 kind: ConfigMap
 metadata:
-  name: scalability
+  name: {{ template "theodolite.fullname" . }}-grafana-scalability
   labels:
     grafana_dashboard: "1"
 data:
diff --git a/execution/helm/templates/kafka-client.yaml b/execution/helm/templates/kafka/kafka-client.yaml
similarity index 87%
rename from execution/helm/templates/kafka-client.yaml
rename to execution/helm/templates/kafka/kafka-client.yaml
index 853cb768672d8888085a3881df81cbdb806ec39d..02e16d33dfc9595dd16c41fa6bfe1404fd7889ab 100644
--- a/execution/helm/templates/kafka-client.yaml
+++ b/execution/helm/templates/kafka/kafka-client.yaml
@@ -3,7 +3,7 @@ apiVersion: v1
 kind: Pod
 metadata:
   # name: {{ template "theodolite.fullname" . }}-kafka-client
-  name: kafka-client
+  name: {{ template "theodolite.fullname" . }}-kafka-client
 spec:
   containers:
   - name: kafka-client
diff --git a/execution/helm/templates/service-monitor.yaml b/execution/helm/templates/kafka/service-monitor.yaml
similarity index 83%
rename from execution/helm/templates/service-monitor.yaml
rename to execution/helm/templates/kafka/service-monitor.yaml
index 50e4688cf7f9b919afdc9455462034f682975893..68fd5f7599d36187fa7c4dee2fab211eb263c67d 100644
--- a/execution/helm/templates/service-monitor.yaml
+++ b/execution/helm/templates/kafka/service-monitor.yaml
@@ -5,7 +5,7 @@ metadata:
   labels:
     app: cp-kafka
     appScope: titan-ccp
-  name: kafka
+  name: {{ template "theodolite.fullname" . }}-cp-kafka
 spec:
   selector:
     matchLabels:
diff --git a/execution/helm/templates/cluster-role-binding.yaml b/execution/helm/templates/prometheus/cluster-role-binding.yaml
similarity index 61%
rename from execution/helm/templates/cluster-role-binding.yaml
rename to execution/helm/templates/prometheus/cluster-role-binding.yaml
index 400a972cdb73dca181b621f49e7a3e79c926e65b..f2f167b94b79ad4db130565777cb8af486762c8c 100644
--- a/execution/helm/templates/cluster-role-binding.yaml
+++ b/execution/helm/templates/prometheus/cluster-role-binding.yaml
@@ -2,13 +2,13 @@
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
 subjects:
 - kind: ServiceAccount
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
   namespace: {{ .Release.Namespace }}
 {{- end}}
\ No newline at end of file
diff --git a/execution/helm/templates/cluster-role.yaml b/execution/helm/templates/prometheus/cluster-role.yaml
similarity index 86%
rename from execution/helm/templates/cluster-role.yaml
rename to execution/helm/templates/prometheus/cluster-role.yaml
index 2a272718da1413a466d6afed51b3bca1f37a1fe0..c2fea2205451e01474d1ab7ef1ca342a9d975dc9 100644
--- a/execution/helm/templates/cluster-role.yaml
+++ b/execution/helm/templates/prometheus/cluster-role.yaml
@@ -2,7 +2,7 @@
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
 rules:
 - apiGroups: [""]
   resources:
diff --git a/execution/helm/templates/prometheus-datasource-config-map.yaml b/execution/helm/templates/prometheus/datasource-config-map.yaml
similarity index 94%
rename from execution/helm/templates/prometheus-datasource-config-map.yaml
rename to execution/helm/templates/prometheus/datasource-config-map.yaml
index 4e793ff83668ac7a7582a924750ca729d9e277ae..b28157940c4dd7cb05eca3fe04926f6e7726830f 100644
--- a/execution/helm/templates/prometheus-datasource-config-map.yaml
+++ b/execution/helm/templates/prometheus/datasource-config-map.yaml
@@ -2,7 +2,7 @@
 apiVersion: v1
 kind: ConfigMap
 metadata:
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
   labels:
     grafana_datasource: "1"
 data:
diff --git a/execution/helm/templates/prometheus.yaml b/execution/helm/templates/prometheus/prometheus.yaml
similarity index 86%
rename from execution/helm/templates/prometheus.yaml
rename to execution/helm/templates/prometheus/prometheus.yaml
index a3060798a8a3b000f730525805c0d050becc7a68..4e297b20290be9686b901fa8c76823136c6fabef 100644
--- a/execution/helm/templates/prometheus.yaml
+++ b/execution/helm/templates/prometheus/prometheus.yaml
@@ -4,7 +4,7 @@ kind: Prometheus
 metadata:
   name: {{ template "theodolite.fullname" . }}-prometheus
 spec:
-  serviceAccountName: prometheus
+  serviceAccountName: {{ template "theodolite.fullname" . }}-prometheus
   serviceMonitorSelector:
     matchLabels:
       #app: cp-kafka
diff --git a/execution/helm/templates/service-account.yaml b/execution/helm/templates/prometheus/service-account.yaml
similarity index 65%
rename from execution/helm/templates/service-account.yaml
rename to execution/helm/templates/prometheus/service-account.yaml
index 2e14c8eb8ffd912f3d34d1b94aa481cb497b4b90..090284a0cf3c6bb7ca643ee111b2d62d1bd93fb3 100644
--- a/execution/helm/templates/service-account.yaml
+++ b/execution/helm/templates/prometheus/service-account.yaml
@@ -2,5 +2,5 @@
 apiVersion: v1
 kind: ServiceAccount
 metadata:
-  name: prometheus
+  name: {{ template "theodolite.fullname" . }}-prometheus
 {{- end}}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/crd-benchmark.yaml b/execution/helm/templates/theodolite/crd-benchmark.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9d7468b490fa2f2a6cf829bdcafab8c4bd6fc5bf
--- /dev/null
+++ b/execution/helm/templates/theodolite/crd-benchmark.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.benchmarkCRD.create -}}
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: benchmarks.theodolite.com
+spec:
+  group: theodolite.com
+  version: v1alpha1
+  names:
+    kind: benchmark
+    plural: benchmarks
+  scope: Namespaced
+  subresources:
+    status: {}
+{{- end }}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/crd-execution.yaml b/execution/helm/templates/theodolite/crd-execution.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73b58397b8c1fc15ffef5da74e8f1dbdabaa3a30
--- /dev/null
+++ b/execution/helm/templates/theodolite/crd-execution.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.executionCRD.create -}}
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: executions.theodolite.com
+spec:
+  group: theodolite.com
+  version: v1alpha1
+  names:
+    kind: execution
+    plural: executions
+  scope: Namespaced
+  subresources:
+    status: {}
+{{- end }}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/role-binding.yaml b/execution/helm/templates/theodolite/role-binding.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..93d8c34e7bc544c3b0c231e986bc58c792cce38e
--- /dev/null
+++ b/execution/helm/templates/theodolite/role-binding.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: RoleBinding
+metadata:
+  name:  {{ include "theodolite.fullname" . }}
+  labels:
+    app:  {{ include "theodolite.name" . }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: {{ include "theodolite.fullname" . }}
+subjects:
+- kind: ServiceAccount
+  name: {{ include "theodolite.serviceAccountName" . }}
+{{- end }}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/role.yaml b/execution/helm/templates/theodolite/role.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73e3e5098448c88e6b030f1dc2056caf999da3ce
--- /dev/null
+++ b/execution/helm/templates/theodolite/role.yaml
@@ -0,0 +1,60 @@
+{{- if .Values.rbac.create -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: {{ include "theodolite.fullname" . }}
+rules:
+  - apiGroups:
+    - apps
+    resources:
+    - deployments
+    verbs:
+    - delete
+    - list
+    - get
+    - create
+    - update
+  - apiGroups:
+    - ""
+    resources:
+    - services
+    - pods
+    - configmaps
+    verbs:
+    - update
+    - delete
+    - list
+    - get
+    - create
+  - apiGroups:
+    - ""
+    resources:
+    - pods/exec
+    verbs:
+    - create
+    - get
+  - apiGroups:
+    - monitoring.coreos.com
+    resources:
+    - servicemonitors
+    verbs:
+    - update
+    - delete
+    - list
+    - create
+  {{- if .Values.operator.enabled -}}
+  - apiGroups:
+    - theodolite.com
+    resources: 
+    - executions
+    - benchmarks
+    verbs:
+    - delete
+    - list
+    - get
+    - create
+    - watch
+    - update
+    - patch
+  {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/serviceaccount.yaml b/execution/helm/templates/theodolite/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4585b8ce413bf3d36cb986163788c353f2a4a2de
--- /dev/null
+++ b/execution/helm/templates/theodolite/serviceaccount.yaml
@@ -0,0 +1,12 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "theodolite.serviceAccountName" . }}
+  labels:
+    {{- include "theodolite.labels" . | nindent 4 }}
+  {{- with .Values.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/execution/helm/templates/theodolite/thedolite-operator.yaml b/execution/helm/templates/theodolite/thedolite-operator.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cb3f193b89c3a198bab853fb85a0db1184394dce
--- /dev/null
+++ b/execution/helm/templates/theodolite/thedolite-operator.yaml
@@ -0,0 +1,31 @@
+{{- if .Values.operator.enabled -}}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "theodolite.fullname" . }}-operator
+spec:
+  selector:
+    matchLabels:
+      app: {{ include "theodolite.fullname" . }}
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: {{ include "theodolite.fullname" . }}
+    spec:
+      terminationGracePeriodSeconds: 0
+      serviceAccountName:  {{ include "theodolite.serviceAccountName" . }}
+      containers:
+        - name: theodolite
+          image: ghcr.io/cau-se/theodolite:theodolite-kotlin-latest
+          env:
+            - name: NAMESPACE
+              value: {{ .Release.Namespace }}
+            - name: MODE
+              value: operator
+        - name: lag-analysis
+          image: ghcr.io/cau-se/theodolite-slo-checker-lag-trend:theodolite-kotlin-latest
+          ports:
+          - containerPort: 80
+            name: analysis 
+{{- end }}
diff --git a/execution/helm/values.yaml b/execution/helm/values.yaml
index d35912de6ffc72fff27f5d389c94761bc80eecd1..5e48ad46b01689c974189f471b0016e45d71f958 100644
--- a/execution/helm/values.yaml
+++ b/execution/helm/values.yaml
@@ -226,4 +226,22 @@ prometheus:
   clusterRole:
     enabled: true
   clusterRoleBinding:
-    enabled: true
\ No newline at end of file
+    enabled: true
+
+###
+# Theodolite Operator
+###
+operator:
+  enabled: true
+
+executionCRD:
+  create: true
+
+benchmarkCRD:
+  create: true
+
+serviceAccount:
+  create: true
+
+rbac:
+  create: true
diff --git a/execution/infrastructure/kubernetes/rbac/role.yaml b/execution/infrastructure/kubernetes/rbac/role.yaml
index 84ba14a8bc7a6eceb8a20596ede057ca2271b967..a21fd554f0f56b3955e9a9b6cf4bf95442b5d7af 100644
--- a/execution/infrastructure/kubernetes/rbac/role.yaml
+++ b/execution/infrastructure/kubernetes/rbac/role.yaml
@@ -38,4 +38,18 @@ rules:
     verbs:
     - delete
     - list
-    - create
\ No newline at end of file
+    - create
+  - apiGroups:
+    - theodolite.com
+    resources: 
+    - executions
+    - benchmarks
+    verbs:
+    - delete
+    - list
+    - get
+    - create
+    - watch
+    - update
+    - patch
+    
diff --git a/theodolite-quarkus/config/BenchmarkType.yaml b/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
similarity index 93%
rename from theodolite-quarkus/config/BenchmarkType.yaml
rename to theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
index 60eb3bb9c31e3eab3e70f916b450372d56db4968..42b1cd08dc1949355c97edebc92ea7b5ab8799b2 100644
--- a/theodolite-quarkus/config/BenchmarkType.yaml
+++ b/theodolite-quarkus/config/example-benchmark-yaml-resource.yaml
@@ -20,7 +20,7 @@ loadTypes:
         container: "workload-generator"
         variableName: "NUM_SENSORS"
 kafkaConfig:
-  bootstrapServer: "theodolite-cp-kafka:9092"
+  bootstrapServer: "my-confluent-cp-kafka:9092"
   topics:
     - name: "input"
       numPartitions: 40
diff --git a/theodolite-quarkus/config/BenchmarkExecution.yaml b/theodolite-quarkus/config/example-execution-yaml-resource.yaml
similarity index 59%
rename from theodolite-quarkus/config/BenchmarkExecution.yaml
rename to theodolite-quarkus/config/example-execution-yaml-resource.yaml
index ef74e14f94b65f077fdec7e6f0b61772a7f3079f..80e4575d653bff8d67d8f66cf4ae9806a1fe102e 100644
--- a/theodolite-quarkus/config/BenchmarkExecution.yaml
+++ b/theodolite-quarkus/config/example-execution-yaml-resource.yaml
@@ -1,4 +1,4 @@
-name: "Theodolite Test Context"
+name: example-execution
 benchmark: "uc1-kstreams"
 load:
   loadType: "NumSensors"
@@ -32,19 +32,19 @@ configOverrides:
       resource: "uc1-kstreams-deployment.yaml"
       variableName: "env"
     value: "prod"
-  - patcher:
-      type: "ResourceLimitPatcher"
-      resource: "uc1-kstreams-deployment.yaml"
-      container: "uc-application"
-      variableName: "cpu"
-    value: "1000m"
-  - patcher:
-      type: "ResourceLimitPatcher"
-      resource: "uc1-kstreams-deployment.yaml"
-      container: "uc-application"
-      variableName: "memory"
-    value: "2Gi"
-  - patcher:
-      type: "SchedulerNamePatcher"
-      resource: "uc1-kstreams-deployment.yaml"
-    value: "random-scheduler"
\ No newline at end of file
+#  - patcher:
+#      type: "ResourceLimitPatcher"
+#      resource: "uc1-kstreams-deployment.yaml"
+#      container: "uc-application"
+#      variableName: "cpu"
+#    value: "1000m"
+#  - patcher:
+#      type: "ResourceLimitPatcher"
+#      resource: "uc1-kstreams-deployment.yaml"
+#      container: "uc-application"
+#      variableName: "memory"
+#    value: "2Gi"
+#  - patcher:
+#      type: "SchedulerNamePatcher"
+#      resource: "uc1-kstreams-deployment.yaml"
+#    value: "random-scheduler"
diff --git a/theodolite-quarkus/config/thedolite-operator.yaml b/theodolite-quarkus/config/thedolite-operator.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1e0e60248c2474cc8493179c003b806030f79f8c
--- /dev/null
+++ b/theodolite-quarkus/config/thedolite-operator.yaml
@@ -0,0 +1,24 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: theodolite
+spec:
+  selector:
+    matchLabels:
+      app: theodolite
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: theodolite
+    spec:
+      terminationGracePeriodSeconds: 0
+      serviceAccountName: theodolite
+      containers:
+        - name: thedolite
+          image: ghcr.io/cau-se/theodolite:theodolite-kotlin-latest
+          env:
+            - name: KUBECONFIG
+              value: "~/.kube/config"
+            - name: NAMESPACE
+              value: "default"
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
index d90cb18ccba1967572677a5ae23be9d6c426d943..36fd00795e3f075ca1fbd171fa59339df8151f85 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecution.kt
@@ -1,11 +1,17 @@
 package theodolite.benchmark
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
+import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.fabric8.kubernetes.api.model.Namespaced
+import io.fabric8.kubernetes.client.CustomResource
 import io.quarkus.runtime.annotations.RegisterForReflection
 import theodolite.util.ConfigurationOverride
 import kotlin.properties.Delegates
 
+@JsonDeserialize
 @RegisterForReflection
-class BenchmarkExecution {
+class BenchmarkExecution : CustomResource(), Namespaced {
+    var executionId: Int = 0
     lateinit var name: String
     lateinit var benchmark: String
     lateinit var load: LoadDefinition
@@ -14,16 +20,18 @@ class BenchmarkExecution {
     lateinit var execution: Execution
     lateinit var configOverrides: List<ConfigurationOverride?>
 
+    @JsonDeserialize
     @RegisterForReflection
-    class Execution {
+    class Execution : KubernetesResource {
         lateinit var strategy: String
         var duration by Delegates.notNull<Long>()
         var repetitions by Delegates.notNull<Int>()
         lateinit var restrictions: List<String>
     }
 
+    @JsonDeserialize
     @RegisterForReflection
-    class Slo {
+    class Slo : KubernetesResource {
         lateinit var sloType: String
         var threshold by Delegates.notNull<Int>()
         lateinit var prometheusUrl: String
@@ -32,14 +40,17 @@ class BenchmarkExecution {
         var warmup by Delegates.notNull<Int>()
     }
 
+
+    @JsonDeserialize
     @RegisterForReflection
-    class LoadDefinition {
+    class LoadDefinition : KubernetesResource {
         lateinit var loadType: String
         lateinit var loadValues: List<Int>
     }
 
+    @JsonDeserialize
     @RegisterForReflection
-    class ResourceDefinition {
+    class ResourceDefinition : KubernetesResource {
         lateinit var resourceType: String
         lateinit var resourceValues: List<Int>
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecutionList.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecutionList.kt
new file mode 100644
index 0000000000000000000000000000000000000000..50e8967f20aebad880ebd218136749af8e3ea6ee
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/BenchmarkExecutionList.kt
@@ -0,0 +1,5 @@
+package theodolite.benchmark
+
+import io.fabric8.kubernetes.client.CustomResourceList
+
+class BenchmarkExecutionList : CustomResourceList<BenchmarkExecution>()
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt
index 9e241cabfa208a0632635a30c658590faec2c1a8..2b86c51ae87c7b26609683b68bf6cfc12003efc8 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KafkaLagExporterRemover.kt
@@ -1,14 +1,14 @@
-package theodolite.benchmark;
+package theodolite.benchmark
 
 import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import mu.KotlinLogging
 
 private val logger = KotlinLogging.logger {}
 
-class KafkaLagExporterRemover(private val client : NamespacedKubernetesClient) {
+class KafkaLagExporterRemover(private val client: NamespacedKubernetesClient) {
 
-    fun remove(label: String){
+    fun remove(label: String) {
         this.client.pods().withLabel(label).delete()
-        logger.info{"Pod with label: $label deleted"}
+        logger.info { "Pod with label: $label deleted" }
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
index dea845ec4c9209c603641a57112acf52815430a7..a348deb9ff2acf592458635712b99c8d23fb0577 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmark.kt
@@ -1,6 +1,8 @@
 package theodolite.benchmark
 
 import io.fabric8.kubernetes.api.model.KubernetesResource
+import io.fabric8.kubernetes.api.model.Namespaced
+import io.fabric8.kubernetes.client.CustomResource
 import io.fabric8.kubernetes.client.DefaultKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 import mu.KotlinLogging
@@ -9,27 +11,21 @@ import theodolite.patcher.PatcherFactory
 import theodolite.util.*
 
 private val logger = KotlinLogging.logger {}
-
 private var DEFAULT_NAMESPACE = "default"
 
 @RegisterForReflection
-class KubernetesBenchmark : Benchmark {
+class KubernetesBenchmark : Benchmark, CustomResource(), Namespaced {
     lateinit var name: String
     lateinit var appResource: List<String>
     lateinit var loadGenResource: List<String>
     lateinit var resourceTypes: List<TypeName>
     lateinit var loadTypes: List<TypeName>
     lateinit var kafkaConfig: KafkaConfig
-    lateinit var namespace: String
-    lateinit var path: String
+    private val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
+    var path = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
 
     private fun loadKubernetesResources(resources: List<String>): List<Pair<String, KubernetesResource>> {
-        //val path = "./../../../resources/main/yaml/"
         val parser = YamlParser()
-
-        namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
-        logger.info { "Using $namespace as namespace." }
-
         val loader = K8sResourceLoader(DefaultKubernetesClient().inNamespace(namespace))
         return resources
             .map { resource ->
@@ -45,22 +41,32 @@ class KubernetesBenchmark : Benchmark {
         res: Resource,
         configurationOverrides: List<ConfigurationOverride?>
     ): BenchmarkDeployment {
+        logger.info { "Using $namespace as namespace." }
+        logger.info { "Using $path as resource path." }
+
         val resources = loadKubernetesResources(this.appResource + this.loadGenResource)
         val patcherFactory = PatcherFactory()
 
         // patch the load dimension the resources
-        load.getType().forEach { patcherDefinition -> patcherFactory.createPatcher(patcherDefinition, resources).patch(load.get().toString()) }
-        res.getType().forEach{ patcherDefinition -> patcherFactory.createPatcher(patcherDefinition, resources).patch(res.get().toString()) }
+        load.getType().forEach { patcherDefinition ->
+            patcherFactory.createPatcher(patcherDefinition, resources).patch(load.get().toString())
+        }
+        res.getType().forEach { patcherDefinition ->
+            patcherFactory.createPatcher(patcherDefinition, resources).patch(res.get().toString())
+        }
 
         // Patch the given overrides
-        configurationOverrides.forEach { override -> override?.let { patcherFactory.createPatcher(it.patcher, resources).patch(override.value) } }
-
-
+        configurationOverrides.forEach { override ->
+            override?.let {
+                patcherFactory.createPatcher(it.patcher, resources).patch(override.value)
+            }
+        }
         return KubernetesBenchmarkDeployment(
             namespace = namespace,
             resources = resources.map { r -> r.second },
             kafkaConfig = hashMapOf("bootstrap.servers" to kafkaConfig.bootstrapServer),
-            topics = kafkaConfig.getKafkaTopics()
+            topics = kafkaConfig.getKafkaTopics(),
+            client = DefaultKubernetesClient().inNamespace(namespace)
         )
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
index 238cb17071c5b48fc883808b4334b79dada7ee32..8e4fce681147ffe7c80b37bab1d0dbb094b4036e 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkDeployment.kt
@@ -1,7 +1,7 @@
 package theodolite.benchmark
 
 import io.fabric8.kubernetes.api.model.KubernetesResource
-import io.fabric8.kubernetes.client.DefaultKubernetesClient
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
 import io.quarkus.runtime.annotations.RegisterForReflection
 import org.apache.kafka.clients.admin.NewTopic
 import theodolite.k8s.K8sManager
@@ -12,13 +12,12 @@ class KubernetesBenchmarkDeployment(
     val namespace: String,
     val resources: List<KubernetesResource>,
     private val kafkaConfig: HashMap<String, Any>,
-    private val topics: Collection<NewTopic>
+    private val topics: Collection<NewTopic>,
+    private val client: NamespacedKubernetesClient
 ) : BenchmarkDeployment {
     private val kafkaController = TopicManager(this.kafkaConfig)
-    private val kubernetesManager = K8sManager(DefaultKubernetesClient().inNamespace(namespace))
-
+    private val kubernetesManager = K8sManager(client)
     private val LABEL = "app.kubernetes.io/name=kafka-lag-exporter"
-    private val client = DefaultKubernetesClient().inNamespace(namespace)
 
     override fun setup() {
         kafkaController.createTopics(this.topics)
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkList.kt b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkList.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0930875e96146fda58301478bda68b00c229e99f
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/benchmark/KubernetesBenchmarkList.kt
@@ -0,0 +1,5 @@
+package theodolite.benchmark
+
+import io.fabric8.kubernetes.client.CustomResourceList
+
+class KubernetesBenchmarkList : CustomResourceList<KubernetesBenchmark>()
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
index 2910d84991c2c37051b4b053c0c024344c0b3ff0..0b6c681c9123adace08bc60946a067442ca2baa1 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/evaluation/AnalysisExecutor.kt
@@ -9,14 +9,17 @@ import java.time.Instant
 
 private val logger = KotlinLogging.logger {}
 
-class AnalysisExecutor(private val slo: BenchmarkExecution.Slo) {
+class AnalysisExecutor(
+    private val slo: BenchmarkExecution.Slo,
+    private val executionId: Int
+) {
 
     private val fetcher = MetricFetcher(
         prometheusURL = slo.prometheusUrl,
         offset = Duration.ofHours(slo.offset.toLong())
     )
 
-    fun analyse(load: LoadDimension, res: Resource, executionDuration: Duration): Boolean {
+    fun analyze(load: LoadDimension, res: Resource, executionDuration: Duration): Boolean {
         var result = false
 
         try {
@@ -26,8 +29,7 @@ class AnalysisExecutor(private val slo: BenchmarkExecution.Slo) {
                 query = "sum by(group)(kafka_consumergroup_group_lag >= 0)"
             )
 
-            CsvExporter().toCsv(name = "${load.get()}_${res.get()}_${slo.sloType}", prom = prometheusData)
-
+            CsvExporter().toCsv(name = "$executionId-${load.get()}-${res.get()}-${slo.sloType}", prom = prometheusData)
             val sloChecker = SloCheckerFactory().create(
                 slotype = slo.sloType,
                 externalSlopeURL = slo.externalSloUrl,
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
index f18fc1cbbe989b41b8786630f6ee2dd8ffe174d3..a6eae8bbfb1273b90e3d457db3287d6fc1546fbe 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutor.kt
@@ -8,6 +8,7 @@ import theodolite.util.LoadDimension
 import theodolite.util.Resource
 import theodolite.util.Results
 import java.time.Duration
+import java.util.concurrent.atomic.AtomicBoolean
 
 private val logger = KotlinLogging.logger {}
 
@@ -24,9 +25,12 @@ abstract class BenchmarkExecutor(
     val results: Results,
     val executionDuration: Duration,
     configurationOverrides: List<ConfigurationOverride?>,
-    val slo: BenchmarkExecution.Slo
+    val slo: BenchmarkExecution.Slo,
+    val executionId: Int
 ) {
 
+    var run: AtomicBoolean = AtomicBoolean(true)
+
     /**
      * Run a experiment for the given parametrization, evaluate the experiment and save the result.
      *
@@ -35,19 +39,26 @@ abstract class BenchmarkExecutor(
      * @return True, if the number of resources are suitable for the given load, false otherwise.
      */
     abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean
-
+    
     /**
      * Wait while the benchmark is running and log the number of minutes executed every 1 minute.
      *
      */
     fun waitAndLog() {
         logger.info { "Execution of a new benchmark started." }
-        for (i in 1.rangeTo(executionDuration.toSeconds())) {
 
+        var secondsRunning = 0L
+
+        while (run.get() && secondsRunning < executionDuration.toSeconds()) {
+            secondsRunning++
             Thread.sleep(Duration.ofSeconds(1).toMillis())
-            if ((i % 60) == 0L) {
-                logger.info { "Executed: ${i / 60} minutes" }
+
+            if ((secondsRunning % 60) == 0L) {
+                logger.info { "Executed: ${secondsRunning / 60} minutes." }
             }
         }
+
+        logger.debug { "Executor shutdown gracefully." }
+
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
index 74c4ca3971daa2ac535a8f40c7448651cd3d6f7d..03c66e757abab9de69bc97ff98a67fffdafdf3d1 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/BenchmarkExecutorImpl.kt
@@ -19,20 +19,28 @@ class BenchmarkExecutorImpl(
     results: Results,
     executionDuration: Duration,
     private val configurationOverrides: List<ConfigurationOverride?>,
-    slo: BenchmarkExecution.Slo
-) : BenchmarkExecutor(benchmark, results, executionDuration, configurationOverrides, slo) {
+    slo: BenchmarkExecution.Slo,
+    executionId: Int
+) : BenchmarkExecutor(benchmark, results, executionDuration, configurationOverrides, slo, executionId) {
     override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
+        var result = false
         val benchmarkDeployment = benchmark.buildDeployment(load, res, this.configurationOverrides)
-        benchmarkDeployment.setup()
-        this.waitAndLog()
 
-        val result = AnalysisExecutor(slo = slo).analyse(load = load, res = res, executionDuration = executionDuration)
+        try {
+            benchmarkDeployment.setup()
+            this.waitAndLog()
+        } catch(e: Exception) {
+            logger.error { "Error while setup experiment." }
+            logger.error { "Error is: $e" }
+            this.run.set(false)
+        }
 
+        if (this.run.get()) {
+            result =
+                AnalysisExecutor(slo = slo, executionId = executionId).analyze(load = load, res = res, executionDuration = executionDuration)
+            this.results.setResult(Pair(load, res), result)
+        }
         benchmarkDeployment.teardown()
-
-        benchmarkDeployment.teardown()
-
-        this.results.setResult(Pair(load, res), result)
         return result
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4518ef7957104819b26eae95cf4e6e9b35c4e995
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Main.kt
@@ -0,0 +1,25 @@
+package theodolite.execution
+
+import io.quarkus.runtime.annotations.QuarkusMain
+import mu.KotlinLogging
+import theodolite.execution.operator.TheodoliteOperator
+import kotlin.system.exitProcess
+
+private val logger = KotlinLogging.logger {}
+
+@QuarkusMain
+object Main {
+
+    @JvmStatic
+    fun main(args: Array<String>) {
+
+        val mode = System.getenv("MODE") ?: "yaml-executor"
+        logger.info { "Start Theodolite with mode $mode" }
+
+        when(mode) {
+           "yaml-executor" -> TheodoliteYamlExecutor().start()
+            "operator" -> TheodoliteOperator().start()
+            else ->  {logger.error { "MODE $mode not found" }; exitProcess(1)}
+        }
+    }
+}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/Shutdown.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Shutdown.kt
index 9ca7e70f6ecd5ed30120940be8de965c73f79a6a..92aaef2923ed87e2bb2c3706ac4fc862538a222f 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/Shutdown.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/Shutdown.kt
@@ -8,10 +8,9 @@ import theodolite.util.Resource
 
 private val logger = KotlinLogging.logger {}
 
-class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) :
-    Thread() {
+class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val benchmark: KubernetesBenchmark) {
 
-    override fun run() {
+    fun run() {
         // Build Configuration to teardown
         logger.info { "Received shutdown signal -> Shutting down" }
         val deployment =
@@ -20,7 +19,7 @@ class Shutdown(private val benchmarkExecution: BenchmarkExecution, private val b
                 res = Resource(0, emptyList()),
                 configurationOverrides = benchmarkExecution.configOverrides
             )
-        logger.info { "Teardown the everything deployed" }
+        logger.info { "Teardown everything deployed" }
         deployment.teardown()
         logger.info { "Teardown completed" }
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
index 689c07fc6419f8d8a63c2c0fe5f2d5961e15e374..0c3e0d2fd6d1f40df5299c64b214d84323cba853 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteExecutor.kt
@@ -1,5 +1,6 @@
 package theodolite.execution
 
+import com.google.gson.GsonBuilder
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.benchmark.KubernetesBenchmark
 import theodolite.patcher.PatcherDefinitionFactory
@@ -9,12 +10,14 @@ import theodolite.util.Config
 import theodolite.util.LoadDimension
 import theodolite.util.Resource
 import theodolite.util.Results
+import java.io.PrintWriter
 import java.time.Duration
 
 class TheodoliteExecutor(
     private val config: BenchmarkExecution,
     private val kubernetesBenchmark: KubernetesBenchmark
 ) {
+    lateinit var executor: BenchmarkExecutor
 
     private fun buildConfig(): Config {
         val results = Results()
@@ -22,20 +25,26 @@ class TheodoliteExecutor(
 
         val executionDuration = Duration.ofSeconds(config.execution.duration)
 
-        val resourcePatcherDefinition = PatcherDefinitionFactory().createPatcherDefinition(
-            config.resources.resourceType,
-            this.kubernetesBenchmark.resourceTypes
-        )
+        val resourcePatcherDefinition =
+            PatcherDefinitionFactory().createPatcherDefinition(
+                config.resources.resourceType,
+                this.kubernetesBenchmark.resourceTypes
+            )
+
         val loadDimensionPatcherDefinition =
-            PatcherDefinitionFactory().createPatcherDefinition(config.load.loadType, this.kubernetesBenchmark.loadTypes)
+            PatcherDefinitionFactory().createPatcherDefinition(
+                config.load.loadType,
+                this.kubernetesBenchmark.loadTypes
+            )
 
-        val executor =
+        executor =
             BenchmarkExecutorImpl(
-                kubernetesBenchmark,
-                results,
-                executionDuration,
-                config.configOverrides,
-                config.slos[0]
+                benchmark = kubernetesBenchmark,
+                results = results,
+                executionDuration = executionDuration,
+                configurationOverrides = config.configOverrides,
+                slo = config.slos[0],
+                executionId = config.executionId
             )
 
         return Config(
@@ -57,12 +66,33 @@ class TheodoliteExecutor(
         )
     }
 
+    fun getExecution(): BenchmarkExecution {
+        return this.config
+    }
+
+    fun getBenchmark(): KubernetesBenchmark {
+        return this.kubernetesBenchmark
+    }
+
     fun run() {
-        val config = buildConfig()
+        storeAsFile(this.config, "${this.config.executionId}-execution-configuration")
+        storeAsFile(kubernetesBenchmark, "${this.config.executionId}-benchmark-configuration")
 
+        val config = buildConfig()
         // execute benchmarks for each load
         for (load in config.loads) {
-            config.compositeStrategy.findSuitableResource(load, config.resources)
+            if (executor.run.get()) {
+                config.compositeStrategy.findSuitableResource(load, config.resources)
+            }
+        }
+        storeAsFile(config.compositeStrategy.benchmarkExecutor.results, "${this.config.executionId}-result")
+    }
+
+    private fun <T> storeAsFile(saveObject: T, filename: String) {
+        val gson = GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting().create()
+
+        PrintWriter(filename).use { pw ->
+            pw.println(gson.toJson(saveObject))
         }
     }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt
index 8e856cac7286b6eb547b143e6cde8d1b7b56fb2b..6bddea20c05fb5c0eb6a5a3bd60b3ec2c6b9bd5d 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/TheodoliteYamlExecutor.kt
@@ -1,38 +1,36 @@
 package theodolite.execution
 
-import io.quarkus.runtime.annotations.QuarkusMain
 import mu.KotlinLogging
 import theodolite.benchmark.BenchmarkExecution
 import theodolite.benchmark.KubernetesBenchmark
 import theodolite.util.YamlParser
+import kotlin.concurrent.thread
 import kotlin.system.exitProcess
 
 private val logger = KotlinLogging.logger {}
 
-@QuarkusMain(name = "TheodoliteYamlExecutor")
-object TheodoliteYamlExecutor {
-    @JvmStatic
-    fun main(args: Array<String>) {
+class TheodoliteYamlExecutor {
+    private val parser = YamlParser()
+
+    fun start() {
         logger.info { "Theodolite started" }
 
         val executionPath = System.getenv("THEODOLITE_EXECUTION") ?: "./config/BenchmarkExecution.yaml"
         val benchmarkPath = System.getenv("THEODOLITE_BENCHMARK") ?: "./config/BenchmarkType.yaml"
-        val appResource = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
 
         logger.info { "Using $executionPath for BenchmarkExecution" }
         logger.info { "Using $benchmarkPath for BenchmarkType" }
-        logger.info { "Using $appResource for Resources" }
 
 
         // load the BenchmarkExecution and the BenchmarkType
-        val parser = YamlParser()
         val benchmarkExecution =
             parser.parse(path = executionPath, E = BenchmarkExecution::class.java)!!
         val benchmark =
             parser.parse(path = benchmarkPath, E = KubernetesBenchmark::class.java)!!
-        benchmark.path = appResource
 
-        val shutdown = Shutdown(benchmarkExecution, benchmark)
+        // Add shutdown hook
+        // Use thread{} with start = false, else the thread will start right away
+        val shutdown = thread(start = false) { Shutdown(benchmarkExecution, benchmark).run() }
         Runtime.getRuntime().addShutdownHook(shutdown)
 
         val executor = TheodoliteExecutor(benchmarkExecution, benchmark)
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/BenchmarkEventHandler.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/BenchmarkEventHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..2b4a784315c2961c5782264c44f2c7e4e8f0d2e8
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/BenchmarkEventHandler.kt
@@ -0,0 +1,35 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.informers.ResourceEventHandler
+import mu.KotlinLogging
+import theodolite.benchmark.KubernetesBenchmark
+private val logger = KotlinLogging.logger {}
+
+class BenchmarkEventHandler(private val controller: TheodoliteController): ResourceEventHandler<KubernetesBenchmark> {
+    override fun onAdd(benchmark: KubernetesBenchmark) {
+        benchmark.name = benchmark.metadata.name
+        logger.info { "Add new benchmark ${benchmark.name}." }
+        this.controller.benchmarks[benchmark.name] = benchmark
+    }
+
+    override fun onUpdate(oldBenchmark: KubernetesBenchmark, newBenchmark: KubernetesBenchmark) {
+        logger.info { "Update benchmark ${newBenchmark.metadata.name}." }
+        newBenchmark.name = newBenchmark.metadata.name
+        if (this.controller.isInitialized() &&  this.controller.executor.getBenchmark().name == oldBenchmark.metadata.name) {
+            this.controller.isUpdated.set(true)
+            this.controller.executor.executor.run.compareAndSet(true, false)
+        } else {
+            onAdd(newBenchmark)
+        }
+    }
+
+    override fun onDelete(benchmark: KubernetesBenchmark, b: Boolean) {
+        logger.info { "Delete benchmark ${benchmark.metadata.name}." }
+        this.controller.benchmarks.remove(benchmark.metadata.name)
+        if ( this.controller.isInitialized() &&  this.controller.executor.getBenchmark().name == benchmark.metadata.name) {
+            this.controller.isUpdated.set(true)
+            this.controller.executor.executor.run.compareAndSet(true, false)
+            logger.info { "Current benchmark stopped." }
+        }
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1752ac112ea84ea179e238f7ab8d808779014d1b
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/ExecutionEventHandler.kt
@@ -0,0 +1,36 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.informers.ResourceEventHandler
+import mu.KotlinLogging
+import theodolite.benchmark.BenchmarkExecution
+
+private val logger = KotlinLogging.logger {}
+
+class ExecutionHandler(private val controller: TheodoliteController): ResourceEventHandler<BenchmarkExecution> {
+    override fun onAdd(execution: BenchmarkExecution) {
+        execution.name = execution.metadata.name
+        logger.info { "Add new execution ${execution.metadata.name} to queue." }
+        this.controller.executionsQueue.add(execution)
+    }
+
+    override fun onUpdate(oldExecution: BenchmarkExecution, newExecution: BenchmarkExecution) {
+        logger.info { "Add updated execution to queue." }
+        newExecution.name = newExecution.metadata.name
+        this.controller.executionsQueue.removeIf { e -> e.name == newExecution.metadata.name }
+        this.controller.executionsQueue.addFirst(newExecution)
+        if (this.controller.isInitialized() &&  this.controller.executor.getExecution().name == newExecution.metadata.name) {
+            this.controller.isUpdated.set(true)
+            this.controller.executor.executor.run.compareAndSet(true, false)
+        }
+    }
+
+    override fun onDelete(execution: BenchmarkExecution, b: Boolean) {
+        logger.info { "Delete execution ${execution.metadata.name} from queue." }
+        this.controller.executionsQueue.removeIf { e -> e.name == execution.metadata.name }
+        if (this.controller.isInitialized() && this.controller.executor.getExecution().name == execution.metadata.name) {
+            this.controller.isUpdated.set(true)
+            this.controller.executor.executor.run.compareAndSet(true, false)
+            logger.info { "Current benchmark stopped." }
+        }
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
new file mode 100644
index 0000000000000000000000000000000000000000..9e6280cf3c8160ef686fd6dcee45276de7e67fa7
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteController.kt
@@ -0,0 +1,83 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
+import khttp.patch
+import mu.KotlinLogging
+import theodolite.benchmark.BenchmarkExecution
+import theodolite.benchmark.KubernetesBenchmark
+import theodolite.execution.TheodoliteExecutor
+import java.lang.Thread.sleep
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.ConcurrentLinkedDeque
+import java.util.concurrent.atomic.AtomicBoolean
+import java.util.concurrent.atomic.AtomicInteger
+
+private val logger = KotlinLogging.logger {}
+
+class TheodoliteController(
+    val client: NamespacedKubernetesClient,
+    val executionContext: CustomResourceDefinitionContext,
+    val path: String
+) {
+    lateinit var executor: TheodoliteExecutor
+    val executionsQueue: ConcurrentLinkedDeque<BenchmarkExecution> = ConcurrentLinkedDeque()
+    val benchmarks: ConcurrentHashMap<String, KubernetesBenchmark> = ConcurrentHashMap()
+    var isUpdated = AtomicBoolean(false)
+    var executionID = AtomicInteger(0)
+
+    fun run() {
+        while (true) {
+            try {
+                reconcile()
+                logger.info { "Theodolite is waiting for new matching benchmark and execution." }
+                logger.info { "Currently available executions: " }
+                executionsQueue.forEach {
+                    logger.info { "${it.name} : waiting for : ${it.benchmark}" }
+                }
+                logger.info { "Currently available benchmarks: " }
+                benchmarks.forEach {
+                    logger.info { it.key }
+                }
+                sleep(2000)
+            } catch (e: InterruptedException) {
+                logger.error { "Execution interrupted with error: $e." }
+            }
+        }
+    }
+
+    @Synchronized
+    private fun reconcile() {
+        while (executionsQueue.isNotEmpty()) {
+            val execution = executionsQueue.peek()
+            val benchmark = benchmarks[execution.benchmark]
+
+            if (benchmark == null) {
+                logger.debug { "No benchmark found for execution ${execution.name}." }
+                sleep(1000)
+            } else {
+                runExecution(execution, benchmark)
+            }
+        }
+    }
+
+    @Synchronized
+    fun runExecution(execution: BenchmarkExecution, benchmark: KubernetesBenchmark) {
+        execution.executionId = executionID.getAndSet(executionID.get() + 1)
+        isUpdated.set(false)
+        benchmark.path = path
+        logger.info { "Start execution ${execution.name} with benchmark ${benchmark.name}." }
+        executor = TheodoliteExecutor(config = execution, kubernetesBenchmark = benchmark)
+        executor.run()
+
+        if (!isUpdated.get()) {
+            client.customResource(executionContext).delete(client.namespace, execution.metadata.name)
+        }
+        logger.info { "Execution of ${execution.name} is finally stopped." }
+    }
+
+    @Synchronized
+    fun isInitialized(): Boolean {
+        return ::executor.isInitialized
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
new file mode 100644
index 0000000000000000000000000000000000000000..c6181d19bcedfdb36e455b540e19bf0a54a2a297
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/execution/operator/TheodoliteOperator.kt
@@ -0,0 +1,66 @@
+package theodolite.execution.operator
+
+import io.fabric8.kubernetes.client.DefaultKubernetesClient
+import io.fabric8.kubernetes.internal.KubernetesDeserializer
+import mu.KotlinLogging
+import theodolite.benchmark.BenchmarkExecution
+import theodolite.benchmark.BenchmarkExecutionList
+import theodolite.benchmark.KubernetesBenchmark
+import theodolite.benchmark.KubernetesBenchmarkList
+import theodolite.k8s.K8sContextFactory
+
+
+private const val DEFAULT_NAMESPACE = "default"
+private const val SCOPE = "Namespaced"
+private const val EXECUTION_SINGULAR = "execution"
+private const val EXECUTION_PLURAL = "executions"
+private const val BENCHMARK_SINGULAR = "benchmark"
+private const val BENCHMARK_PLURAL = "benchmarks"
+private const val API_VERSION = "v1alpha1"
+private const val RESYNC_PERIOD = 10 * 60 * 1000.toLong()
+private const val GROUP = "theodolite.com"
+private val logger = KotlinLogging.logger {}
+
+class TheodoliteOperator {
+    private val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
+
+    fun start() {
+        logger.info { "Using $namespace as namespace." }
+        val client = DefaultKubernetesClient().inNamespace(namespace)
+
+        KubernetesDeserializer.registerCustomKind(
+            "$GROUP/$API_VERSION",
+            EXECUTION_SINGULAR,
+            BenchmarkExecution::class.java
+        )
+
+        KubernetesDeserializer.registerCustomKind(
+            "$GROUP/$API_VERSION",
+            BENCHMARK_SINGULAR,
+            KubernetesBenchmark::class.java
+        )
+
+        val contextFactory = K8sContextFactory()
+        val executionContext = contextFactory.create(API_VERSION, SCOPE, GROUP, EXECUTION_PLURAL)
+        val benchmarkContext = contextFactory.create(API_VERSION, SCOPE, GROUP, BENCHMARK_PLURAL)
+
+        val appResource = System.getenv("THEODOLITE_APP_RESOURCES") ?: "./config"
+        val controller = TheodoliteController(client = client, executionContext = executionContext, path = appResource)
+
+        val informerFactory = client.informers()
+        val informerExecution = informerFactory.sharedIndexInformerForCustomResource(
+            executionContext, BenchmarkExecution::class.java,
+            BenchmarkExecutionList::class.java, RESYNC_PERIOD
+        )
+        val informerBenchmark = informerFactory.sharedIndexInformerForCustomResource(
+            benchmarkContext, KubernetesBenchmark::class.java,
+            KubernetesBenchmarkList::class.java, RESYNC_PERIOD
+        )
+
+        informerExecution.addEventHandler(ExecutionHandler(controller))
+        informerBenchmark.addEventHandler(BenchmarkEventHandler(controller))
+        informerFactory.startAllRegisteredInformers()
+
+        controller.run()
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8fd822c615da4fab37dafb6927032f64db6c4462
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sContextFactory.kt
@@ -0,0 +1,15 @@
+package theodolite.k8s
+
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
+
+class K8sContextFactory {
+
+    fun create(api: String, scope: String, group: String, plural: String  ) : CustomResourceDefinitionContext{
+       return CustomResourceDefinitionContext.Builder()
+            .withVersion(api)
+            .withScope(scope)
+            .withGroup(group)
+            .withPlural(plural)
+            .build()
+    }
+}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt
deleted file mode 100644
index 8b3ac08265d5caa75f602b18e279e36efd24e187..0000000000000000000000000000000000000000
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sCustomResourceWrapper.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package theodolite.k8s
-
-import io.fabric8.kubernetes.client.CustomResource
-import io.fabric8.kubernetes.client.NamespacedKubernetesClient
-import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext
-
-/**
-* Fabric8 handles custom resources as plain HashMaps. These need to be handled differently than normal
-* Kubernetes resources.  The K8sCustomResourceWrapper class provides a wrapper to deploy and delete
-* custom resources in a uniform way.
-*
-* @property map custom resource as plain hashmap
-* @constructor Create empty K8s custom resource wrapper
-*/
-class K8sCustomResourceWrapper(private val map : Map<String,String>) : CustomResource() {
-
-
-    /**
-     * Deploy a custom resource
-     *
-     * @param client a namespaced Kubernetes client which are used to deploy the CR object.
-     */
-    fun deploy(client : NamespacedKubernetesClient){
-        val kind = this.map["kind"]
-        // Search the CustomResourceDefinition to which the CR Object belongs.
-        // This should be exactly one if the CRD is registered for Kubernetes, zero otherwise.
-        val crds = client.apiextensions().v1beta1().customResourceDefinitions().list()
-        crds.items
-            .filter { crd -> crd.toString().contains("kind=$kind") }
-            .map { crd -> CustomResourceDefinitionContext.fromCrd(crd) }
-            .forEach { context ->
-                client.customResource(context).createOrReplace(client.configuration.namespace,this.map as Map<String, Any>)
-            }
-    }
-
-    /**
-     * Delete a custom resource
-     *
-     * @param client a namespaced Kubernetes client which are used to delete the CR object.
-     */
-    fun delete(client : NamespacedKubernetesClient){
-        val kind = this.map["kind"]
-        val metadata = this.map["metadata"] as HashMap<String,String>
-        val name = metadata["name"]
-
-        val crds = client.apiextensions().v1beta1().customResourceDefinitions().list()
-        crds.items
-            .filter { crd -> crd.toString().contains("kind=$kind") }
-            .map { crd -> CustomResourceDefinitionContext.fromCrd(crd)   }
-            .forEach { context ->
-                client.customResource(context).delete(client.configuration.namespace,name) }
-    }
-
-}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
index 38a07545513d7713f61e484702cb48143ab3aed0..029f18c30b79bbbf36c3761ced107e23f39682d8 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sManager.kt
@@ -19,7 +19,7 @@ class K8sManager(private val client: NamespacedKubernetesClient) {
                 this.client.configMaps().createOrReplace(resource)
             is StatefulSet ->
                 this.client.apps().statefulSets().createOrReplace(resource)
-            is K8sCustomResourceWrapper -> resource.deploy(client)
+            is ServiceMonitorWrapper -> resource.deploy(client)
             else -> throw IllegalArgumentException("Unknown Kubernetes resource.")
         }
     }
@@ -34,7 +34,7 @@ class K8sManager(private val client: NamespacedKubernetesClient) {
                 this.client.configMaps().delete(resource)
             is StatefulSet ->
                 this.client.apps().statefulSets().delete(resource)
-            is K8sCustomResourceWrapper -> resource.delete(client)
+            is ServiceMonitorWrapper -> resource.delete(client)
             else -> throw IllegalArgumentException("Unknown Kubernetes resource.")
         }
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt
index 658af46611ec7e1e784d286391ecf1e25a25366e..bf4af6c531064d42a9fcee1b22058850a560427d 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/K8sResourceLoader.kt
@@ -26,8 +26,8 @@ class K8sResourceLoader(private val client: NamespacedKubernetesClient) {
      * @param path of the yaml file
      * @return customResource from fabric8
      */
-    fun loadCustomResource(path: String): K8sCustomResourceWrapper {
-        return loadGenericResource(path) { x: String -> K8sCustomResourceWrapper(YamlParser().parse(path, HashMap<String, String>()::class.java)!!) }
+    private fun loadServiceMonitor(path: String): ServiceMonitorWrapper {
+        return loadGenericResource(path) { x: String -> ServiceMonitorWrapper(YamlParser().parse(path, HashMap<String, String>()::class.java)!!) }
     }
 
     /**
@@ -73,16 +73,11 @@ class K8sResourceLoader(private val client: NamespacedKubernetesClient) {
         return when (kind) {
             "Deployment" -> loadDeployment(path)
             "Service" -> loadService(path)
-            "ServiceMonitor" -> loadCustomResource(path)
+            "ServiceMonitor" -> loadServiceMonitor(path)
             "ConfigMap" -> loadConfigmap(path)
             else -> {
-                    logger.warn { "Try to load $kind from $path as Custom ressource" }
-                    try{
-                        loadCustomResource(path)
-                    } catch (e:Exception){
-                        logger.error { "Error during loading of unspecified CustomResource: $e" }
-                        throw e
-                    }
+                logger.error { "Error during loading of unspecified resource Kind" }
+                throw java.lang.IllegalArgumentException("error while loading resource with kind: $kind")
             }
         }
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/ServiceMonitorWrapper.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/ServiceMonitorWrapper.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4950cee225e103ff095def91de64471ec1894a79
--- /dev/null
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/ServiceMonitorWrapper.kt
@@ -0,0 +1,56 @@
+package theodolite.k8s
+
+import io.fabric8.kubernetes.client.CustomResource
+import io.fabric8.kubernetes.client.NamespacedKubernetesClient
+import mu.KotlinLogging
+
+private val logger = KotlinLogging.logger {}
+
+class ServiceMonitorWrapper(private val serviceMonitor: Map<String, String>) : CustomResource() {
+
+    /**
+     * Deploy a service monitor
+     *
+     * @param client a namespaced Kubernetes client which are used to deploy the CR object.
+     *
+     * @throws java.io.IOException if the resource could not be deployed.
+     */
+    fun deploy(client: NamespacedKubernetesClient) {
+        val serviceMonitorContext = K8sContextFactory().create(
+            api = "v1",
+            scope = "Namespaced",
+            group = "monitoring.coreos.com",
+            plural = "servicemonitors"
+        )
+        client.customResource(serviceMonitorContext)
+            .createOrReplace(client.configuration.namespace, this.serviceMonitor as Map<String, Any>)
+    }
+
+    /**
+     * Delete a service monitor
+     *
+     * @param client a namespaced Kubernetes client which are used to delete the CR object.
+     */
+    fun delete(client: NamespacedKubernetesClient) {
+        val serviceMonitorContext = K8sContextFactory().create(
+            api = "v1",
+            scope = "Namespaced",
+            group = "monitoring.coreos.com",
+            plural = "servicemonitors"
+        )
+        try {
+            client.customResource(serviceMonitorContext)
+                .delete(client.configuration.namespace, this.getServiceMonitorName())
+        } catch (e: Exception) {
+            logger.warn { "Could not delete service monitor" }
+        }
+    }
+
+    /**
+     * @throws NullPointerException if name or metadata is null
+     */
+    private fun getServiceMonitorName(): String {
+        val smAsMap = this.serviceMonitor["metadata"]!! as Map<String, String>
+        return smAsMap["name"]!!
+    }
+}
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
index 1336f57517ef74d8c781cc3b51bf130dbf8d99c5..390974cd247645197ebe6044bf785710164155aa 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/k8s/TopicManager.kt
@@ -12,52 +12,35 @@ private val logger = KotlinLogging.logger {}
  * Manages the topics related tasks
  * @param kafkaConfig Kafka Configuration as HashMap
  */
-class TopicManager(kafkaConfig: HashMap<String, Any>) {
-    private lateinit var kafkaAdmin: AdminClient
-
-    init {
-        try {
-            kafkaAdmin = AdminClient.create(kafkaConfig)
-        } catch (e: Exception) {
-            logger.error { e.toString() }
-        }
-    }
+class TopicManager(private val kafkaConfig: HashMap<String, Any>) {
 
     /**
      * Creates topics.
      * @param newTopics List of all Topic which should be created
      */
     fun createTopics(newTopics: Collection<NewTopic>) {
+        var kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
         kafkaAdmin.createTopics(newTopics)
+        kafkaAdmin.close()
         logger.info { "Topics created" }
     }
 
-    fun createTopics(topics: List<String>, numPartitions: Int, replicationFactor: Short) {
-        val newTopics = mutableSetOf<NewTopic>()
-        for (i in topics) {
-            val tops = NewTopic(i, numPartitions, replicationFactor)
-            newTopics.add(tops)
-        }
-        kafkaAdmin.createTopics(newTopics)
-        logger.info { "Creation of $topics started" }
-    }
 
     /**
      * Removes topics.
      * @param topics
      */
     fun removeTopics(topics: List<String>) {
+        var kafkaAdmin: AdminClient = AdminClient.create(this.kafkaConfig)
         val result = kafkaAdmin.deleteTopics(topics)
 
         try {
             result.all().get()
-        } catch (ex: Exception) {
-            logger.error { ex.toString() }
+        } catch (e: Exception) {
+            logger.error { "Error while removing topics: $e"  }
+            logger.debug { "Existing topics are: ${kafkaAdmin.listTopics()}."  }
         }
+        kafkaAdmin.close()
         logger.info { "Topics removed" }
     }
-
-    fun getTopics(): ListTopicsResult? {
-        return kafkaAdmin.listTopics()
-    }
 }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
index ca34e9e3511f0ee35eff8f2ccf0cbd0582fc8646..b4b33fabc5a27e3cc52f5cda889f63bc61adbf5f 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/ReplicaPatcher.kt
@@ -4,10 +4,10 @@ import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.api.model.apps.Deployment
 
 class ReplicaPatcher(private val k8sResource: KubernetesResource) : AbstractPatcher(k8sResource) {
-    override fun <Int> patch(value: Int) {
+    override fun <String> patch(value: String) {
         if (k8sResource is Deployment) {
-            if (value is kotlin.Int) {
-                this.k8sResource.spec.replicas = value
+            if (value is kotlin.String) {
+                this.k8sResource.spec.replicas = Integer.parseInt(value)
             }
         }
     }
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
index 88d9a978f23c8c5612d2ad46df795b7e3ba8cd19..6d6505192daac3331e5c99b9706ca7413e98ea7d 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/patcher/SchedulerNamePatcher.kt
@@ -3,10 +3,10 @@ package theodolite.patcher
 import io.fabric8.kubernetes.api.model.KubernetesResource
 import io.fabric8.kubernetes.api.model.apps.Deployment
 
-class SchedulerNamePatcher(private val k8sResource: KubernetesResource): Patcher {
+class SchedulerNamePatcher(private val k8sResource: KubernetesResource) : Patcher {
     override fun <String> patch(value: String) {
         if (k8sResource is Deployment) {
-            k8sResource.spec.template.spec.schedulerName = value as kotlin.String;
+            k8sResource.spec.template.spec.schedulerName = value as kotlin.String
         }
     }
 }
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/ConfigurationOverride.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/ConfigurationOverride.kt
index bf517595ac7a28d2dada3f4f1d5f75b6db1dae0e..c4801dfbab0beb01cab025200cceab17efb0053d 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/ConfigurationOverride.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/ConfigurationOverride.kt
@@ -1,7 +1,9 @@
 package theodolite.util
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
 
+@JsonDeserialize
 @RegisterForReflection
 class ConfigurationOverride {
     lateinit var patcher: PatcherDefinition
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
index 46960ccdb1aedad1c104f6f5ec2082077f55e4de..cb94c8b7bfac4c3bc043e04a67d673ccaddea3c5 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/KafkaConfig.kt
@@ -1,10 +1,12 @@
 package theodolite.util
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
 import org.apache.kafka.clients.admin.NewTopic
 import kotlin.properties.Delegates
 
 @RegisterForReflection
+@JsonDeserialize
 class KafkaConfig {
     lateinit var bootstrapServer: String
     lateinit var topics: List<TopicWrapper>
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/PatcherDefinition.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/PatcherDefinition.kt
index 9ebe82a66382d238f314e1c6853265eca6690abd..e78048cd7691f8bfd14f663d401384ae6c329d4b 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/PatcherDefinition.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/PatcherDefinition.kt
@@ -1,7 +1,9 @@
 package theodolite.util
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
 
+@JsonDeserialize
 @RegisterForReflection
 class PatcherDefinition {
     lateinit var type: String
diff --git a/theodolite-quarkus/src/main/kotlin/theodolite/util/TypeName.kt b/theodolite-quarkus/src/main/kotlin/theodolite/util/TypeName.kt
index 2a83eef700edd1f1017dcb5d9fdbffbc20d6dafd..20758466c5d5efbcb999bf0bf9c4edbe63ea1032 100644
--- a/theodolite-quarkus/src/main/kotlin/theodolite/util/TypeName.kt
+++ b/theodolite-quarkus/src/main/kotlin/theodolite/util/TypeName.kt
@@ -1,8 +1,10 @@
 package theodolite.util
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize
 import io.quarkus.runtime.annotations.RegisterForReflection
 
 @RegisterForReflection
+@JsonDeserialize
 class TypeName {
     lateinit var typeName: String
     lateinit var patchers: List<PatcherDefinition>
diff --git a/theodolite-quarkus/src/main/resources/application.properties b/theodolite-quarkus/src/main/resources/application.properties
index 318ce68ff1ae344f44288bfaacfbc43538211f50..42647e2391706286602945cf2be7baa96857ba19 100644
--- a/theodolite-quarkus/src/main/resources/application.properties
+++ b/theodolite-quarkus/src/main/resources/application.properties
@@ -1,4 +1,6 @@
-quarkus.package.main-class=TheodoliteYamlExecutor
 quarkus.native.additional-build-args=\
   --initialize-at-run-time=io.fabric8.kubernetes.client.internal.CertUtils,\
-  --report-unsupported-elements-at-runtime
\ No newline at end of file
+  --initialize-at-run-time=io.fabric8.kubernetes.client.dsl.internal.uploadable.PodUpload,\
+  --initialize-at-run-time=io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl$1,\
+  --initialize-at-run-time=io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl$3,\
+  --report-unsupported-elements-at-runtime
diff --git a/theodolite-quarkus/src/main/resources/operator/benchmarkCRD.yaml b/theodolite-quarkus/src/main/resources/operator/benchmarkCRD.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8fb3de1928f051d338a78ee58da074a73ef933c1
--- /dev/null
+++ b/theodolite-quarkus/src/main/resources/operator/benchmarkCRD.yaml
@@ -0,0 +1,13 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: benchmarks.theodolite.com
+spec:
+  group: theodolite.com
+  version: v1alpha1
+  names:
+    kind: benchmark
+    plural: benchmarks
+  scope: Namespaced
+  subresources:
+    status: {}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml b/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9fc16f92e303f05a449f7e8b83600c3b299f215d
--- /dev/null
+++ b/theodolite-quarkus/src/main/resources/operator/example-benchmark-k8s-resource.yaml
@@ -0,0 +1,29 @@
+apiVersion: theodolite.com/v1alpha1
+kind: benchmark
+metadata:
+  name: uc1-kstreams
+appResource:
+  - "uc1-kstreams-deployment.yaml"
+  - "aggregation-service.yaml"
+  - "jmx-configmap.yaml"
+loadGenResource:
+  - "uc1-load-generator-deployment.yaml"
+  - "uc1-load-generator-service.yaml"
+resourceTypes:
+  - typeName: "Instances"
+    patchers:
+      - type: "ReplicaPatcher"
+        resource: "uc1-kstreams-deployment.yaml"
+loadTypes:
+  - typeName: "NumSensors"
+    patchers:
+      - type: "EnvVarPatcher"
+        resource: "uc1-load-generator-deployment.yaml"
+        container: "workload-generator"
+        variableName: "NUM_SENSORS"
+kafkaConfig:
+  bootstrapServer: "localhost:31290"
+  topics:
+    - name: "input"
+      numPartitions: 40
+      replicationFactor: 1
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/resources/operator/example-execution-k8s-resource.yaml b/theodolite-quarkus/src/main/resources/operator/example-execution-k8s-resource.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ef625dfe6ec78c2cc0ed099dfee0f767d57263bb
--- /dev/null
+++ b/theodolite-quarkus/src/main/resources/operator/example-execution-k8s-resource.yaml
@@ -0,0 +1,37 @@
+apiVersion: theodolite.com/v1alpha1
+kind: execution
+metadata:
+  name: theodolite-example-execution
+benchmark: "uc1-kstreams"
+load:
+  loadType: "NumSensors"
+  loadValues:
+    - 50000
+resources:
+  resourceType: "Instances"
+  resourceValues:
+    - 1
+slos:
+  - sloType: "lag trend"
+    threshold: 1000
+    prometheusUrl: "http://localhost:32656"
+    externalSloUrl: "http://localhost:80/evaluate-slope"
+    offset: 0
+    warmup: 0
+execution:
+  strategy: "LinearSearch"
+  duration: 60
+  repetitions: 1
+  restrictions:
+    - "LowerBound"
+configOverrides:
+  - patcher:
+      type: "NodeSelectorPatcher"
+      resource: "uc1-load-generator-deployment.yaml"
+      variableName: "env"
+    value: "prod"
+  - patcher:
+      type: "NodeSelectorPatcher"
+      resource: "uc1-kstreams-deployment.yaml"
+      variableName: "env"
+    value: "prod"
\ No newline at end of file
diff --git a/theodolite-quarkus/src/main/resources/operator/executionCRD.yaml b/theodolite-quarkus/src/main/resources/operator/executionCRD.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0bdb83c6201112a750bad41b81321b7a108a66fa
--- /dev/null
+++ b/theodolite-quarkus/src/main/resources/operator/executionCRD.yaml
@@ -0,0 +1,13 @@
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: executions.theodolite.com
+spec:
+  group: theodolite.com
+  version: v1alpha1
+  names:
+    kind: execution
+    plural: executions
+  scope: Namespaced
+  subresources:
+    status: {}
\ No newline at end of file
diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt b/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt
index 67c9857220a0d419183644ffaf8c6a6e16a6ce9b..7802529bfda309131cafc0ab3f39fda43285c32f 100644
--- a/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt
+++ b/theodolite-quarkus/src/test/kotlin/theodolite/CompositeStrategyTest.kt
@@ -31,7 +31,7 @@ class CompositeStrategyTest {
         val results = Results()
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker)
+        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker, 0)
         val linearSearch = LinearSearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
@@ -65,7 +65,7 @@ class CompositeStrategyTest {
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
         val benchmarkExecutorImpl =
-            TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker)
+            TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker, 0)
         val binarySearch = BinarySearch(benchmarkExecutorImpl)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
@@ -98,7 +98,7 @@ class CompositeStrategyTest {
         val results = Results()
         val benchmark = TestBenchmark()
         val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
-        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker)
+        val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, sloChecker, 0)
         val binarySearch = BinarySearch(benchmarkExecutor)
         val lowerBoundRestriction = LowerBoundRestriction(results)
         val strategy =
diff --git a/theodolite-quarkus/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt b/theodolite-quarkus/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
index 2de07d48dbe59313506745e6c97b2ae9a5ed114e..2bafcb76dfc3463d9aa350b88c9f73d52cea6629 100644
--- a/theodolite-quarkus/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
+++ b/theodolite-quarkus/src/test/kotlin/theodolite/TestBenchmarkExecutorImpl.kt
@@ -12,14 +12,16 @@ class TestBenchmarkExecutorImpl(
     private val mockResults: Array<Array<Boolean>>,
     benchmark: Benchmark,
     results: Results,
-    slo: BenchmarkExecution.Slo
+    slo: BenchmarkExecution.Slo,
+    executionId: Int
 ) :
     BenchmarkExecutor(
         benchmark,
         results,
         executionDuration = Duration.ofSeconds(1),
         configurationOverrides = emptyList(),
-        slo = slo
+        slo = slo,
+        executionId = executionId
     ) {
 
     override fun runExperiment(load: LoadDimension, res: Resource): Boolean {