diff --git a/react-ui/docs/routine_pattern.md b/react-ui/docs/routine_pattern.md
new file mode 100644
index 0000000000000000000000000000000000000000..97a29da31e704a64150a1723b51edc78b7e1ece2
--- /dev/null
+++ b/react-ui/docs/routine_pattern.md
@@ -0,0 +1,18 @@
+## Routine pattern
+The goal is to get a generic architecture to invoke persist and rerun asynchronous actions (thunks).
+
+
+### Goals
+* Invoke asyncronous actions
+* Rerun actions after page reload by persisting
+* Ability to access and manipulate the redux state
+* Give a simple interface to the outside world by abstracting the task to achive the upper goals
+
+
+### Usage
+Add 
+
+
+### Description
+The image displays the whole workflow starting by the user that clicks a button. The actual routine pattern takes place within the red border. 
+![image](./routine_pattern.png)
diff --git a/react-ui/docs/routine_pattern.png b/react-ui/docs/routine_pattern.png
new file mode 100644
index 0000000000000000000000000000000000000000..86b582398523ed51922d8ebad316c15be59265db
Binary files /dev/null and b/react-ui/docs/routine_pattern.png differ
diff --git a/react-ui/src/components/subscriptions/action.subscription.ts b/react-ui/src/components/routines/action.routine.ts
similarity index 100%
rename from react-ui/src/components/subscriptions/action.subscription.ts
rename to react-ui/src/components/routines/action.routine.ts
diff --git a/react-ui/src/components/subscriptions/device.subscription.ts b/react-ui/src/components/routines/device.routine.ts
similarity index 86%
rename from react-ui/src/components/subscriptions/device.subscription.ts
rename to react-ui/src/components/routines/device.routine.ts
index 5afcc7c68d5c7be6aeb2549a5ef2e5dae0d113cd..0290f637d3cdfa20f9a2735ab93130377c670ee0 100644
--- a/react-ui/src/components/subscriptions/device.subscription.ts
+++ b/react-ui/src/components/routines/device.routine.ts
@@ -1,10 +1,10 @@
 import { NetworkElementServiceGetAllFlattenedApiArg, api } from "@api/api";
-import { setDevices } from "@reducer/device.reducer";
+import { setDevices } from "@reducer/device.reducer/device.reducer";
 import { setUser } from "@reducer/user.reducer";
 import { createAsyncThunk } from "@reduxjs/toolkit";
 import { RootState } from "src/stores";
-import { startListening } from "../../../src/stores/middleware/listener.middleware";
-import { FETCH_DEVICE_ACTION } from "./action.subscription";
+import { startListening } from "../../stores/middleware/listener.middleware";
+import { FETCH_DEVICE_ACTION } from "./action.routine";
 
 // continously fetch devices
 const FETCH_DEVICES_INTERVAL = 15000; // in ms
diff --git a/react-ui/src/components/subscriptions/index.ts b/react-ui/src/components/subscriptions/index.ts
deleted file mode 100644
index 2a3e02f20022a66fa6d4c68dd814bd03e0c973aa..0000000000000000000000000000000000000000
--- a/react-ui/src/components/subscriptions/index.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { AsyncThunk } from '@reduxjs/toolkit';
-import { fetchDevicesThunk } from './device.subscription';
-import { fetchSelectedMneThunk } from './mne.subscription';
-
-
-export enum THUNK_TYPE {
-    MNE =  'device/fetch',
-    DEVICE =  'mne/fetch',
-}
-
-export interface SubscriptionThunkModule {
-    thunkFn?: AsyncThunk<any, any, {}>
-    type: THUNK_TYPE,
-}
-
-export const SubscriptionThunks: SubscriptionThunkModule[] = [
-    {
-        thunkFn: fetchDevicesThunk,
-        type: THUNK_TYPE.DEVICE
-    }, {
-
-        thunkFn: fetchSelectedMneThunk,
-        type: THUNK_TYPE.MNE
-    }
-]
-
diff --git a/react-ui/src/components/view/device/device.view.tsx b/react-ui/src/components/view/device/device.view.tsx
index 0ef5c05b96ded16966d81393ab681e215b1fd5c5..c85ce6be6d52e1049ca663e3e0b0f597bd025a8d 100644
--- a/react-ui/src/components/view/device/device.view.tsx
+++ b/react-ui/src/components/view/device/device.view.tsx
@@ -1,10 +1,10 @@
 import { useDeviceViewModel } from '@viewmodel/device.viewmodel';
 import { useRef } from 'react';
