diff --git a/lib/config/bloc_config.dart b/lib/config/bloc_config.dart
index b7d87f2e..ff7a8236 100644
--- a/lib/config/bloc_config.dart
+++ b/lib/config/bloc_config.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/cubit/connection_status/connection_status_bloc.dart';
 import 'package:selfprivacy/logic/cubit/devices/devices_cubit.dart';
 import 'package:selfprivacy/logic/cubit/recovery_key/recovery_key_cubit.dart';
@@ -11,7 +12,6 @@ import 'package:selfprivacy/logic/cubit/dns_records/dns_records_cubit.dart';
 import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
 import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
 import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
 import 'package:selfprivacy/logic/cubit/support_system/support_system_cubit.dart';
 import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
 import 'package:selfprivacy/logic/cubit/provider_volumes/provider_volume_cubit.dart';
@@ -28,7 +28,7 @@ class BlocAndProviderConfig extends StatelessWidget {
     final serverInstallationCubit = ServerInstallationCubit()..load();
     final supportSystemCubit = SupportSystemCubit();
     final usersCubit = UsersCubit(serverInstallationCubit);
-    final servicesCubit = ServicesCubit(serverInstallationCubit);
+    final servicesBloc = ServicesBloc();
     final backupsBloc = BackupsBloc();
     final dnsRecordsCubit = DnsRecordsCubit(serverInstallationCubit);
     final recoveryKeyCubit = RecoveryKeyCubit(serverInstallationCubit);
@@ -61,8 +61,7 @@ class BlocAndProviderConfig extends StatelessWidget {
           lazy: false,
         ),
         BlocProvider(
-          create: (final _) => servicesCubit..load(),
-          lazy: false,
+          create: (final _) => servicesBloc,
         ),
         BlocProvider(
           create: (final _) => backupsBloc,
@@ -92,7 +91,7 @@ class BlocAndProviderConfig extends StatelessWidget {
         BlocProvider(
           create: (final _) => JobsCubit(
             usersCubit: usersCubit,
-            servicesCubit: servicesCubit,
+            servicesBloc: servicesBloc,
           ),
         ),
       ],
diff --git a/lib/logic/bloc/backups/backups_bloc.dart b/lib/logic/bloc/backups/backups_bloc.dart
index 55d4753a..fcdedfeb 100644
--- a/lib/logic/bloc/backups/backups_bloc.dart
+++ b/lib/logic/bloc/backups/backups_bloc.dart
@@ -193,7 +193,8 @@ class BackupsBloc extends Bloc<BackupsEvent, BackupsState> {
             );
     if (result.success == false) {
       getIt<NavigationService>().showSnackBar(
-          result.message ?? "Couldn't initialize repository on your server.");
+        result.message ?? "Couldn't initialize repository on your server.",
+      );
       emit(BackupsUnititialized());
       return;
     }
diff --git a/lib/logic/bloc/backups/backups_state.dart b/lib/logic/bloc/backups/backups_state.dart
index 153b1e4e..e41c3b74 100644
--- a/lib/logic/bloc/backups/backups_state.dart
+++ b/lib/logic/bloc/backups/backups_state.dart
@@ -71,7 +71,8 @@ class BackupsUnititialized extends BackupsState {
     final BackblazeBucket? backblazeBucket,
   }) =>
       BackupsUnititialized(
-          backblazeBucket: backblazeBucket ?? this.backblazeBucket);
+        backblazeBucket: backblazeBucket ?? this.backblazeBucket,
+      );
 }
 
 class BackupsInitializing extends BackupsState {
@@ -86,7 +87,8 @@ class BackupsInitializing extends BackupsState {
     final BackblazeBucket? backblazeBucket,
   }) =>
       BackupsInitializing(
-          backblazeBucket: backblazeBucket ?? this.backblazeBucket);
+        backblazeBucket: backblazeBucket ?? this.backblazeBucket,
+      );
 }
 
 class BackupsInitialized extends BackupsState {
diff --git a/lib/logic/bloc/services/services_bloc.dart b/lib/logic/bloc/services/services_bloc.dart
new file mode 100644
index 00000000..1d5293fd
--- /dev/null
+++ b/lib/logic/bloc/services/services_bloc.dart
@@ -0,0 +1,144 @@
+import 'dart:async';
+
+import 'package:easy_localization/easy_localization.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:selfprivacy/config/get_it_config.dart';
+
+import 'package:selfprivacy/logic/models/service.dart';
+
+part 'services_event.dart';
+part 'services_state.dart';
+
+class ServicesBloc extends Bloc<ServicesEvent, ServicesState> {
+  ServicesBloc() : super(ServicesInitial()) {
+    final connectionRepository = getIt<ApiConnectionRepository>();
+
+    _apiDataSubscription = connectionRepository.dataStream.listen(
+      (final ApiData apiData) {
+        add(
+          ServicesListUpdate([...apiData.services.data ?? []]),
+        );
+      },
+    );
+
+    if (connectionRepository.connectionStatus == ConnectionStatus.connected) {
+      add(
+        ServicesListUpdate(
+          [...connectionRepository.apiData.services.data ?? []],
+        ),
+      );
+    }
+
+    on<ServicesListUpdate>(
+      _updateList,
+    );
+    on<ServicesReload>(
+      _reload,
+    );
+    on<ServiceRestart>(
+      _restart,
+    );
+    on<ServiceMove>(
+      _move,
+    );
+  }
+
+  Future<void> _updateList(
+    final ServicesListUpdate event,
+    final Emitter<ServicesState> emit,
+  ) async {
+    if (event.services.isEmpty) {
+      emit(ServicesInitial());
+      return;
+    }
+    final newState = ServicesLoaded(
+      services: event.services,
+      lockedServices: state._lockedServices,
+    );
+    emit(newState);
+  }
+
+  Future<void> _reload(
+    final ServicesReload event,
+    final Emitter<ServicesState> emit,
+  ) async {
+    final currentState = state;
+    if (currentState is ServicesLoaded) {
+      emit(ServicesReloading.fromState(currentState));
+      getIt<ApiConnectionRepository>().apiData.services.invalidate();
+      await getIt<ApiConnectionRepository>().reload(null);
+    }
+  }
+
+  Future<void> awaitReload() async {
+    final currentState = state;
+    if (currentState is ServicesLoaded) {
+      getIt<ApiConnectionRepository>().apiData.services.invalidate();
+      await getIt<ApiConnectionRepository>().reload(null);
+    }
+  }
+
+  Future<void> _restart(
+    final ServiceRestart event,
+    final Emitter<ServicesState> emit,
+  ) async {
+    emit(
+      state.copyWith(
+        lockedServices: [
+          ...state._lockedServices,
+          ServiceLock(
+            serviceId: event.service.id,
+            lockDuration: const Duration(seconds: 15),
+          ),
+        ],
+      ),
+    );
+    final result = await getIt<ApiConnectionRepository>()
+        .api
+        .restartService(event.service.id);
+    if (!result.success) {
+      getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
+      return;
+    }
+    if (!result.data) {
+      getIt<NavigationService>()
+          .showSnackBar(result.message ?? 'jobs.generic_error'.tr());
+      return;
+    }
+  }
+
+  Future<void> _move(
+    final ServiceMove event,
+    final Emitter<ServicesState> emit,
+  ) async {
+    final migrationJob = await getIt<ApiConnectionRepository>()
+        .api
+        .moveService(event.service.id, event.destination);
+    if (!migrationJob.success) {
+      getIt<NavigationService>()
+          .showSnackBar(migrationJob.message ?? 'jobs.generic_error'.tr());
+    }
+    if (migrationJob.data != null) {
+      getIt<ApiConnectionRepository>()
+          .apiData
+          .serverJobs
+          .data
+          ?.add(migrationJob.data!);
+      getIt<ApiConnectionRepository>().emitData();
+    }
+  }
+
+  late StreamSubscription _apiDataSubscription;
+
+  @override
+  void onChange(final Change<ServicesState> change) {
+    super.onChange(change);
+  }
+
+  @override
+  Future<void> close() {
+    _apiDataSubscription.cancel();
+    return super.close();
+  }
+}
diff --git a/lib/logic/bloc/services/services_event.dart b/lib/logic/bloc/services/services_event.dart
new file mode 100644
index 00000000..c8239152
--- /dev/null
+++ b/lib/logic/bloc/services/services_event.dart
@@ -0,0 +1,40 @@
+part of 'services_bloc.dart';
+
+abstract class ServicesEvent extends Equatable {
+  const ServicesEvent();
+}
+
+class ServicesListUpdate extends ServicesEvent {
+  const ServicesListUpdate(this.services);
+
+  final List<Service> services;
+
+  @override
+  List<Object?> get props => [services];
+}
+
+class ServicesReload extends ServicesEvent {
+  const ServicesReload();
+
+  @override
+  List<Object?> get props => [];
+}
+
+class ServiceRestart extends ServicesEvent {
+  const ServiceRestart(this.service);
+
+  final Service service;
+
+  @override
+  List<Object?> get props => [service];
+}
+
+class ServiceMove extends ServicesEvent {
+  const ServiceMove(this.service, this.destination);
+
+  final Service service;
+  final String destination;
+
+  @override
+  List<Object?> get props => [service, destination];
+}
diff --git a/lib/logic/bloc/services/services_state.dart b/lib/logic/bloc/services/services_state.dart
new file mode 100644
index 00000000..05d6bc89
--- /dev/null
+++ b/lib/logic/bloc/services/services_state.dart
@@ -0,0 +1,115 @@
+part of 'services_bloc.dart';
+
+abstract class ServicesState extends Equatable {
+  ServicesState({final List<ServiceLock> lockedServices = const []})
+      : _lockedServices =
+            lockedServices.where((final lock) => lock.isLocked).toList();
+  final List<ServiceLock> _lockedServices;
+  List<Service> get services;
+  List<String> get lockedServices => _lockedServices
+      .where((final lock) => lock.isLocked)
+      .map((final lock) => lock.serviceId)
+      .toList();
+
+  List<Service> get servicesThatCanBeBackedUp => services
+      .where(
+        (final service) => service.canBeBackedUp,
+      )
+      .toList();
+
+  bool isServiceLocked(final String serviceId) =>
+      lockedServices.contains(serviceId);
+
+  Service? getServiceById(final String id) {
+    final service = services.firstWhere(
+      (final service) => service.id == id,
+      orElse: () => Service.empty,
+    );
+    if (service.id == 'empty') {
+      return null;
+    }
+    return service;
+  }
+
+  ServicesState copyWith({
+    final List<Service>? services,
+    final List<ServiceLock>? lockedServices,
+  });
+}
+
+class ServiceLock extends Equatable {
+  ServiceLock({
+    required this.serviceId,
+    required this.lockDuration,
+  }) : lockTime = DateTime.now();
+
+  final String serviceId;
+  final Duration lockDuration;
+  final DateTime lockTime;
+
+  bool get isLocked => DateTime.now().isBefore(lockTime.add(lockDuration));
+
+  @override
+  List<Object?> get props => [serviceId, lockDuration, lockTime];
+}
+
+class ServicesInitial extends ServicesState {
+  @override
+  List<Object> get props => [];
+
+  @override
+  List<Service> get services => [];
+
+  @override
+  ServicesState copyWith({
+    final List<Service>? services,
+    final List<ServiceLock>? lockedServices,
+  }) =>
+      ServicesInitial();
+}
+
+class ServicesLoaded extends ServicesState {
+  ServicesLoaded({
+    required final List<Service> services,
+    required super.lockedServices,
+  }) : _servicesHachCode = Object.hashAll([...services]);
+
+  final int _servicesHachCode;
+
+  final apiConnectionRepository = getIt<ApiConnectionRepository>();
+
+  List<Service> get _services =>
+      apiConnectionRepository.apiData.services.data ?? [];
+
+  @override
+  List<Service> get services => _services;
+
+  @override
+  List<Object?> get props => [_servicesHachCode, _lockedServices];
+
+  @override
+  ServicesLoaded copyWith({
+    final List<Service>? services,
+    final List<ServiceLock>? lockedServices,
+  }) =>
+      ServicesLoaded(
+        services: services ?? this.services,
+        lockedServices: lockedServices ?? _lockedServices,
+      );
+}
+
+class ServicesReloading extends ServicesLoaded {
+  ServicesReloading({
+    required super.services,
+    required super.lockedServices,
+  });
+
+  ServicesReloading.fromState(final ServicesLoaded state)
+      : super(
+          services: state.services,
+          lockedServices: state._lockedServices,
+        );
+
+  @override
+  List<Object?> get props => [services, lockedServices];
+}
diff --git a/lib/logic/cubit/client_jobs/client_jobs_cubit.dart b/lib/logic/cubit/client_jobs/client_jobs_cubit.dart
index 59a33673..f9188985 100644
--- a/lib/logic/cubit/client_jobs/client_jobs_cubit.dart
+++ b/lib/logic/cubit/client_jobs/client_jobs_cubit.dart
@@ -5,7 +5,7 @@ import 'package:equatable/equatable.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:selfprivacy/config/get_it_config.dart';
 import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
 import 'package:selfprivacy/logic/models/job.dart';
 
@@ -16,12 +16,12 @@ part 'client_jobs_state.dart';
 class JobsCubit extends Cubit<JobsState> {
   JobsCubit({
     required this.usersCubit,
-    required this.servicesCubit,
+    required this.servicesBloc,
   }) : super(JobsStateEmpty());
 
   final ServerApi api = ServerApi();
   final UsersCubit usersCubit;
-  final ServicesCubit servicesCubit;
+  final ServicesBloc servicesBloc;
 
   void addJob(final ClientJob job) {
     final jobs = currentJobList;
@@ -90,7 +90,7 @@ class JobsCubit extends Cubit<JobsState> {
 
       await api.pullConfigurationUpdate();
       await api.apply();
-      await servicesCubit.load();
+      servicesBloc.add(const ServicesReload());
 
       emit(JobsStateEmpty());
     }
diff --git a/lib/logic/cubit/services/services_cubit.dart b/lib/logic/cubit/services/services_cubit.dart
deleted file mode 100644
index a9849700..00000000
--- a/lib/logic/cubit/services/services_cubit.dart
+++ /dev/null
@@ -1,81 +0,0 @@
-import 'dart:async';
-
-import 'package:easy_localization/easy_localization.dart';
-import 'package:selfprivacy/config/get_it_config.dart';
-import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
-import 'package:selfprivacy/logic/cubit/server_connection_dependent/server_connection_dependent_cubit.dart';
-import 'package:selfprivacy/logic/models/service.dart';
-
-part 'services_state.dart';
-
-class ServicesCubit extends ServerConnectionDependentCubit<ServicesState> {
-  ServicesCubit(final ServerInstallationCubit serverInstallationCubit)
-      : super(const ServicesState.empty());
-  final ServerApi api = ServerApi();
-  Timer? timer;
-  @override
-  Future<void> load() async {
-    final List<Service> services = await api.getAllServices();
-    emit(
-      ServicesState(
-        services: services,
-        lockedServices: const [],
-      ),
-    );
-    timer = Timer(const Duration(seconds: 10), () => reload(useTimer: true));
-  }
-
-  Future<void> reload({final bool useTimer = false}) async {
-    final List<Service> services = await api.getAllServices();
-    emit(
-      state.copyWith(
-        services: services,
-      ),
-    );
-    if (useTimer) {
-      timer = Timer(const Duration(seconds: 60), () => reload(useTimer: true));
-    }
-  }
-
-  Future<void> restart(final String serviceId) async {
-    emit(state.copyWith(lockedServices: [...state.lockedServices, serviceId]));
-    final result = await api.restartService(serviceId);
-    if (!result.success) {
-      getIt<NavigationService>().showSnackBar('jobs.generic_error'.tr());
-      return;
-    }
-    if (!result.data) {
-      getIt<NavigationService>()
-          .showSnackBar(result.message ?? 'jobs.generic_error'.tr());
-      return;
-    }
-
-    await Future.delayed(const Duration(seconds: 2));
-    unawaited(reload());
-    await Future.delayed(const Duration(seconds: 10));
-    emit(
-      state.copyWith(
-        lockedServices: state.lockedServices
-            .where((final element) => element != serviceId)
-            .toList(),
-      ),
-    );
-    unawaited(reload());
-  }
-
-  Future<void> moveService(
-    final String serviceId,
-    final String destination,
-  ) async {
-    await api.moveService(serviceId, destination);
-  }
-
-  @override
-  void clear() async {
-    emit(const ServicesState.empty());
-    if (timer != null && timer!.isActive) {
-      timer!.cancel();
-      timer = null;
-    }
-  }
-}
diff --git a/lib/logic/cubit/services/services_state.dart b/lib/logic/cubit/services/services_state.dart
deleted file mode 100644
index 7a136b54..00000000
--- a/lib/logic/cubit/services/services_state.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-part of 'services_cubit.dart';
-
-class ServicesState extends ServerInstallationDependendState {
-  const ServicesState({
-    required this.services,
-    required this.lockedServices,
-  });
-
-  const ServicesState.empty()
-      : this(services: const [], lockedServices: const []);
-
-  final List<Service> services;
-  final List<String> lockedServices;
-
-  List<Service> get servicesThatCanBeBackedUp => services
-      .where(
-        (final service) => service.canBeBackedUp,
-      )
-      .toList();
-
-  bool isServiceLocked(final String serviceId) =>
-      lockedServices.contains(serviceId);
-
-  Service? getServiceById(final String id) {
-    final service = services.firstWhere(
-      (final service) => service.id == id,
-      orElse: () => Service.empty,
-    );
-    if (service.id == 'empty') {
-      return null;
-    }
-    return service;
-  }
-
-  @override
-  List<Object> get props => [
-        services,
-        lockedServices,
-      ];
-
-  ServicesState copyWith({
-    final List<Service>? services,
-    final List<String>? lockedServices,
-  }) =>
-      ServicesState(
-        services: services ?? this.services,
-        lockedServices: lockedServices ?? this.lockedServices,
-      );
-}
diff --git a/lib/logic/get_it/api_connection_repository.dart b/lib/logic/get_it/api_connection_repository.dart
index 72e9fb65..8503acbc 100644
--- a/lib/logic/get_it/api_connection_repository.dart
+++ b/lib/logic/get_it/api_connection_repository.dart
@@ -9,6 +9,7 @@ import 'package:selfprivacy/logic/models/backup.dart';
 import 'package:selfprivacy/logic/models/hive/server_details.dart';
 import 'package:selfprivacy/logic/models/hive/server_domain.dart';
 import 'package:selfprivacy/logic/models/json/server_job.dart';
+import 'package:selfprivacy/logic/models/service.dart';
 
 /// Repository for all API calls
 /// Stores the current state of all data from API and exposes it to Blocs.
@@ -74,6 +75,7 @@ class ApiConnectionRepository {
     _apiData.serverJobs.data = await api.getServerJobs();
     _apiData.backupConfig.data = await api.getBackupsConfiguration();
     _apiData.backups.data = await api.getBackups();
+    _apiData.services.data = await api.getAllServices();
     _dataStream.add(_apiData);
 
     connectionStatus = ConnectionStatus.connected;
@@ -109,6 +111,8 @@ class ApiConnectionRepository {
         .refetchData(version, () => _dataStream.add(_apiData));
     await _apiData.backupConfig
         .refetchData(version, () => _dataStream.add(_apiData));
+    await _apiData.services
+        .refetchData(version, () => _dataStream.add(_apiData));
   }
 
   void emitData() {
@@ -132,12 +136,17 @@ class ApiData {
         backups = ApiDataElement<List<Backup>>(
           fetchData: () async => api.getBackups(),
           requiredApiVersion: '>=2.4.2',
+        ),
+        services = ApiDataElement<List<Service>>(
+          fetchData: () async => api.getAllServices(),
+          requiredApiVersion: '>=2.4.3',
         );
 
   ApiDataElement<List<ServerJob>> serverJobs;
   ApiDataElement<String> apiVersion;
   ApiDataElement<BackupConfiguration> backupConfig;
   ApiDataElement<List<Backup>> backups;
+  ApiDataElement<List<Service>> services;
 }
 
 enum ConnectionStatus {
@@ -163,7 +172,9 @@ class ApiDataElement<T> {
   final Future<T?> Function() fetchData;
 
   Future<void> refetchData(
-      final Version version, final Function callback) async {
+    final Version version,
+    final Function callback,
+  ) async {
     if (VersionConstraint.parse(requiredApiVersion).allows(version)) {
       print('Fetching data for $runtimeType');
       if (isExpired) {
diff --git a/lib/logic/models/service.dart b/lib/logic/models/service.dart
index 702b94db..5f2364e9 100644
--- a/lib/logic/models/service.dart
+++ b/lib/logic/models/service.dart
@@ -1,6 +1,7 @@
 import 'dart:convert';
 
 import 'package:easy_localization/easy_localization.dart';
+import 'package:equatable/equatable.dart';
 import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/schema.graphql.dart';
 import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/services.graphql.dart';
 import 'package:selfprivacy/logic/models/disk_size.dart';
@@ -8,7 +9,7 @@ import 'package:selfprivacy/logic/models/json/dns_records.dart';
 
 import 'package:selfprivacy/logic/api_maps/graphql_maps/schema/server_settings.graphql.dart';
 
-class Service {
+class Service extends Equatable {
   Service.fromGraphQL(final Query$AllServices$services$allServices service)
       : this(
           id: service.id,
@@ -37,7 +38,7 @@ class Service {
               [],
           url: service.url,
         );
-  Service({
+  const Service({
     required this.id,
     required this.displayName,
     required this.description,
@@ -72,7 +73,7 @@ class Service {
     return '';
   }
 
-  static Service empty = Service(
+  static Service empty = const Service(
     id: 'empty',
     displayName: '',
     description: '',
@@ -83,7 +84,7 @@ class Service {
     backupDescription: '',
     status: ServiceStatus.off,
     storageUsage: ServiceStorageUsage(
-      used: const DiskSize(byte: 0),
+      used: DiskSize(byte: 0),
       volume: '',
     ),
     svgIcon: '',
@@ -104,16 +105,36 @@ class Service {
   final String svgIcon;
   final String? url;
   final List<DnsRecord> dnsRecords;
+
+  @override
+  List<Object?> get props => [
+        id,
+        displayName,
+        description,
+        isEnabled,
+        isRequired,
+        isMovable,
+        canBeBackedUp,
+        backupDescription,
+        status,
+        storageUsage,
+        svgIcon,
+        dnsRecords,
+        url,
+      ];
 }
 
-class ServiceStorageUsage {
-  ServiceStorageUsage({
+class ServiceStorageUsage extends Equatable {
+  const ServiceStorageUsage({
     required this.used,
     required this.volume,
   });
 
   final DiskSize used;
   final String? volume;
+
+  @override
+  List<Object?> get props => [used, volume];
 }
 
 enum ServiceStatus {
diff --git a/lib/ui/pages/backups/backup_details.dart b/lib/ui/pages/backups/backup_details.dart
index a99d6385..d5dbe4e4 100644
--- a/lib/ui/pages/backups/backup_details.dart
+++ b/lib/ui/pages/backups/backup_details.dart
@@ -5,7 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart';
 import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
 import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
 import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/backup.dart';
 import 'package:selfprivacy/logic/models/json/server_job.dart';
 import 'package:selfprivacy/logic/models/service.dart';
@@ -39,7 +39,7 @@ class BackupDetailsPage extends StatelessWidget {
     final bool preventActions = backupsState.preventActions;
     final List<Backup> backups = backupsState.backups;
     final List<Service> services =
-        context.watch<ServicesCubit>().state.servicesThatCanBeBackedUp;
+        context.watch<ServicesBloc>().state.servicesThatCanBeBackedUp;
     final Duration? autobackupPeriod = backupsState.autobackupPeriod;
     final List<ServerJob> backupJobs = context
         .watch<ServerJobsBloc>()
@@ -298,7 +298,7 @@ class BackupDetailsPage extends StatelessWidget {
                   children: backups.take(15).map(
                     (final Backup backup) {
                       final service = context
-                          .read<ServicesCubit>()
+                          .read<ServicesBloc>()
                           .state
                           .getServiceById(backup.serviceId);
                       return ListTile(
@@ -419,7 +419,7 @@ class BackupDetailsPage extends StatelessWidget {
                     : () => {
                           context
                               .read<BackupsBloc>()
-                              .add(const ForceSnapshotListUpdate())
+                              .add(const ForceSnapshotListUpdate()),
                         },
               ),
               const SizedBox(height: 8),
diff --git a/lib/ui/pages/backups/backups_list.dart b/lib/ui/pages/backups/backups_list.dart
index 79eb7a95..fd2b541e 100644
--- a/lib/ui/pages/backups/backups_list.dart
+++ b/lib/ui/pages/backups/backups_list.dart
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/backup.dart';
 import 'package:selfprivacy/logic/models/service.dart';
 import 'package:selfprivacy/ui/helpers/modals.dart';
@@ -43,7 +43,7 @@ class BackupsListPage extends StatelessWidget {
           ...backups.map(
             (final Backup backup) {
               final service = context
-                  .read<ServicesCubit>()
+                  .read<ServicesBloc>()
                   .state
                   .getServiceById(backup.serviceId);
               return ListTile(
diff --git a/lib/ui/pages/backups/snapshot_modal.dart b/lib/ui/pages/backups/snapshot_modal.dart
index 3236ddc1..54dbaae4 100644
--- a/lib/ui/pages/backups/snapshot_modal.dart
+++ b/lib/ui/pages/backups/snapshot_modal.dart
@@ -4,7 +4,7 @@ import 'package:flutter_svg/flutter_svg.dart';
 import 'package:selfprivacy/config/get_it_config.dart';
 import 'package:selfprivacy/logic/bloc/backups/backups_bloc.dart';
 import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/backup.dart';
 import 'package:selfprivacy/logic/models/json/server_job.dart';
 import 'package:selfprivacy/logic/models/service.dart';
@@ -48,7 +48,7 @@ class _SnapshotModalState extends State<SnapshotModal> {
     final bool isServiceBusy = busyServices.contains(widget.snapshot.serviceId);
 
     final Service? service = context
-        .read<ServicesCubit>()
+        .read<ServicesBloc>()
         .state
         .getServiceById(widget.snapshot.serviceId);
 
@@ -153,8 +153,12 @@ class _SnapshotModalState extends State<SnapshotModal> {
                   onPressed: isServiceBusy
                       ? null
                       : () {
-                          context.read<BackupsBloc>().add(RestoreBackup(
-                              widget.snapshot.id, selectedStrategy));
+                          context.read<BackupsBloc>().add(
+                                RestoreBackup(
+                                  widget.snapshot.id,
+                                  selectedStrategy,
+                                ),
+                              );
                           Navigator.of(context).pop();
                           getIt<NavigationService>()
                               .showSnackBar('backup.restore_started'.tr());
diff --git a/lib/ui/pages/server_storage/binds_migration/services_migration.dart b/lib/ui/pages/server_storage/binds_migration/services_migration.dart
index 453e7067..171fb53d 100644
--- a/lib/ui/pages/server_storage/binds_migration/services_migration.dart
+++ b/lib/ui/pages/server_storage/binds_migration/services_migration.dart
@@ -2,7 +2,7 @@ import 'package:auto_route/auto_route.dart';
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:selfprivacy/logic/bloc/server_jobs/server_jobs_bloc.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/disk_size.dart';
 import 'package:selfprivacy/logic/models/service.dart';
 import 'package:selfprivacy/ui/components/buttons/brand_button.dart';
@@ -175,9 +175,11 @@ class _ServicesMigrationPageState extends State<ServicesMigrationPage> {
                 onPressed: () {
                   for (final service in widget.services) {
                     if (serviceToDisk[service.id] != null) {
-                      context.read<ServicesCubit>().moveService(
-                            service.id,
-                            serviceToDisk[service.id]!,
+                      context.read<ServicesBloc>().add(
+                            ServiceMove(
+                              service,
+                              serviceToDisk[service.id]!,
+                            ),
                           );
                     }
                   }
diff --git a/lib/ui/pages/server_storage/server_storage.dart b/lib/ui/pages/server_storage/server_storage.dart
index eb7a586b..fb1602b9 100644
--- a/lib/ui/pages/server_storage/server_storage.dart
+++ b/lib/ui/pages/server_storage/server_storage.dart
@@ -3,7 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/service.dart';
 import 'package:selfprivacy/ui/components/buttons/outlined_button.dart';
 import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
@@ -30,8 +30,7 @@ class _ServerStoragePageState extends State<ServerStoragePage> {
     final bool isReady = context.watch<ServerInstallationCubit>().state
         is ServerInstallationFinished;
 
-    final List<Service> services =
-        context.watch<ServicesCubit>().state.services;
+    final List<Service> services = context.watch<ServicesBloc>().state.services;
 
     if (!isReady) {
       return BrandHeroScreen(
diff --git a/lib/ui/pages/services/service_page.dart b/lib/ui/pages/services/service_page.dart
index 96560db0..4291c6e2 100644
--- a/lib/ui/pages/services/service_page.dart
+++ b/lib/ui/pages/services/service_page.dart
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
 import 'package:selfprivacy/logic/cubit/server_volumes/server_volume_cubit.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/job.dart';
 import 'package:selfprivacy/logic/models/service.dart';
 import 'package:selfprivacy/ui/components/cards/filled_card.dart';
@@ -26,7 +26,7 @@ class _ServicePageState extends State<ServicePage> {
   @override
   Widget build(final BuildContext context) {
     final Service? service =
-        context.watch<ServicesCubit>().state.getServiceById(widget.serviceId);
+        context.watch<ServicesBloc>().state.getServiceById(widget.serviceId);
 
     if (service == null) {
       return const BrandHeroScreen(
@@ -43,7 +43,7 @@ class _ServicePageState extends State<ServicePage> {
         service.status == ServiceStatus.off;
 
     final bool serviceLocked =
-        context.watch<ServicesCubit>().state.isServiceLocked(service.id);
+        context.watch<ServicesBloc>().state.isServiceLocked(service.id);
 
     return BrandHeroScreen(
       hasBackButton: true,
@@ -81,7 +81,7 @@ class _ServicePageState extends State<ServicePage> {
         ListTile(
           iconColor: Theme.of(context).colorScheme.onBackground,
           onTap: () => {
-            context.read<ServicesCubit>().restart(service.id),
+            context.read<ServicesBloc>().add(ServiceRestart(service)),
           },
           leading: const Icon(Icons.restart_alt_outlined),
           title: Text(
diff --git a/lib/ui/pages/services/services.dart b/lib/ui/pages/services/services.dart
index 2aa31d8b..3bc0de48 100644
--- a/lib/ui/pages/services/services.dart
+++ b/lib/ui/pages/services/services.dart
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:selfprivacy/config/brand_theme.dart';
 import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
+import 'package:selfprivacy/logic/bloc/services/services_bloc.dart';
 import 'package:selfprivacy/logic/models/service.dart';
 import 'package:selfprivacy/logic/models/state_types.dart';
 import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
@@ -30,7 +30,7 @@ class _ServicesPageState extends State<ServicesPage> {
     final isReady = context.watch<ServerInstallationCubit>().state
         is ServerInstallationFinished;
 
-    final services = [...context.watch<ServicesCubit>().state.services];
+    final services = [...context.watch<ServicesBloc>().state.services];
     services
         .sort((final a, final b) => a.status.index.compareTo(b.status.index));
 
@@ -52,7 +52,8 @@ class _ServicesPageState extends State<ServicesPage> {
             )
           : RefreshIndicator(
               onRefresh: () async {
-                await context.read<ServicesCubit>().reload();
+                // Create a ServicesRelaod event and wait for the state to change.
+                await context.read<ServicesBloc>().awaitReload();
               },
               child: ListView(
                 padding: paddingH15V0,