A method performed by a computing device of distributed computing resources comprising one or more computing devices (106; 400) operating in a cluster, each computing device including one or multiple processors operably connected to a memory, the method comprising: performing a differential dataflow computation mapped across multiple processes running on respective said computing devices in the cluster, each of a plurality of data items (618, 622-626) to be processed in the computation being associated with a vertex of a cyclic dataflow graph modeling the computation, each vertex being partitioned into a plurality of disjoint shards, each process containing multiple workers implemented using threads, each worker being assigned one of the plurality of shards; tracking progress of the computation by: associating each of the plurality of data items (618, 622-626) to be processed in the computation with a timestamp (620, 628), the timestamp corresponding to a logical time at which the respective data item was created in the computation, the logical time being a tuple comprising at least an integer representing an epoch and an integer representing an iteration, wherein each cycle of the cyclic dataflow graph contains a vertex (322, 708) that increments the integer representing the iteration; for each process, storing in a respective coordination clock at least one mapping entry from a name of a said vertex associated with the process and a given logical time to a count of a number of data items yet to be processed by the said vertex at the given logical time; following operations at a said vertex, broadcasting to all processes a clock update indicating changes to the number of yet to be processed data items (618, 622-626) associated with respective vertices and the logical times at which the yet to be processed data items are to be processed; and when the count of the number of yet to be processed data items for all vertices that are associated with a particular process reaches zero, terminating the particular process. performing a differential dataflow computation mapped across multiple processes running on respective said computing devices in the cluster, each of a plurality of data items (618, 622-626) to be processed in the computation being associated with a vertex of a cyclic dataflow graph modeling the computation, each vertex being partitioned into a plurality of disjoint shards, each process containing multiple workers implemented using threads, each worker being assigned one of the plurality of shards; tracking progress of the computation by: associating each of the plurality of data items (618, 622-626) to be processed in the computation with a timestamp (620, 628), the timestamp corresponding to a logical time at which the respective data item was created in the computation, the logical time being a tuple comprising at least an integer representing an epoch and an integer representing an iteration, wherein each cycle of the cyclic dataflow graph contains a vertex (322, 708) that increments the integer representing the iteration; for each process, storing in a respective coordination clock at least one mapping entry from a name of a said vertex associated with the process and a given logical time to a count of a number of data items yet to be processed by the said vertex at the given logical time; following operations at a said vertex, broadcasting to all processes a clock update indicating changes to the number of yet to be processed data items (618, 622-626) associated with respective vertices and the logical times at which the yet to be processed data items are to be processed; and when the count of the number of yet to be processed data items for all vertices that are associated with a particular process reaches zero, terminating the particular process. associating each of the plurality of data items (618, 622-626) to be processed in the computation with a timestamp (620, 628), the timestamp corresponding to a logical time at which the respective data item was created in the computation, the logical time being a tuple comprising at least an integer representing an epoch and an integer representing an iteration, wherein each cycle of the cyclic dataflow graph contains a vertex (322, 708) that increments the integer representing the iteration; for each process, storing in a respective coordination clock at least one mapping entry from a name of a said vertex associated with the process and a given logical time to a count of a number of data items yet to be processed by the said vertex at the given logical time; following operations at a said vertex, broadcasting to all processes a clock update indicating changes to the number of yet to be processed data items (618, 622-626) associated with respective vertices and the logical times at which the yet to be processed data items are to be processed; and when the count of the number of yet to be processed data items for all vertices that are associated with a particular process reaches zero, terminating the particular process.