            (.foreach index push-input)
            (.foreach-reverse index push-input))
          (push-input (btree/greatest-key group-len))
-         (dotimes [i (alength sinks)]
-           (.run (aget sinks i) kn rule->dirty? kind->name->rules facts&vals)))))
+
+         ;; diff against old output
+         (let [old-output (or (.-facts&vals index) (btree/tree 10 (+ group-len 1 (alength aggs))))
+               delta-output (btree/tree 10 (+ group-len 1 (alength aggs)))]
+           (.foreach old-output
+                     (fn [k v]
+                       (.update delta-output k (- v))))
+           (.foreach new-output
+                     (fn [k v]
+                       (.update delta-output k v)))
+
+           ;; save new output
+           (set! (.-facts&vals index) new-output)
+
+           ;; send deltas to sinks
+           (let [facts&vals (.elems delta-output)]
+             (dotimes [i (alength sinks)]
+               (.run (aget sinks i) kn rule->dirty? kind->name->rules facts&vals)))))))
 
 (deftype Flows [rules rule->flow rule->dirty? kind->name->rules name->lifetime]
   Object

         (dotimes [i (alength sinks)]
           (.run (aget sinks i) kn rule->dirty? kind->name->rules facts&vals)))))

(deftype AggregateFlow [index group-len limit-ix ascending? agg-ixes agg-funs sinks]
  Object
  (run [this kn rule->dirty? kind->name->rules]
       (let [current-key nil
             current-limit nil
             current-index 1
             inputs #js []
             aggs (make-array (alength agg-ixes))
             facts&vals #js []
             push-input (fn [key]
                          (when (nil? current-key)
                            (set!! current-key key)

                              (let [output (aget inputs i)]
                                (dotimes [j (alength aggs)]
                                  (apush output (aget aggs j)))
                                (.update new-output output 1)))
                            (aclear inputs)
                            (set!! current-key key)
                            (set!! current-limit (aget key limit-ix))
