bittide: Distributed Synchronization Without a Central Clock
Reading time: 10
When you have multiple computers working together on a task (say, a distributed AI training cluster) they each have their own internal clock. These clocks are never perfectly in sync. One ticks slightly faster, another slightly slower. Over time this causes problems. One node sends data faster than another can receive it, so buffers overflow or run dry. The whole system then needs complex traffic management to compensate. This is expensive, slow, and introduces unpredictability. Basing solutions on research from Google, we successfully worked to solve this problem.
Instead of synchronizing clocks to a shared global time reference, bittide takes a different angle. GPS and the PTP protocol both use that conventional approach. Bittide does not care what time it is, only that all nodes tick at the same frequency.
Each node watches its own incoming data buffers. If a buffer is filling up, it means the sender is ticking faster than you are. So, you speed up your clock slightly. If the buffer is draining, you slow down. That’s it. There’s no central timekeeper and no need for complex coordination messages. The system self-organizes into frequency alignment purely by watching its own buffers.
Project background
In the context of this project, we co-authored a research paper with Google DeepMind and Stanford University, published in March 2025. The paper presents the first hardware implementation of bittide. We designed and built this, using Clash as the primary hardware description language. The full implementation is open source.
An elegant result
Once all nodes are ticking at the same frequency, some cool things start happening. The delay between one node sending a frame and another node receiving it (called the ‘logical latency’) becomes a fixed, predictable constant. It doesn’t fluctuate, jitter or change because of network load or what else is running on the system. To test just how robust this property is, one experiment replaced the short cable between two nodes with a 2km fiber-optic cable. The clock behavior and buffer occupancy across all eight nodes were nearly identical to the baseline. The logical latency on that link went up as expected, since light takes time to travel 2km, but it stayed perfectly stable. The physical length of the link turned out to be irrelevant to the quality of the synchronization.
Why this changes the playing field
Conventional distributed systems are built defensively. Because you can never be certain exactly when a message will arrive – network congestion, retransmissions, and competing processes all introduce unpredictability – systems compensate with flow control, backpressure signaling and synchronization barriers between computation steps. These mechanisms work, but they carry overhead and put a ceiling on how tightly you can coordinate distributed computation.
Bittide removes the source of uncertainty rather than managing its symptoms. Because logical latency is constant, compute and communication can be scheduled ahead of time, before any code runs. You know exactly when every message will arrive at every node. This makes it possible to build deep computation pipelines across multiple machines with the same predictability you would normally only have inside a single chip, without any in-band signaling overhead to achieve it.
From theory to hardware
Bittide was proposed theoretically several years ago, but this project represents its first implementation in real hardware.
The implementation consists of eight FPGA nodes, each with its own independent clock, interconnected in several different network configurations: a fully connected mesh, an hourglass topology, and a cube. Across all configurations, the clocks converged to within 1 ppm of each other, buffer occupancies stabilized and logical latencies remained consistent. The mathematical model developed alongside the mechanism accurately predicted the hardware behavior, and simulations showed the approach scaling to networks of millions of nodes.
Built with our own tools
We designed the hardware using Clash, our open-source hardware description language compiler. Three specific features of Clash were crucial in achieving this. First, Clash’s type system encodes clock domains directly, meaning the compiler catches accidental clock domain crossings that in other hardware languages typically only surface as bugs after synthesis. In a design with multiple independent clocks per node, as bittide requires, this is a major convenience.
Second, Clash handles the automatic pipelining of floating point operations, tracking signal delays at the type level and inserting the correct number of registers automatically.
Third, Clash is built on Haskell. So the same codebase that describes the hardware also generates the experiments, simulates the design, processes measurement data and produces the diagrams, all in one language.
Bittide at scale?
Distributed computing has been managing the symptoms of the clock problem for decades. The bittide project shows that it can be solved at the source. The next step will be to see whether that holds at scale, across the thousands of nodes in ever-growing and ever more complex production environments. But we’re proud to have shown that the hardware works, the model predicted the correct outcomes and that the implementation is open for anyone to examine and improve upon.
Frequently asked questions
What is bittide?
Bittide is a mechanism that keeps the nodes of a distributed system ticking at the same frequency without any central timekeeper. Each node watches its own incoming data buffers: if a buffer is filling up the sender is ticking faster, so the node speeds up its clock slightly, and if the buffer is draining it slows down. The system self-organizes into frequency alignment purely by watching its own buffers, with no coordination messages.
How does bittide differ from GPS or PTP synchronization?
Conventional approaches synchronize clocks to a shared global time reference. Bittide does not care what time it is, only that all nodes tick at the same frequency. That removes the need for a central timekeeper and for complex coordination, and it is what makes the delay between one node sending a frame and another receiving it a fixed, predictable constant.
Why does constant logical latency matter?
Because it removes the uncertainty that distributed systems are normally built to defend against. Conventional systems compensate for unpredictable message arrival with flow control, backpressure signalling and synchronization barriers, all of which carry overhead. When logical latency is constant, compute and communication can be scheduled ahead of time, before any code runs, making it possible to build deep computation pipelines across multiple machines.
