Synchronization happens automatically in near-real-time (we don’t use a polling interval). Some methods exist to request historical messages to be synced to the device if they haven’t been synced already.

When your app is opened, the client SDKs will pull new data since the last sync from the server. Subsequent updates are pushed from the server to the client.

Offline Operations

You can continue to create conversations, send messages, change participants, etc… while offline, and we will automatically sync changes when a network connection is established.

For this to work, we must provide Conversation or Message objects without waiting for a response from the server. The example below shows that you can immediately use an object once created without waiting for confirmation from the server:

var c = client.createConversation({
    participants: ['UserA', 'UserB']
var m = c.createMessage('hello').send();

m.on('messages:sent', function() {
    view.rerenderMessage(m);('Message has been sent');

The above example will render the message “hello” immediately; once we are online and the message has been successfully sent, an event will trigger in case you want to show that is has been sent.

A more common approach is to listen on Query Events:

// A new unsynced Conversation
var c = client.createConversation({
    participants: ['UserA', 'UserB']

// A query on the Conversation that doesn't yet exist on the server
var query = client.createQuery({
    model: layer.Core.Query.Message,
    predicate: ' = \'' + + '\''

// Render any data added to the query
query.on('change', function(evt) {

// A new unsynced message in the unsynced conversation
var m = c.createMessage('hello').send();

The Conversation, Message and Query are all created. The Query will contain the new Message as soon as it has been locally created.

Once we are online, the Conversation and Message will be sent to the server, and new Messages in that Conversation will be added to the Query. New query events will fire as the Message is accepted by the server and its properties (recipientStatus, etc) are updated.


Persistence is only enabled if both the isTrustedDevice property is enabled, and the isPersistenceEnabled property is enabled:

var client = Layer.init({
    appId: myAppId,
    isTrustedDevice: true,
    isPersistenceEnabled: true

Persistence allows your web application to maintain a database (IndexedDB) of Message, Announcement and Conversation objects as well as unsent server requests. By keeping these in sync, its possible to load Conversation lists and Message lists from the database while offline… and to get a quicker list if on a slow network.

layer.Core.Query takes care of determining whether to load Conversation and Message objects from the local database or from the server. With persistence enabled, this behavior will transparently occur in the background, adding no complexity to your application.

Sync Manager Events

Layer provides a flexible notification system for notifying your app when changes have occurred in response to data being synced. The system is designed to be general purpose and alerts your application to the creation, update, or deletion of an object. This is an advanced feature and is intended for use in applications that require granular detail into everything occurring within Layer.

In the Web SDK, all operations go through a synchronization manager and then on to Layer servers. You can subscribe to events from the synchronization manager if you want to receive detailed notifications:

    "sync:add": function(event) {
        var request = event.request;
        var target =;
        console.log(target.toString() + ' has a ' + event.op + ' operation added to the sync queue');
    'sync:success': function(event) {
        var request = event.request;
        var target =;
        console.log(target.toString() + ' has completed a ' + request.op + ' operation');
    'sync:error': function(event) {
        var request = event.request;
        var target =;
        console.log(target.toString() + ' has failed a ' + request.op + ' operation');

For more details, see the SyncManager documentation.

Sync state

Message objects are subclasses of Syncable (as are Conversation and Identity objects), which provides some information about the sync state of the object.

  • isNew(): The object was just created, and only exists in memory on the client.
  • isSaving(): The object was recently created, and being sent to the server.
  • isSaved(): The object exists on both server and client though they may be out of sync.
  • isSynced(): The object exists on both client and server and is in sync.
  • isLoading: The object exists on server; being downloaded to the client.
Metadata Push notifications