+ new_dat_lines
                                      + self.server.dat_lines[end_idx+1:])
             self.server.load_bookings()
-            self.server.tainted = True
             self.redirect(Path('/').joinpath('booking').joinpath(str(id_)))
             return
         self.redirect(Path('/'))
         self.dat_lines = [
             DatLine(line)
             for line in self._path_dat.read_text(encoding='utf8').splitlines()]
+        self.last_save_hash = self._hash_dat_lines()
         self.load_bookings()
-        self.tainted = False
+
+    def _hash_dat_lines(self) -> int:
+        return hash(tuple(dl.raw for dl in self.dat_lines))
+
+    @property
+    def tainted(self) -> bool:
+        """If .dat_lines different to those of last .load()."""
+        return self._hash_dat_lines() != self.last_save_hash
 
     def load_bookings(self) -> None:
         """Read .dat_lines into Bookings / full ledger."""