diff --git a/km3io/online.py b/km3io/online.py
index 5aa9774bacc964e7120b97c6066595125730e2d2..de6c519f4c1e636d93e6fde9d035d7c05e1d4413 100644
--- a/km3io/online.py
+++ b/km3io/online.py
@@ -1,4 +1,5 @@
 import binascii
+from collections import namedtuple
 import os
 import uproot
 import uproot3
@@ -22,36 +23,70 @@ RATE_FACTOR = np.log(MAXIMAL_RATE_HZ / MINIMAL_RATE_HZ) / 255
 CHANNEL_BITS_TEMPLATE = np.zeros(31, dtype=bool)
 
 
+SummarysliceChunk = namedtuple(field_names=["headers", "slices"], typename="SummarysliceChunk")
+
+
 class SummarysliceReader:
+    """
+    A reader for summaryslices which are loaded as chunks given by step_size.
+
+    To be used as an iterator (`for chunks in SummarysliceReader(...): ...`)
+    """
     TREE_ADDR = "KM3NET_SUMMARYSLICE/KM3NET_SUMMARYSLICE"
-    BRANCH_NAME = "vector<KM3NETDAQ::JDAQSummaryFrame>"
+    SUMMARYSLICES_BRANCH_NAME = "vector<KM3NETDAQ::JDAQSummaryFrame>"
+    HEADERS_BRANCH_NAME = "KM3NETDAQ::JDAQSummarysliceHeader"
     SUMMARYSLICE_INTERPRETATION = uproot.interpretation.jagged.AsJagged(
         uproot.interpretation.numerical.AsDtype(
             [
                 ("dom_id", ">i4"),
-                ("dq_status", "u4"),
-                ("hrv", "<u4"),
-                ("fifo", "<u4"),
-                ("status3", "u4"),
-                ("status4", "u4"),
+                ("dq_status", ">u4"),
+                ("hrv", ">u4"),
+                ("fifo", ">u4"),
+                ("status3", ">u4"),
+                ("status4", ">u4"),
             ]
             + [(f"ch{c}", "u1") for c in range(31)]
         ),
         header_bytes=10,
     )
+    HEADER_INTERPRETATION = uproot.interpretation.numerical.AsDtype(
+            [
+                (" cnt", "u4"),
+                (" vers", "u2"),
+                (" cnt2", "u4"),
+                (" vers2", "u2"),
+                (" cnt3", "u4"),
+                (" vers3", "u2"),
+                ("detector_id", ">i4"),
+                ("run", ">i4"),
+                ("frame_index", ">i4"),
+                (" cnt4", "u4"),
+                (" vers4", "u2"),
+                ("UTC_seconds", ">u4"),
+                ("UTC_16nanosecondcycles", ">u4"),
+            ]
+        )
 
-    def __init__(self, filename, step_size=1000):
-        self._filename = filename
+    def __init__(self, fobj, step_size=1000):
+        if isinstance(fobj, str):
+            self._fobj = uproot.open(fobj)
+        else:
+            self._fobj = fobj
         self._step_size = step_size
-        self._fobj = uproot.open(filename)
         self._branch = self._fobj[self.TREE_ADDR]
 
     def _summaryslices_generator(self):
