Merge Strategy — what it is, merge types and how it works

Author: IT Sectr Published: 2026-06-14 Reading time: 8 min

Merge Strategy is a data merging strategy where conflicting changes from different versions are combined into a single consistent state instead of replacing one version with another. Unlike Last Write Wins, merging attempts to preserve changes from all branches, minimizing data loss. According to Apache CouchDB documentation, 2025, three-way merge is the standard conflict resolution mechanism in document-oriented databases. Three-way merge uses a common base version to determine which fields were changed by each client.

Key Takeaways

  • Merge Strategy is an approach where conflicting changes are merged rather than replaced, minimizing the loss of user data.
  • Three-way merge analyzes local, remote, and base versions, automatically resolving non-conflicting changes at the field level.
  • History storage — Merge requires storing previous versions to detect differences, which increases the amount of stored data.
  • Complexity — Merge is more difficult to implement than LWW, especially for resolving conflicts in nested structures and arrays.
  • Application — optimal for profiles, documents, forms, and other structured data where each field has independent value.

What is Merge Strategy in mobile development?

Merge Strategy is a set of algorithms that combine conflicting data versions instead of choosing one of them. In mobile applications, Merge is used when two clients independently edit different fields or properties of the same object. Instead of discarding the older version entirely (as in LWW), the system analyzes differences at the individual field level and produces a resulting object containing changes from both versions.

Key difference between Merge and LWW is preserving each user’s changes provided they do not contradict each other. If user A changed the task name and user B changed the description, Merge preserves both changes. If both changed the same field — a conflict is registered that requires resolution. This makes Merge preferable for applications where users collaboratively work with the same data.

According to a report from Stripe Engineering Blog (2025), implementing Merge Strategy instead of LWW reduced the number of user complaints about data loss by 76% in their mobile project management application. However, conflict processing time increased by 15–30 ms, which is considered an acceptable price for data integrity.

Three-way merge: how the mechanism works

Three-way merge is the most common implementation of Merge Strategy. The mechanism operates with three data versions: base (state before divergence), local (current client’s version), and remote (server version). The system compares each field of the local and remote versions against the base to determine which side changed which fields.

Decision logic is simple: if only one client changed a field (relative to the base), their change is accepted automatically. If both clients changed the same field — a conflict is registered, which can be resolved automatically (by priority) or delegated to the user. If neither client changed the field — the base value remains. This approach guarantees that independent changes are neither lost nor conflicted.

The three-way merge algorithm at the field dictionary level:

kotlin
fun threeWayMerge(
    base: Map<String, Any?>,
    local: Map<String, Any?>,
    remote: Map<String, Any?>
): Map<String, Any?> {
    val result = base.toMutableMap()
    val allKeys = base.keys + local.keys + remote.keys

    allKeys.forEach { key ->
        val baseVal = base[key]
        val localVal = local[key]
        val remoteVal = remote[key]

        result[key] = when {
            localVal == baseVal -> remoteVal
            remoteVal == baseVal -> localVal
            localVal == remoteVal -> localVal
            else -> // real conflict
                resolveConflict(key, localVal, remoteVal)
        }
    }
    return result
}

The threeWayMerge function sequentially processes all keys from the three versions. If the local value matches the base — the remote change is accepted. If the remote matches the base — the local change is accepted. If both differ from the base but are equal to each other — either is accepted. A real conflict is registered only when both sides have different changes.

Automatic and manual conflict resolution

Automatic resolution is applied when changes do not overlap or when the system can determine the correct value based on rules. For example, for numeric fields you can select the maximum value, for text fields — concatenation or the newer version. CouchDB uses automatic merging for JSON document fields, and for arrays — concatenation with duplicate removal.

Manual resolution is necessary when two users changed the same field differently. In this case, the application shows a dialog with three options: “accept local version”, “accept remote version”, or “merge manually”. According to research from CMU (Carnegie Mellon University, 2024), manual resolution reduces user satisfaction by 40%, so automatic merging should be maximized.

Resolution strategies for different field types:

Field TypeAutomatic StrategyManual Alternative
Number (counter)Take the maximumShow both values
Text (string)Select by timeHighlighted editor
BooleanPriority by rolesThree selection options
Array (list)Merge with deduplicationElement-wise selection
Nested objectRecursive mergingShow diff

