diff --git a/saqc/core/register.py b/saqc/core/register.py
index 072c68b6e6cd1cdeba677dadfac8a819cd09b10e..9607bebe309d18cfc28b7d0e316d23e29d8f1e6a 100644
--- a/saqc/core/register.py
+++ b/saqc/core/register.py
@@ -39,7 +39,6 @@ class CallState:
 
 
 def processing(module: Optional[str] = None):
-
     # executed on module import
     def inner(func):
         func_name = func.__name__
@@ -58,7 +57,6 @@ def processing(module: Optional[str] = None):
 
 
 def flagging(masking: MaskingStrT = "all", module: Optional[str] = None):
-
     # executed on module import
     def inner(func):
         func_name = func.__name__
@@ -324,65 +322,63 @@ def _restoreFlags(flags: Flags, old_state: CallState):
     -------
     Flags
     """
-    columns = flags.columns
-
-    if old_state.masking == "all":
-        pass
-
-    # The function processed a copy of the original flags and may or may not added some
-    # columns. So we take only new history columns and define new flags with it, which
-    # are enriched with meta later
-    elif old_state.masking == "none":
-        flags = flags.copy(deep=False)
-
-        for c in flags.columns:
-            # if a new field (aka. variable) was inserted, we take the full history and
-            # no slicing is needed, which is the hidden else-case.
-            if c in old_state.flags.columns:
-                l = len(old_state.flags.history[c].columns)
-                flags.history[c] = _sliceHistory(flags.history[c], slice(l, None))
-
-    # take field column and all possibly newly added columns
+    out = old_state.flags.copy()
+    meta = {
+        "func": old_state.func_name,
+        "args": old_state.args,
+        "keywords": old_state.kwargs,
+    }
+    new_columns = flags.columns.difference(old_state.flags.columns)
+
+    # masking == 'none'
+    # - no data was masked (no relevance here, but help understanding)
+    # - the saqc-function got a copy of the whole flags frame with all full histories
+    #   (but is not allowed to change them; we have -> @processing for this case)
+    # - the saqc-function appended none or some columns to the each history
+    #
+    # masking == 'all'
+    # - all data was masked by flags (no relevance here, but help understanding)
+    # - the saqc-function got a complete new flags frame, with empty Histories
+    # - the saqc-function appended none or some columns to the each history
+    #
+    # masking == 'field'
+    # - some data columns were masked by flags (no relevance here)
+    # - the saqc-function got a complete new flags frame, with empty Histories
+    # - the saqc-function appended none or some columns to the each history
+    # Note: actually the flags SHOULD have been cleared only at the field (as the
+    # masking-parameter implies) but the current implementation in `_prepareFlags`
+    # clear all columns. Nevertheless the following code only update the field (and new
+    # columns) and not all columns.
+    if old_state.masking == "none":
+        columns = flags.columns
+    elif old_state.masking == "all":
+        columns = flags.columns
     elif old_state.masking == "field":
-        columns = columns.difference(old_state.flags.columns)
-        columns = columns.append(pd.Index([old_state.field]))
-
+        columns = pd.Index([old_state.field])
     else:
         raise RuntimeError(old_state.masking)
 
-    out = old_state.flags.copy()
+    for c in columns.union(new_columns):
 
-    # this implicitly squash the new flags history (RHS) to a single column, which than
-    # is appended to the old history (LHS). Thus because the new flags history possibly
-    # consists of multiple columns, one for each time a series or scalar was passed to
-    # the flags.
-    for c in columns:
+        if c in new_columns:
+            history = flags.history[c]
+            out.history[c] = History(index=history.index)  # ensure existence
+        # New columns was appended to the old history, but we want to have the new
+        # columns only. If old and new are the same (nothing was appended), we end up
+        # having a empty history, whats handled later correctly
+        elif old_state.masking == "none":
+            sl = slice(len(old_state.flags.history[c].columns), None)
+            history = _sliceHistory(flags.history[c], sl)
+        else:
+            history = flags.history[c]
+
+        squeezed = flags.history[c].max(raw=True)
+
+        # nothing to update
+        if history.empty or (squeezed == UNTOUCHED).all():
+            continue
 
-        h = flags.history[c]
-        hmax = h.max(raw=True)
-
-        # # handle empty case (i.e. test didn't set any flags, can happen on early returns),
-        # # to prevent a missing (empty) flags column
-        # if h.empty:
-        #     out.history[c] = h.copy()
-        #     continue
-
-        # # if nothing was touched we have no need to clutter the history
-        # if (hmax == UNTOUCHED).all():
-        #     continue
-
-        out[c] = hmax
-
-        # we enrich the (already existing !) empty meta with some infos
-        history = out.history[c]
-        history.meta[-1].update(
-            {
-                "func": old_state.func_name,
-                "args": old_state.args,
-                "keywords": old_state.kwargs,
-            }
-        )
-        out.history[c] = history
+        out.history[c] = out.history[c].append(squeezed, force=True, meta=meta)
 
     return out