-        expressions = {self.BRANCH_NAME: self.SUMMARYSLICE_INTERPRETATION}
-        for summaryslices in self._branch.iterate(
+        expressions = {
+            self.SUMMARYSLICES_BRANCH_NAME: self.SUMMARYSLICE_INTERPRETATION,
+            self.HEADERS_BRANCH_NAME: self.HEADER_INTERPRETATION,
+        }
+        for chunk in self._branch.iterate(
             expressions, step_size=self._step_size
         ):
-            yield summaryslices[self.BRANCH_NAME]
+            yield SummarysliceChunk(
+                chunk[self.HEADERS_BRANCH_NAME],
+                chunk[self.SUMMARYSLICES_BRANCH_NAME],
+            )
 
     def __iter__(self):
         self._summaryslices = self._summaryslices_generator()
@@ -63,6 +98,9 @@ class SummarysliceReader:
     def __len__(self):
         return int(np.ceil(self._branch.num_entries / self._step_size))
 
+    def __repr__(self):
+        return f"<SummarysliceReader {self._branch.num_entries} summaryslices, step_size={self._step_size} ({len(self)} chunks)>"
+
 
 @nb.vectorize(
     [nb.int32(nb.int8), nb.int32(nb.int16), nb.int32(nb.int32), nb.int32(nb.int64)]
@@ -224,74 +262,10 @@ class OnlineReader:
     @property
     def summaryslices(self):
         if self._summaryslices is None:
-            self._summaryslices = SummarySlices(self._fobj)
+            self._summaryslices = SummarysliceReader(uproot.open(self._filename))  # TODO: remove when using uproot4
         return self._summaryslices
 
 
-class SummarySlices:
-    """A wrapper for summary slices"""
-
-    def __init__(self, fobj):
-        self._fobj = fobj
-        self._slices = None
-        self._headers = None
-        self._rates = None
-        self._ch_selector = ["ch{}".format(c) for c in range(31)]
-
-    @property
-    def headers(self):
-        if self._headers is None:
-            self._headers = self._read_headers()
-        return self._headers
-
-    @property
-    def slices(self):
-        if self._slices is None:
-            self._slices = self._read_summaryslices()
-        return self._slices
-
-    @property
-    def rates(self):
-        if self._rates is None:
-            self._rates = self.slices[["dom_id"] + self._ch_selector]
-        return self._rates
-
-    def _read_summaryslices(self):
-        """Reads a lazyarray of summary slices"""
-        tree = self._fobj[b"KM3NET_SUMMARYSLICE"][b"KM3NET_SUMMARYSLICE"]
-        return tree[b"vector<KM3NETDAQ::JDAQSummaryFrame>"].lazyarray(
-            uproot3.asjagged(
-                uproot3.astable(
-                    uproot3.asdtype(
-                        [
-                            ("dom_id", "i4"),
-                            ("dq_status", "u4"),
-                            ("hrv", "u4"),
-                            ("fifo", "u4"),
-                            ("status3", "u4"),
-                            ("status4", "u4"),
-                        ]
-                        + [(c, "u1") for c in self._ch_selector]
-                    )
-                ),
-                skipbytes=10,
-            ),
-            basketcache=uproot3.cache.ThreadSafeArrayCache(
-                SUMMARYSLICE_FRAME_BASKET_CACHE_SIZE
-            ),
-        )
-
-    def _read_headers(self):
-        """Reads a lazyarray of summary slice headers"""
-        tree = self._fobj[b"KM3NET_SUMMARYSLICE"][b"KM3NET_SUMMARYSLICE"]
-        return tree[b"KM3NETDAQ::JDAQSummarysliceHeader"].lazyarray(
-            uproot3.interpret(tree[b"KM3NETDAQ::JDAQSummarysliceHeader"], cntvers=True)
-        )
-
-    def __str__(self):
-        return "Number of summaryslices: {}".format(len(self.headers))
-
-
 class Timeslices:
     """A simple wrapper for timeslices"""
 
diff --git a/tests/test_online.py b/tests/test_online.py
index c86ab49b5e7675c9e5ad8e8766c7ddd92913b755..09fb9acc7438c78858e968e7c495beef9fd54d8e 100644
--- a/tests/test_online.py
+++ b/tests/test_online.py
@@ -175,7 +175,9 @@ class TestTimeslice(unittest.TestCase):
 
 class TestSummaryslices(unittest.TestCase):
     def setUp(self):
-        self.ss = OnlineReader(ONLINE_FILE).summaryslices
+        for chunk in OnlineReader(ONLINE_FILE).summaryslices:
+            self.ss = chunk
+            break
 
     def test_headers(self):
         assert 3 == len(self.ss.headers)
@@ -187,9 +189,6 @@ class TestSummaryslices(unittest.TestCase):
     def test_slices(self):
         assert 3 == len(self.ss.slices)
 
-    def test_rates(self):
-        assert 3 == len(self.ss.rates)
-
     def test_fifo(self):
         s = self.ss.slices[0]
         dct_fifo_stat = {
@@ -700,7 +699,10 @@ class TestGetChannelFlags_Issue59(unittest.TestCase):
         r = OnlineReader(
             data_path("online/KM3NeT_00000049_00008456.summaryslice-167941.root")
         )
-        summaryslice = r.summaryslices.slices[0]
+
+        for chunks in r.summaryslices:
+            summaryslice = chunks.slices[0]
+            break
 
         for ours, ref in zip(summaryslice, ref_entries):
             assert ours.dom_id == to_num(ref.dom_id)
@@ -766,16 +768,16 @@ class TestSummarysliceReader(unittest.TestCase):
 
         for ss in sr:
             self.assertListEqual(
-                ss[0].dom_id[:3].to_list(), [806451572, 806455814, 806465101]
+                ss.slices[0].dom_id[:3].to_list(), [806451572, 806455814, 806465101]
             )
             self.assertListEqual(
-                ss[0].dom_id[-3:].to_list(), [809526097, 809544058, 809544061]
+                ss.slices[0].dom_id[-3:].to_list(), [809526097, 809544058, 809544061]
             )
-            assert len(ss) == 3
-            assert len(ss[0]) == 64
-            assert len(ss[1]) == 66
-            assert len(ss[2]) == 68
-            self.assertListEqual(ss[0].ch5[:3].to_list(), [75, 62, 55])
+            assert len(ss.slices) == 3
+            assert len(ss.slices[0]) == 64
+            assert len(ss.slices[1]) == 66
+            assert len(ss.slices[2]) == 68
+            self.assertListEqual(ss.slices[0].ch5[:3].to_list(), [75, 62, 55])
 
         sr = SummarysliceReader(data_path("online/km3net_online.root"), step_size=1)
 
@@ -784,7 +786,7 @@ class TestSummarysliceReader(unittest.TestCase):
         for idx, ss in enumerate(sr):
             # self.assertListEqual(ss[0].dom_id[:3].to_list(), [806451572, 806455814, 806465101])
             # self.assertListEqual(ss[0].dom_id[-3:].to_list(), [809526097, 809544058, 809544061])
-            assert len(ss) == 1
-            assert len(ss[0]) == lengths[idx]
-            assert len(ss[0].dom_id) == lengths[idx]
-            assert len(ss[0].ch3) == lengths[idx]
+            assert len(ss.slices) == 1
+            assert len(ss.slices[0]) == lengths[idx]
+            assert len(ss.slices[0].dom_id) == lengths[idx]
+            assert len(ss.slices[0].ch3) == lengths[idx]