Chromium Sync is a system designed to synchronize user data (bookmarks, passwords, history, etc.) across multiple devices. It follows a layered architecture to separate high-level service logic, low-level sync protocol management, and individual data type models. This document describes the high-level architecture.
Additional (more specific/detailed) docs are in docs/website/site/developers/design-documents/sync/. You can also visit them via chromium.org.
The system is primarily divided into four parts:
components/sync/service/)This is the main public entry point for the rest of Chromium. It runs on the UI thread.
SyncService / SyncServiceImpl: The central facade. It manages the overall sync lifecycle (initialization, startup, shutdown) and high-level state.SyncUserSettings: Manages user preferences, such as which data types are enabled and encryption settings.DataTypeController: Responsible for managing the state of a single data type (e.g., Bookmarks). It handles the transition between states like loading the model, connecting to the engine, and stopping. Data types may implement a subclass of this to customize the behavior.Some important private/internal classes:
DataTypeManager: Coordinates the starting and stopping of various data types.SyncAuthManager: Handles Gaia authentication and access tokens.SyncServiceCrypto: Manages encryption state and interacts with the “Nigori” (sync encryption) subsystem.components/sync/engine/)The engine performs the actual communication with the Sync server. It runs on a dedicated Sync thread.
SyncEngine / SyncEngineImpl: The main interface to the engine. Note that this lives on the UI thread; SyncEngineBackend is the corresponding Sync-thread class.SyncScheduler: Orchestrates when sync cycles should run (based on polling, nudges from local changes, or invalidations from the server).DataTypeWorker: Responsible for the communication with the sync server, including batching, encryption, etc. Instantiated per data type.Syncer: The core logic that executes sync cycles (downloading updates via GetUpdates and uploading changes via Commit).components/sync/model/)This layer provides the bridge between sync and the individual features / data types (e.g., the Bookmark model). It includes the main APIs that individual features must integrate with in order to Sync (e.g. main data flow). It runs on the model sequence (often a backend/database sequence, but it can also be the UI thread in some cases).
DataTypeSyncBridge: An abstract interface that data type owners must implement. It handles merging local and remote data, and receiving and applying remote updates. It is responsible for storing its own sync metadata.SyncableService: A deprecated predecessor to DataTypeSyncBridge. Several data types still use it, but it must not be used for any new data types. Unlike DataTypeSyncBridge, it does not manage its own metadata directly; instead, it is wrapped in a SyncableServiceBasedBridge which uses DataTypeStore (LevelDB) for persistence. Historically, this metadata was managed by a central SQLite database called the “Directory”, which has since been removed.DataTypeLocalChangeProcessor: Used by the bridge to report local changes to sync.DataTypeStore: Offers a simple storage system (LevelDB-based) for features that don't have or need a specific storage system.components/sync/protocol/).proto) definitions used for communication between the client and the server. sync.proto is the main entry point, with various *_specifics.proto files defining the schema for each data type.SyncServiceImpl::Initialize() is called during browser startup.SyncAuthManager fetches an OAuth2 access token.SyncServiceImpl creates the SyncEngine.DataTypeManager begins a “configuration” cycle, determining which types should start.DataTypeController connects its DataTypeSyncBridge (model) to a DataTypeWorker (engine).DataTypeSyncBridge calls processor()->Put().DataTypeWorker is notified and “nudges” the SyncScheduler.Syncer performs a Commit request, sending the new data to the server.Syncer performs a GetUpdates request.DataTypeWorker and forwarded to the DataTypeSyncBridge.ApplyIncrementalSyncChanges().Chromium Sync operates across multiple threads to ensure the UI remains responsive and to isolate complex sync logic.
SyncService, DataTypeManager, SyncAuthManager, DataTypeController, SyncEngine.SyncEngineBackend, Syncer, SyncScheduler, DataTypeWorker.SequencedTaskRunner created via the base::ThreadPool (managed by SyncEngineFactoryImpl).DataTypeSyncBridge, DataTypeLocalChangeProcessor, and the actual data models (e.g., BookmarkModel).ProxyDataTypeControllerDelegate is used to hop from the UI thread to the model thread when they are different.SyncEngineImpl (on UI thread) posts tasks to SyncEngineBackend (on Sync thread).SyncEngineBackend uses a WeakPtr to SyncEngineImpl to post notifications (like OnEngineInitialized) back to the UI thread.DataTypeLocalChangeProcessor (on Model thread) communicates with DataTypeWorker (on Sync thread).DataTypeWorker posts tasks to DataTypeProcessor (which lives on the Model thread).