-import { Button, Col, Container, FloatingLabel, Form, Nav, NavLink, Row } from 'react-bootstrap';
+import { Button, Col, Container, Form, Nav, NavLink, Row } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
-import { DeviceViewTabs, DeviceViewTabValues } from './device.view.tabs';
 import './device.scss';
 import { DeviceViewTable } from './device.view.table';
+import { DeviceViewTabs, DeviceViewTabValues } from './device.view.tabs';
 
 function DeviceView() {
     const { t } = useTranslation('common');
@@ -27,9 +27,9 @@ function DeviceView() {
 
                 <Row className='align-items-center'>
                     <Col sm={3}>
-                    <Form.Group controlId='device.search' className='p-0 mx-1 pt-2'>
-                        <Form.Control type="text" placeholder={t('device.search.placeholder')} ref={searchRef} />
-                    </Form.Group>
+                        <Form.Group controlId='device.search' className='p-0 mx-1 pt-2'>
+                            <Form.Control type="text" placeholder={t('device.search.placeholder')} ref={searchRef} />
+                        </Form.Group>
                     </Col>
                     <Col sm={{ span: 2, offset: 2 }} className='border-right pt-2'>
                         <Button variant='primary' className='w-100 my-auto'>{t('device.add_device_button')}</Button>
diff --git a/react-ui/src/components/view_model/device.table.viewmodel.ts b/react-ui/src/components/view_model/device.table.viewmodel.ts
index 22d8ae9e0857891d20a6b5504c6c7df7165c44b2..0802d6b575c4240f6f0cb18be612e294d53e01cf 100644
--- a/react-ui/src/components/view_model/device.table.viewmodel.ts
+++ b/react-ui/src/components/view_model/device.table.viewmodel.ts
@@ -1,5 +1,5 @@
 import { useAppDispatch } from "@hooks";
-import { Device, setSelectedDevice } from "@reducer/device.reducer";
+import { Device, setSelectedDevice } from "@reducer/device.reducer/device.reducer";
 import { useEffect, useState } from "react";
 
 export const useDeviceTableViewModel = (searchRef) => {
diff --git a/react-ui/src/components/view_model/device.viewmodel.ts b/react-ui/src/components/view_model/device.viewmodel.ts
index ec75927f033dd5d19b4779fd6d6fe6d000e6cd39..6dd01d07ede92c977e80702d2700a7b688e1107f 100644
--- a/react-ui/src/components/view_model/device.viewmodel.ts
+++ b/react-ui/src/components/view_model/device.viewmodel.ts
@@ -1,5 +1,5 @@
 import { useAppDispatch, useAppSelector } from "@hooks";
-import { setActiveTab as setActiveTabState } from "@reducer/device.reducer";
+import { setActiveTab as setActiveTabState } from "@reducer/device.reducer/device.reducer";
 import { DeviceViewTabValues } from "@view/device/device.view.tabs";
 
 export const useDeviceViewModel = () => {
diff --git a/react-ui/src/index.tsx b/react-ui/src/index.tsx
index a2ddc81a9091427a9d3eaf25a711836dc6819de3..dddcf5c07296c768486fcd7cde1c612f7c127ac6 100644
--- a/react-ui/src/index.tsx
+++ b/react-ui/src/index.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import ReactDOM, { Container } from 'react-dom/client'
+import ReactDOM from 'react-dom/client'
 import {
     RouterProvider
 } from 'react-router-dom'
@@ -12,8 +12,8 @@ import { ToastContainer } from 'react-toastify'
 import { PersistGate } from 'redux-persist/integration/react'
 import './i18n/config'
 import { router } from './routes'
+import './shared/icons/icons'
 import { persistor, store } from './stores'
-import './utils/icons/icons'
 
 const installToastify = () => {
     return (
@@ -34,4 +34,3 @@ ReactDOM.createRoot(document.getElementById("root")).render(
     </React.StrictMode>
 );
 
-import './components/subscriptions'
\ No newline at end of file
diff --git a/react-ui/src/routes.tsx b/react-ui/src/routes.tsx
index b273246d9ca6d5067e2b38185036443a05a65676..a63d6d87552a05da1c1cebd6d4736f19ae1c96c9 100644
--- a/react-ui/src/routes.tsx
+++ b/react-ui/src/routes.tsx
@@ -1,8 +1,8 @@
-import { BasicLayout } from "@layout/basic.layout"
-import { LoginLayout } from "@layout/login.layout"
-import { ProtectedLayout } from "@layout/protected.layout/protected.layout"
-import DeviceView from "@view/device/device.view"
-import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router-dom"
+import { BasicLayout } from "@layout/basic.layout";
+import { LoginLayout } from "@layout/login.layout";
+import { ProtectedLayout } from "@layout/protected.layout/protected.layout";
+import DeviceView from "@view/device/device.view";
+import { createBrowserRouter, createRoutesFromElements, Navigate, Route } from "react-router-dom";
 
 export const DEVICE_URL = '/device/';
 export const LOGIN_URL = '/login';
diff --git a/react-ui/src/utils/api/api.ts b/react-ui/src/shared/api/api.ts
similarity index 100%
rename from react-ui/src/utils/api/api.ts
rename to react-ui/src/shared/api/api.ts
diff --git a/react-ui/src/utils/helper/coookie.ts b/react-ui/src/shared/helper/coookie.ts
similarity index 100%
rename from react-ui/src/utils/helper/coookie.ts
rename to react-ui/src/shared/helper/coookie.ts
diff --git a/react-ui/src/utils/icons/icons.ts b/react-ui/src/shared/icons/icons.ts
similarity index 100%
rename from react-ui/src/utils/icons/icons.ts
rename to react-ui/src/shared/icons/icons.ts
diff --git a/react-ui/src/utils/layouts/basic.layout.tsx b/react-ui/src/shared/layouts/basic.layout.tsx
similarity index 88%
rename from react-ui/src/utils/layouts/basic.layout.tsx
rename to react-ui/src/shared/layouts/basic.layout.tsx
index 7b7f2b11c1780101c70f71317a3e5ed8204cf5b1..640af3e1ba3948e61cf80977f865b4db9cd9a8ea 100644
--- a/react-ui/src/utils/layouts/basic.layout.tsx
+++ b/react-ui/src/shared/layouts/basic.layout.tsx
@@ -4,11 +4,11 @@ import { useOutlet } from "react-router-dom";
 export const BasicLayout = () => {
     const outlet = useOutlet();
 
-    
+
 
     return (
         <AuthProvider>
-                {outlet}
+            {outlet}
         </AuthProvider>
     )
 }
\ No newline at end of file
diff --git a/react-ui/src/utils/layouts/login.layout.tsx b/react-ui/src/shared/layouts/login.layout.tsx
similarity index 100%
rename from react-ui/src/utils/layouts/login.layout.tsx
rename to react-ui/src/shared/layouts/login.layout.tsx
diff --git a/react-ui/src/utils/layouts/protected.layout/protected.layout.scss b/react-ui/src/shared/layouts/protected.layout/protected.layout.scss
similarity index 100%
rename from react-ui/src/utils/layouts/protected.layout/protected.layout.scss
rename to react-ui/src/shared/layouts/protected.layout/protected.layout.scss
diff --git a/react-ui/src/utils/layouts/protected.layout/protected.layout.tsx b/react-ui/src/shared/layouts/protected.layout/protected.layout.tsx
similarity index 98%
rename from react-ui/src/utils/layouts/protected.layout/protected.layout.tsx
rename to react-ui/src/shared/layouts/protected.layout/protected.layout.tsx
index 588491230158d7053f51fa1a28e2151c8d23b8cc..faff61c40e62c67b32dddb699cf4fb50dbe4a6ea 100644
--- a/react-ui/src/utils/layouts/protected.layout/protected.layout.tsx
+++ b/react-ui/src/shared/layouts/protected.layout/protected.layout.tsx
@@ -1,16 +1,16 @@
 import logo from '@assets/logo.svg';
 import { faCircleUser, faRightFromBracket } from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { useAppDispatch, useAppSelector } from '@hooks';
 import { useAuth } from "@provider/auth.provider";
+import { fetchPnds } from '@reducer/device.reducer/device.reducer';
+import { fetchUser } from '@reducer/user.reducer';
+import { DEVICE_URL, LOGIN_URL } from '@routes';
 import React, { useEffect } from "react";
 import { Dropdown } from "react-bootstrap";
 import { useTranslation } from "react-i18next";
 import { Link, Outlet, useNavigate } from "react-router-dom";
 import "./protected.layout.scss";
-import { useAppDispatch, useAppSelector } from '@hooks';
-import { fetchUser } from '@reducer/user.reducer';
-import { fetchPnds } from '@reducer/device.reducer';
-import { DEVICE_URL, LOGIN_URL } from '@routes';
 
 
 export const ProtectedLayout = () => {
diff --git a/react-ui/src/utils/provider/auth.provider.tsx b/react-ui/src/shared/provider/auth.provider.tsx
similarity index 100%
rename from react-ui/src/utils/provider/auth.provider.tsx
rename to react-ui/src/shared/provider/auth.provider.tsx
diff --git a/react-ui/src/shared/utils/routine.manager.ts b/react-ui/src/shared/utils/routine.manager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c86e30d4a6f8eeee961e62fbfd0b444a0440a837
--- /dev/null
+++ b/react-ui/src/shared/utils/routine.manager.ts
@@ -0,0 +1,88 @@
+import { fetchSelectedMneThunk } from '@reducer/device.reducer/mne.subscription';
+import { AsyncThunk } from '@reduxjs/toolkit';
+import { QueryActionCreatorResult } from '@reduxjs/toolkit/query';
+import { fetchDevicesThunk } from '@routine/device.routine';
+
+type Routine = QueryActionCreatorResult<any>;
+
+interface Entity {
+    routine: Routine,
+    id: number
+}
+
+const initialState = {
+    routines: [] as Entity[]
+}
+
+export enum THUNK_KEY {
+    MNE =  'device/fetch',
+    DEVICE =  'mne/fetch',
+}
+
+export const RoutineDictionary = new Map<THUNK_KEY,AsyncThunk<any, any, {}>>([
+    [THUNK_KEY.DEVICE, fetchDevicesThunk],
+    [THUNK_KEY.MNE, fetchSelectedMneThunk]
+])
+
+
+/**
+ * Routine manager is a singleton that holds all running routines.
+ * The redux store holds any persistable information about the routines.
+ * The routines objects itself are stored in the RoutineManager.
+ */
+export const RoutineManager = (() => {
+    let state = initialState;
+    const add = (routine: Routine): number => {
+        const id = state.routines.length;
+
+        const newEntity: Entity = {
+            routine: routine,
+            id
+        }
+
+        state.routines = [...state.routines, newEntity];
+
+        return id;
+    }
+
+
+    const unsubscribeAll = () => {
+        state.routines.forEach(({ routine: subscription }) => {
+            _unsubscribe(subscription)
+        });
+
+        state.routines = initialState.routines;
+    }
+
+    /**
+     * @param id 
+     * @returns returns true if the routine was stopped, false if it was not found
+     */
+    const unsubscribe = (id: number): boolean => {
+        const routine = state.routines.find(({ id: routineId }) => routineId === id);
+
+        if (routine) {
+            _unsubscribe(routine.routine);
+        }
+
+        return !!routine;
+    }
+
+    /**
+     * Actual unsubscribe process.
+     * This process is extracted to have a single process of unsubscribing.
+     * 
+     * @param subscription 
+     */
+    const _unsubscribe = (subscription: Routine) => {
+        subscription.unsubscribe();
+        // TODO remove from state
+    }
+
+
+    return {
+        add,
+        unsubscribe,
+        unsubscribeAll
+    }
+})();
\ No newline at end of file
diff --git a/react-ui/src/stores/index.ts b/react-ui/src/stores/index.ts
index 8d2be362f62efa197e771cb2caaecd9798c4cc60..1b3c3335e60549d6bc6934698d099da759ebe46e 100644
--- a/react-ui/src/stores/index.ts
+++ b/react-ui/src/stores/index.ts
@@ -1,6 +1,6 @@
 import { configureStore } from '@reduxjs/toolkit'
 import { setupListeners } from '@reduxjs/toolkit/query'
-import { FETCH_DEVICE_ACTION, FETCH_MNE_ACTION } from '@subscription/action.subscription'
+import { FETCH_DEVICE_ACTION, FETCH_MNE_ACTION } from '@routine/action.routine'
 import { FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE } from 'redux-persist'
 import persistStore from 'redux-persist/es/persistStore'
 import { emptySplitApi } from './api.store'
@@ -14,7 +14,7 @@ export const store = configureStore({
   middleware: (getDefaultMiddleware) =>
     getDefaultMiddleware({
       serializableCheck: {
-        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, FETCH_DEVICE_ACTION + '/fulfilled', FETCH_MNE_ACTION + '/fulfilled'],
+        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER, FETCH_DEVICE_ACTION + '/fulfilled', FETCH_MNE_ACTION + '/fulfilled', 'routine/addRoutine'],
       },
     }).prepend(listenerMiddleware.middleware).concat(emptySplitApi.middleware, rtkQueryErrorLogger),
 })
diff --git a/react-ui/src/stores/persist.store.ts b/react-ui/src/stores/persist.store.ts
index f14de1bd7f383e3f667a880293a34a52605c8c3e..65ade7d3e85184bef4d8ec10c66acab3e09bdf5a 100644
--- a/react-ui/src/stores/persist.store.ts
+++ b/react-ui/src/stores/persist.store.ts
@@ -1,5 +1,5 @@
-import deviceReducer from "@reducer/device.reducer";
-import subscriptionReducer from "@reducer/subscription.reducer";
+import deviceReducer from "@reducer/device.reducer/device.reducer";
+import routineReducer from "@reducer/routine.reducer";
 import userReducer from "@reducer/user.reducer";
 import { combineReducers } from "redux";
 import { persistReducer } from "redux-persist";
@@ -18,7 +18,7 @@ const rootPersistConfig = {
 const rootReducer = combineReducers({
     user: userReducer, 
     device: deviceReducer, 
-    subscription: subscriptionReducer, 
+    routine: routineReducer, 
     [emptySplitApi.reducerPath]: emptySplitApi.reducer,
 })
 
diff --git a/react-ui/src/stores/reducer/device.reducer.ts b/react-ui/src/stores/reducer/device.reducer/device.reducer.ts
similarity index 97%
rename from react-ui/src/stores/reducer/device.reducer.ts
rename to react-ui/src/stores/reducer/device.reducer/device.reducer.ts
index 5919062d27f4464dca20b03e78d2cf4ca4d3148c..9f21bcbeb7273bdbb3cab53ff8749bee7f7eeaa3 100644
--- a/react-ui/src/stores/reducer/device.reducer.ts
+++ b/react-ui/src/stores/reducer/device.reducer/device.reducer.ts
@@ -1,7 +1,6 @@
 import { api, NetworkelementFlattenedManagedNetworkElement, NetworkelementManagedNetworkElement, PndPrincipalNetworkDomain, PndServiceGetPndListApiArg } from '@api/api';
 import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
 import { DeviceViewTabValues } from '@view/device/device.view.tabs';
-import { startListening } from '../middleware/listener.middleware';
 
 export type Device = NetworkelementFlattenedManagedNetworkElement;
 
diff --git a/react-ui/src/components/subscriptions/mne.subscription.ts b/react-ui/src/stores/reducer/device.reducer/mne.subscription.ts
similarity index 75%
rename from react-ui/src/components/subscriptions/mne.subscription.ts
rename to react-ui/src/stores/reducer/device.reducer/mne.subscription.ts
index b2b036007846f030f58c27763516aaee7e8c9ef4..d84e7c5a5a4c954e26e44599df2d2715d9e48590 100644
--- a/react-ui/src/components/subscriptions/mne.subscription.ts
+++ b/react-ui/src/stores/reducer/device.reducer/mne.subscription.ts
@@ -1,17 +1,17 @@
 import { api, NetworkElementServiceGetApiArg } from "@api/api";
-import { Device, setSelectedDevice, setSelectedMne } from "@reducer/device.reducer";
-import { CATEGORIES, triggerSubscription } from "@reducer/subscription.reducer";
+import { Device, setSelectedDevice, setSelectedMne } from "@reducer/device.reducer/device.reducer";
+import { addRoutine, CATEGORIES } from "@reducer/routine.reducer";
 import { createAsyncThunk } from "@reduxjs/toolkit";
+import { THUNK_KEY } from "@utils/routine.manager";
 import { RootState } from "src/stores";
-import { THUNK_TYPE } from ".";
-import { startListening } from "../../../src/stores/middleware/listener.middleware";
-import { FETCH_MNE_ACTION } from "./action.subscription";
+import { FETCH_MNE_ACTION } from "../../../components/routines/action.routine";
+import { startListening } from "../../middleware/listener.middleware";
 
 // fetch mne if selected device is set
 startListening({
     predicate: (action) => setSelectedDevice.match(action) && !!action.payload,
     effect: async (action, listenerApi) => {
-        listenerApi.dispatch(triggerSubscription({category: CATEGORIES.TAB, thunkType: THUNK_TYPE.MNE, payload: action.payload}));
+        listenerApi.dispatch(addRoutine({category: CATEGORIES.TAB, thunkKey: THUNK_KEY.MNE, payload: action.payload}));
     },
 })
 
diff --git a/react-ui/src/stores/reducer/subscription.reducer.ts b/react-ui/src/stores/reducer/routine.reducer.ts
similarity index 51%
rename from react-ui/src/stores/reducer/subscription.reducer.ts
rename to react-ui/src/stores/reducer/routine.reducer.ts
index 344b42d2502bb6bcfc984f242f33c60e7763c5dd..85ddd7b2b11a2fc35d5a3d49b38cdc5b3b540574 100644
--- a/react-ui/src/stores/reducer/subscription.reducer.ts
+++ b/react-ui/src/stores/reducer/routine.reducer.ts
@@ -1,14 +1,14 @@
 import { PayloadAction, createSlice } from '@reduxjs/toolkit';
-import { SubscriptionThunks, THUNK_TYPE } from '@subscription/index';
+import { RoutineDictionary, RoutineManager, THUNK_KEY } from '@utils/routine.manager';
+import { REHYDRATE } from 'redux-persist';
 import { RootState } from '..';
-import { SubscriptionHandler } from '../../utils/api/subscription.handler';
 import { startListening } from '../middleware/listener.middleware';
 import { setToken } from './user.reducer';
 
 
 
 interface ThunkEntityDTO {
-    thunkType: THUNK_TYPE,
+    thunkKey: THUNK_KEY,
     payload: any
 
     /**
@@ -19,11 +19,11 @@ interface ThunkEntityDTO {
 
 interface ThunkEntity extends ThunkEntityDTO {
     id?: number,
-    locked: boolean    
+    locked: boolean,
 }
 
 
-export interface SubscriptionReducerState {
+export interface ReducerState {
     thunks: {[key in keyof typeof CATEGORIES]: ThunkEntity | null}
 }
 
@@ -32,18 +32,18 @@ export enum CATEGORIES {
     TAB
 }
 
-const initialState: SubscriptionReducerState = {
+const initialState: ReducerState = {
     thunks: {
         TABLE: null,
         TAB: null
     }
 }
 
-const SubscriptionSlice = createSlice({
-    name: 'subscription',
+const RoutineSlice = createSlice({
+    name: 'routine',
     initialState,
     reducers: {
-        triggerSubscription: (state, {payload}: PayloadAction<ThunkEntityDTO>) => {
+        addRoutine: (state, {payload}: PayloadAction<ThunkEntityDTO>) => {
             const newThunk: ThunkEntity = {...payload, locked: true};
             state.thunks[CATEGORIES[payload.category]] = newThunk;
         },
@@ -60,51 +60,67 @@ const SubscriptionSlice = createSlice({
         },
 
         removeAll: (state) => {
-            SubscriptionHandler.unsubscribeAll()
+            RoutineManager.unsubscribeAll()
             state.thunks = initialState.thunks;
         },
     },
 })
 
-export const { triggerSubscription } = SubscriptionSlice.actions
+export const { addRoutine } = RoutineSlice.actions
 
-// on logout remove all subscriptions
+// on logout remove all routine
 startListening({
     predicate: (action) => setToken.match(action) && action.payload.token === null,
     effect: async (_, listenerApi) => {
-        listenerApi.dispatch(SubscriptionSlice.actions.removeAll());
+        listenerApi.dispatch(RoutineSlice.actions.removeAll());
     },
 })
 
+// on rehydrate add all persistet routines
+startListening({
+    predicate: ({type}) => type === REHYDRATE,
+    effect: async (_, listenerApi) => {
+        const {routine} = listenerApi.getState() as RootState;
+        for (const [_,thunk] of Object.entries<ThunkEntity>(routine.thunks)) {
+            if (!thunk) {
+                return;
+            }
+
+            const dto: ThunkEntityDTO = thunk;
+            listenerApi.dispatch(addRoutine(dto));
+        }
+    },
+})
 
-// unsubscribe old subscription 
+// unsubscribe old routine 
 startListening({
-    predicate: (action) => triggerSubscription.match(action),
+    predicate: (action) => addRoutine.match(action),
     effect: async (action, listenerApi) => {
-        const {subscription} = listenerApi.getOriginalState() as RootState;
-        const lastThunk = subscription.thunks[CATEGORIES[action.payload.category]];
-        SubscriptionHandler.unsubscribe(lastThunk.id);
+        const {routine} = listenerApi.getOriginalState() as RootState;
+        const lastThunk = routine.thunks[CATEGORIES[action.payload.category]];
+        if (lastThunk) {
+            RoutineManager.unsubscribe(lastThunk.id);
+        }
     },
 })
 
-// add new subscription
+// add new routine
 startListening({
-    predicate: (action) => triggerSubscription.match(action),
+    predicate: (action) => addRoutine.match(action),
     effect: async (action, listenerApi) => {
-        const {thunkType} = action.payload as ThunkEntity;
+        const {thunkKey} = action.payload as ThunkEntity;
 
-        const {thunkFn} = SubscriptionThunks.find(({type}) => type === thunkType);
+        const thunkFn = RoutineDictionary.get(thunkKey);
         if (!thunkFn) {
             // TODO
             throw new Error('Thunk not found');
         }
         
         const subscription = await listenerApi.dispatch(thunkFn(action.payload.payload));
-        const thunkId = await SubscriptionHandler.add(subscription.payload);
-        listenerApi.dispatch(SubscriptionSlice.actions.setThunkId({id: thunkId, category: action.payload.category}));
-
+        const thunkId = await RoutineManager.add(subscription.payload);
+        listenerApi.dispatch(RoutineSlice.actions.setThunkId({id: thunkId, category: action.payload.category}));
     },
 })
 
 
-export default SubscriptionSlice.reducer
+export default RoutineSlice.reducer
diff --git a/react-ui/src/utils/api/subscription.handler.ts b/react-ui/src/utils/api/subscription.handler.ts
deleted file mode 100644
index e065879f03d26cd23c4b64ab4c4e2afe749f89b7..0000000000000000000000000000000000000000
--- a/react-ui/src/utils/api/subscription.handler.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { QueryActionCreatorResult } from '@reduxjs/toolkit/query';
-
-type Subscription = QueryActionCreatorResult<any>;
-
-interface Entity {
-    subscription: Subscription,
-    id: number
-}
-
-
-const initialState = {
-    subscriptions: [] as Entity[]
-}
-
-export const SubscriptionHandler = (() => {
-    let state = initialState;
-    const add = (subscription: Subscription): number => {
-        const id = state.subscriptions.length;
-
-        const subscriptionEntity: Entity = {
-            subscription,
-            id
-        }
-
-        state.subscriptions = [...state.subscriptions, subscriptionEntity];
-
-        return id;
-    }
-
-
-    const unsubscribeAll = () => {
-        state.subscriptions.forEach(({ subscription }) => {
-            unsubscribeAction(subscription)
-        });
-
-        state.subscriptions = initialState.subscriptions;
-    }
-
-    /**
-     * @param id 
-     * @returns returns true if the subscription was stopped, false if it was not found
-     */
-    const unsubscribe = (id: number): boolean => {
-        const subscription = state.subscriptions.find(({ id: subscriptionId }) => subscriptionId === id);
-
-        if (subscription) {
-            unsubscribeAction(subscription.subscription);
-        }
-
-        return !!subscription;
-    }
-
-    /**
-     * Actual unsubscribe action
-     * 
-     * @param subscription 
-     */
-    const unsubscribeAction = (subscription: Subscription) => {
-        subscription.unsubscribe();
-    }
-
-
-    return {
-        add,
-        unsubscribe,
-        unsubscribeAll
-    }
-})();
\ No newline at end of file
diff --git a/react-ui/tsconfig.json b/react-ui/tsconfig.json
index 41c9c8f6684c18bff5f0ac8aa7c808040e92cfbf..6bd0a18b729d68b99f9f632b42a2d8fefa06675c 100644
--- a/react-ui/tsconfig.json
+++ b/react-ui/tsconfig.json
@@ -23,17 +23,18 @@
         "baseUrl": ".",
         "paths": {
             "@assets/*": ["assets/*"],
-            "@api/*": ["src/utils/api/*"],
+            "@api/*": ["src/shared/api/*"],
             "@viewmodel/*": ["src/components/view_model/*"],
             "@view/*": ["src/components/view/*"],
             "@reducer/*": ["src/stores/reducer/*"],
-            "@provider/*": ["src/utils/provider/*"],
-            "@layout/*": ["src/utils/layouts/*"],
+            "@provider/*": ["src/shared/provider/*"],
+            "@layout/*": ["src/shared/layouts/*"],
             "@hooks": ["src/hooks"],
             "@routes": ["src/routes.tsx"],
-            "@task/*": ["src/utils/tasks/*"],
-            "@helper/*": ["src/utils/helper/*"],
-            "@subscription/*": ["src/components/subscriptions/*"]
+            "@task/*": ["src/shared/tasks/*"],
+            "@helper/*": ["src/shared/helper/*"],
+            "@routine/*": ["src/components/routines/*"],
+            "@utils/*": ["src/shared/utils/*"]
         }
     },
     "include": [
diff --git a/react-ui/vite.config.mjs b/react-ui/vite.config.mjs
index 96be1c8444581aa8a9268841dcc275755fb31b45..d36e8cf3a4fddc50ea26a2e19c97a45a88e56961 100644
--- a/react-ui/vite.config.mjs
+++ b/react-ui/vite.config.mjs
@@ -36,17 +36,18 @@ export default defineConfig({
     resolve: {
         alias: {
             '@assets': '/assets',
-            '@api': '/src/utils/api',
+            '@api': '/src/shared/api',
             '@viewmodel': '/src/components/view_model',
             '@view': '/src/components/view',
             '@reducer': '/src/stores/reducer',
-            '@provider': '/src/utils/provider',
-            '@layout': '/src/utils/layouts',
+            '@provider': '/src/shared/provider',
+            '@layout': '/src/shared/layouts',
             '@hooks': '/src/hooks.ts',
-            '@task': '/src/utils/tasks',
-            '@helper': '/src/utils/helper',
+            '@task': '/src/shared/tasks',
+            '@helper': '/src/shared/helper',
             '@routes': '/src/routes.tsx',
-            '@subscription': '/src/components/subscriptions',
+            '@routine': '/src/components/routines',
+            '@utils': '/src/shared/utils',
         },
     },