How does smart mirroring work in Bitbucket Data Center, and how do you design a global deployment for geographically distributed teams?
Quick Answer
Smart mirroring deploys read-only Bitbucket instances in remote locations that synchronize with the primary cluster. Mirrors serve git clone and fetch requests locally while routing pushes back to the primary. Design considerations include mirror placement based on team density, synchronization lag tolerance, and network topology between mirrors and the primary cluster.
Detailed Answer
Think of smart mirroring like a content delivery network (CDN) for your Git repositories. Just as a CDN places copies of web content in edge locations near users, smart mirrors place copies of repositories near development teams. A developer in Singapore clones from the local mirror at LAN speed instead of crossing the Pacific to reach the primary cluster in Virginia. The difference can be 30 seconds versus 15 minutes for a large repository.
Smart mirroring is a Bitbucket Data Center feature that allows you to deploy lightweight, read-only Bitbucket instances in geographic locations close to your development teams. Each mirror synchronizes repositories from the primary Data Center cluster using Git's native replication protocol. When a developer's Git client connects to a mirror, read operations (clone, fetch, pull) are served directly by the mirror. Write operations (push) are transparently proxied to the primary cluster, which then notifies all mirrors to resynchronize the affected repository. The mirror acts as a smart proxy: it intercepts the Git protocol, determines whether the operation is read or write, and routes accordingly.
The synchronization model is eventually consistent. When a developer pushes to the primary (directly or via mirror proxy), the primary processes the push and then sends a webhook-style notification to all configured mirrors. Each mirror then pulls the updated references from the primary. The synchronization delay is typically under 5 seconds for small pushes, but can be longer for very large pushes or when the network between the mirror and primary is congested. During the synchronization window, a developer on a different mirror might not see the most recent push. Mirrors also support farm-level mirroring, where you can choose which projects or repositories to mirror rather than mirroring everything, reducing storage and synchronization overhead.
In production, designing a global mirroring architecture requires analyzing team distribution, repository sizes, and network paths. The first step is identifying developer clusters: if you have 100 developers in New York, 50 in London, and 30 in Singapore, you deploy mirrors in each location. Each mirror needs sufficient storage for the repositories it mirrors, plus JVM memory for handling concurrent connections. The network between mirrors and the primary must be reliable and have sufficient bandwidth for synchronization traffic. Some organizations use dedicated VPN tunnels or AWS Direct Connect / Azure ExpressRoute for this traffic. For disaster recovery, mirrors cannot be promoted to primary automatically, so teams needing failover must design a separate HA strategy for the primary cluster.
A gotcha that causes developer frustration: mirrors do not support all Bitbucket features. Pull request operations, branch permissions, and API calls other than Git protocol are not handled by mirrors; they must go to the primary. Developers can clone from the mirror but must access the Bitbucket UI on the primary for code review. If the primary is geographically distant, the UI experience is slow even when Git operations are fast. Some organizations mitigate this by deploying a web accelerator (like Cloudflare or Akamai) in front of the primary's web interface. Another trap is storage sizing: mirrors store full repository data including all branches and tags, so a mirror for 500 repositories at 500 MB average needs 250 GB of storage, plus growth headroom.