diff --git a/requirements.txt b/requirements.txt
index 1e86e61017a9f70631b25ba46ad808e16f0b715e..0acdd3827c4b16f9f8109b4ef7aafd5347b690b8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,6 @@ sympy==1.0
 git+https://github.com/inducer/pymbolic
 git+https://github.com/inducer/islpy
 git+https://github.com/inducer/pyopencl
-git+https://gitlab.tiker.net/inducer/boxtree
+git+https://gitlab.tiker.net/inducer/boxtree@timing-data
 git+https://github.com/inducer/loopy
 git+https://github.com/inducer/pyfmmlib
diff --git a/setup.py b/setup.py
index 8d0850540362ddfc3ecedf453f2ccc53bba21a1c..9457bbdc269697f61153e755a930efc9fccae41d 100644
--- a/setup.py
+++ b/setup.py
@@ -94,7 +94,7 @@ setup(name="sumpy",
       install_requires=[
           "pytools>=2018.2",
           "loo.py>=2017.2",
-          "boxtree>=2013.1",
+          "boxtree>=2018.1",
           "pytest>=2.3",
           "six",
 
diff --git a/sumpy/fmm.py b/sumpy/fmm.py
index 2231bd7c2191627a13b895e70169d4f531b8a90f..52748c7d2e54126fbba7445ac414a0bf0bd6835c 100644
--- a/sumpy/fmm.py
+++ b/sumpy/fmm.py
@@ -155,14 +155,20 @@ class TimingFuture(object):
     def __init__(self, events):
         self.events = events
 
-    def __call__(self):
+    @memoize_method
+    def get(self):
         pyopencl.wait_for_events(self.events)
 
         result = 0
         for event in self.events:
-            result += event.profile.end - event.profile.start
+            result += (
+                    (event.profile.end - event.profile.start)
+                    * _SECONDS_PER_NANOSECOND)
+        return result
 
-        return result * _SECONDS_PER_NANOSECOND
+    def __call__(self):
+        from boxtree.fmm import TimingResult
+        return TimingResult(wall_elapsed=self.get(), process_elapsed=None)
 
 # }}}
 
@@ -340,8 +346,8 @@ class SumpyExpansionWrangler(object):
             self.issued_timing_data_warning = True
             return
 
-        timing_data["description"] = description
-        timing_data["callback"] = TimingFuture(events)
+        timing_data.description = description
+        timing_data.callback = TimingFuture(events)
 
     def form_multipoles(self,
             level_start_source_box_nrs, source_boxes,
diff --git a/test/test_fmm.py b/test/test_fmm.py
index 5ec3498c4c1d4df14a2612172606e4ea239c98f7..0c4406bf9ed84c9a4cf260cbffaee29cbfdbf29c 100644
--- a/test/test_fmm.py
+++ b/test/test_fmm.py
@@ -286,6 +286,7 @@ def test_sumpy_fmm_timing_data(ctx_getter):
 
     timing_data = {}
     pot, = drive_fmm(trav, wrangler, weights, timing_data=timing_data)
+    print(timing_data)
     assert timing_data