                 if err
                     cb(err)
                 else
-                    @_process_updates updates, (err, new_updates) =>
+                    @_process_updates updates, squash_thresh, (err, new_updates) =>
                         # ignore err, since it would be in writing back
                         cb(undefined, new_updates)
 
-    _process_updates: (updates, cb) =>
+    _process_updates: (updates, squash_thresh, cb) =>
         #
         # updates is a list of {string_id:?,timestamp:?,patch:?,is_first:?} objects, where
         #

            # not watching for anything
            retry(interval); return

        @read_updates_from_db misc.keys(@strings), TIMESTAMP_OVERLAP, (err, new_updates) =>
            if err
                retry(interval)
            else
                if new_updates
                    # something new -- poll again soon
                    retry(0)
                else
                    # nothing new -- try again after further exponential decay
                    retry(interval)

    sync: (cb) =>
        @_call_with_lock(@_write_updates_to_db, cb)

        @clients = {}
        @head = ''

    new_browser_client: (opts) =>
        opts = defaults opts,
            session_id     : required
            push_to_client : required
            cb             : required
        client = new SyncStringBrowser(@, opts.session_id, opts.push_to_client)
        client.id = opts.session_id
        @clients[opts.session_id] = client
        opts.cb(undefined, client)

    new_in_memory_client: (opts) =>
        opts = defaults opts,
            session_id    : required
            cb            : required
        # Used so that the hub itself (the process where this code is running)
        # can modify this SynchronizedString, rather than just remote clients.
        client = new diffsync.DiffSync(doc:@head)
        client.id = opts.session_id
        client.sync = (cb) =>
            client.shadow    = client.live
            client.last_sync = client.live
            client.emit('sync')
            @sync()
            cb?()
        @clients[opts.session_id] = client
        opts.cb(undefined, client)

    new_database_client: (opts) =>
        opts = defaults opts,
            session_id    : required
            squash_thresh : DB_PATCH_SQUASH_THRESH
            cb            : required
        # Used for synchronizing/persisting the string using the database, so
        # it gets sync'd across all hubs (across data centers).
        syncstring_db.get_string
            string_id     : @string_id
            squash_thresh : opts.squash_thresh
            cb            : (err, client) =>
                if err
                    opts.cb(err)
                else
                    @clients[opts.session_id] = client
                    opts.cb(undefined, client)

    sync: (cb) =>
        @_call_with_lock(@_sync, cb)
