diff --git a/handlers/main.yml b/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c8e102186a3daffd3caf1734f50976efa4e273a0
--- /dev/null
+++ b/handlers/main.yml
@@ -0,0 +1,3 @@
+- name: reload systemd
+  systemd:
+    daemon_reload: True
diff --git a/tasks/main.yml b/tasks/main.yml
index 45cd959376ffdacb29fc4f4b1be3cbfd3dcef1e6..367465269e91b44b0441564e8ddbcef74aea3d77 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -47,13 +47,28 @@
       - backup-all-vms
       - backup-full
       - backup-cronjob
+      - backup-check
     template:
       src: "{{ item }}.j2"
       dest: "/usr/local/bin/{{ item }}"
       owner: root
       group: root
-      mode: 0700
+      mode: 0755
       validate: /bin/bash -n %s
+  - name: copy systemd services
+    notify:
+      - reload systemd
+    loop:
+      - backup-check
+      - backup-retention
+      - backup-run
+    template:
+      src: "{{ item }}.service.j2"
+      dest: "/etc/systemd/system/{{ item }}.service"
+      owner: root
+      group: root
+      mode: 0644
+#      validate: /usr/bin/systemd-analyze verify %s
   - name: create data folder
     file:
       path: /var/backup-client/
diff --git a/templates/backup-check.j2 b/templates/backup-check.j2
new file mode 100755
index 0000000000000000000000000000000000000000..dd313992e686fd0024d1017b34be3f9fa2d8a2a7
--- /dev/null
+++ b/templates/backup-check.j2
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -euo pipefail
+
+{% if backup_backend == 'restic' %}
+# restic backend
+source /etc/backup-client/restic.env
+
+restic check --read-data
+
+{% endif %}
+
+{% if not backup_backend %}
+echo "Noop, backup is handled external"
+{% endif %}
diff --git a/templates/backup-check.service.j2 b/templates/backup-check.service.j2
new file mode 100644
index 0000000000000000000000000000000000000000..9f1dfb387b524297434f926a669ba54a0d1d2ae0
--- /dev/null
+++ b/templates/backup-check.service.j2
@@ -0,0 +1,10 @@
+[Unit]
+Description=Check backup consistency
+OnFailure=status-email-root@%n.service
+
+[Service]
+Nice=19
+IOSchedulingClass=idle
+Type=simple
+ExecStart=/usr/local/bin/backup-check
+
diff --git a/templates/backup-full.j2 b/templates/backup-full.j2
index ac525d0049c977d6f2f8c3dbaa585a18305f980b..a5956b8ba6110075a3f0f9a14f8c6af7764a5eb4 100755
--- a/templates/backup-full.j2
+++ b/templates/backup-full.j2
@@ -7,7 +7,3 @@ set -euo pipefail
 {% if backups.mode in ['hypervisor-restic'] %}
 	backup-all-vms
 {% endif %}
-{% if backup_executor %}
-	backup-retention
-{% endif %}
-
diff --git a/templates/backup-retention.j2 b/templates/backup-retention.j2
index 1a76bc4e0dba5ae212ec402dcd1e824b05e5376e..478631d444cdf760a0c6e7a4a11050bc44e72f94 100755
--- a/templates/backup-retention.j2
+++ b/templates/backup-retention.j2
@@ -7,6 +7,7 @@ source /etc/backup-client/retention.env
 # restic backend
 source /etc/backup-client/restic.env
 restic forget \
+	--cleanup-cache \
 	--verbose \
 	--prune \
 	--group-by "host,paths,tags" \
@@ -17,3 +18,6 @@ restic forget \
 	--keep-yearly ${BACKUP_RETENTION_YEARS}
 
 {% endif %}
+{% if not backup_backend %}
+echo "Noop, backup is handled external"
+{% endif %}
diff --git a/templates/backup-retention.service.j2 b/templates/backup-retention.service.j2
new file mode 100644
index 0000000000000000000000000000000000000000..19004940056a244052549f128b4ed4c1bcf92359
--- /dev/null
+++ b/templates/backup-retention.service.j2
@@ -0,0 +1,10 @@
+[Unit]
+Description=Delete no longer needed backups
+OnFailure=status-email-root@%n.service
+
+[Service]
+Nice=19
+IOSchedulingClass=idle
+Type=simple
+ExecStart=/usr/local/bin/backup-retention
+
diff --git a/templates/backup-run.service.j2 b/templates/backup-run.service.j2
new file mode 100644
index 0000000000000000000000000000000000000000..9f277f4af1b53994cc216877f4015206bce3d065
--- /dev/null
+++ b/templates/backup-run.service.j2
@@ -0,0 +1,10 @@
+[Unit]
+Description=Backup system
+OnFailure=status-email-root@%n.service
+
+[Service]
+Nice=19
+IOSchedulingClass=idle
+Type=simple
+ExecStart=/usr/local/bin/backup-full
+