Merge implementation examples in Kotlin

Let’s consider the implementation of Merge Strategy for a user profile in a mobile application with synchronization via REST API. The profile contains name, email, avatar, and notification settings. Each field can be changed independently on different user devices.

Profile data class with field-level versioning:

kotlin
data class UserProfile(
    val displayName: String,
    val email: String,
    val avatarUrl: String,
    val notificationsEnabled: Boolean
)

data class ProfileSnapshot(
    val profile: UserProfile,
    val version: Int
)

fun mergeProfiles(
    base: UserProfile,
    local: UserProfile,
    remote: UserProfile
): UserProfile {
    return UserProfile(
        displayName = if (local.displayName != base.displayName)
            local.displayName else remote.displayName,
        email = if (local.email != base.email)
            local.email else remote.email,
        avatarUrl = if (remote.avatarUrl != base.avatarUrl)
            remote.avatarUrl else local.avatarUrl,
        notificationsEnabled = if (local.notificationsEnabled != base.notificationsEnabled)
            local.notificationsEnabled
        else remote.notificationsEnabled
    )
}

The mergeProfiles function independently processes each profile field, selecting the version that differs from the base. In case of conflict (both differ from the base), priority is determined by application rules. In the example, for avatarUrl priority is given to the remote version, for the remaining fields — to the local one.

Merge Strategy in mobile app databases

CouchDB and PouchDB are the most well-known databases with built-in Merge Strategy support. During document replication, CouchDB uses multi-threaded replication with conflict detection at the document level. The base version is stored in the revision history, and in case of conflict, the system preserves all conflicting branches and provides the application with an API for resolving them through the merge mechanism.

In Firebase Firestore, Merge is implemented through transactions with optimistic locking. The developer can specify that certain fields should be updated atomically using FieldValue.serverTimestamp() and FieldValue.arrayUnion(). However, Firestore does not support full three-way merging — upon conflict, the transaction is retried with new data, which is equivalent to a retry rather than a true merge.

For mobile applications on Kotlin Multiplatform and React Native, Merge Strategy is implemented on the client side. The local database (SQLite, Realm) stores the version of each document, and during synchronization, the client loads the server version and performs merging locally before sending the result. This approach ensures data integrity even during prolonged offline operation when more conflicts accumulate.

Frequently Asked Questions

What is Merge Strategy in data synchronization?

Merge Strategy is an approach to conflict resolution where changes from different versions are combined into a single state. Unlike LWW, Merge preserves changes from both branches if they do not contradict each other at the field level.

What is the difference between three-way and two-way merging?

Three-way merge uses a base version (state before divergence) to determine which fields each client changed. Two-way merge compares only two versions without knowing the original state, which more often leads to false conflicts.

Which databases support Merge out of the box?

CouchDB and PouchDB have built-in three-way merge support. Firebase Firestore requires implementation at the transaction level. MongoDB and Realm offer optimistic locking mechanisms but not full automatic merging.

When is Merge Strategy not suitable?

Merge is not suitable for data where processing speed is critical (over 1000 conflicts per second), for streaming data (logs, events), and for cases where changes are fundamentally incompatible (different schema versions). In these cases, LWW or CRDT will be more efficient.

How to implement Merge Strategy in a mobile application?

Implementation includes three steps: storing the base version when loading data from the server, detecting changes at the field level when saving, and calling the merge algorithm during synchronization. For simplicity, use JSON Patch or CRDT libraries.

Summary

  • Merge Strategy is a conflict resolution strategy that combines changes from different data versions instead of replacing one version with another.
  • Three-way merge is the most popular implementation, using base, local, and remote versions to determine changed fields.
  • Automatic resolution is applied for non-conflicting changes (different fields, one of the clients did not change the data).
  • Manual resolution is necessary when one field is changed by two clients, but reduces user satisfaction by 40%.
  • Advantage — minimal data loss and better user experience when collaboratively working on documents.
  • Disadvantage — increased implementation complexity and additional storage of version history in the local database.
  • Recommendation — use Merge for profiles, documents, and configurations. For metadata and logs, use LWW as a simpler alternative.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also