realm / realm-kotlin

Kotlin Multiplatform and Android SDK for the Realm Mobile Database: Build Better Apps Faster.
Apache License 2.0
880 stars 52 forks source link

Atlas Device sync - very high latency 200 to 400 ms on read and write #1708

Closed mohamed00736 closed 2 months ago

mohamed00736 commented 3 months ago

we are using this realm kotlin with Atlas device sync , we followed the tutorial made by the device sync team on mongo db website , the sync and everything works well , but the unusual thing is that we noticed the latency is very high in the mongodb logs , is always above 200 ms to 400 ms , whether its a read or a write or even update , what makes me wonder is a friend of mine is using swift sdk to make an ios app ( same as mine ) and latency on his side is about 40 ms only , and that's a huge difference , u can see the mongo db logs below :

Screenshot 2024-03-24 at 14 46 37

you will find below an example function that creates a trip document for example ,

we tried also to make the document schema variable names as short as possible to reduce the document size but the latency stayed the same between 200 ms to 400 ms. ,,

we also tried the todo app template provided by mongo team and it gave us same latency , so we are wondering if this is related to the kotlin sdk ,

as a final try , we tried the java sdk and same results .

**realm version : 1.13.0

Android Studio version: Android Studio Iguana | 2023.2.1 Android Build Tools version: 8.3 Gradle version: 8.3**

suspend fun createTrip(pickup: String, dropoff: String)  : Trip {

        val tripReq = Trip().apply {
            pickUAd = pickup
            dropOAd = dropoff
            client = "Hakim"
        }

        if (user != null) {
            CoroutineScope(Dispatchers.IO).launch {
                realm.write {
                    try {
                        copyToRealm(tripReq)
                    } catch (e: Exception) {
                        Log.d("MongoRepository", e.message.toString())
                    }
                }

            }
        }

        return  tripReq
    },,
sync-by-unito[bot] commented 3 months ago

➤ PM Bot commented:

Jira ticket: RKOTLIN-1060

ehocine commented 3 months ago

I am facing the same high latency issue as well in my project, here is what I have done:

object RepositoryImpl : Repository {
    private val app = App.create(APP_ID)
    val user = app.currentUser
    lateinit var realm: Realm

    fun initialize() {
        configureCollections()
    }

    override fun configureCollections() {
        if (user != null) {
            val config = SyncConfiguration.Builder(
                user,
                setOf(Driver::class, Trip::class)
            )
                .initialSubscriptions { sub ->
                    add(query = sub.query<Driver>(query = "_id == $0", ObjectId(user.id)))
                    add(query = sub.query<Trip>(query = "_id == $0", ObjectId(user.id)))  
                }
                .errorHandler { session, error ->
                    Log.e("syncError", "syncError", error)

                }
                .build()
            realm = Realm.open(config)
        }
    }

    override suspend fun tripAction(trip: Trip, action: TripStatus) {
        if (user != null) {
            realm.write {
                try {
                    findLatest(trip)?.let {
                        it.apply {
                            status = action
                            if (action == TripStatus.Accepted) dID = user.id
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }
}

with latency ranging from 300ms to up to 600 ms while the iOS SDK for the same data and operation is giving a very good latency ~30ms

kneth commented 2 months ago

From the documentation of write(): "The write transaction always represent the latest version of data in the Realm file"

Do you need findLatest()? Does it have an effect if you replace findLatest(trip) with trip?

nirinchev commented 2 months ago

Is your friend, who's working on the iOS app developing against the same Atlas App Services application? If you can share links to some logs showing low latency as well as some logs showing high latency, we could be able to check and see if there's any clues there.

mohamed00736 commented 2 months ago

Hi @nirinchev , as you see here in the first screenshot , the logs of the android app using kotlin its always around 400 ms

Screenshot 2024-04-08 at 09 21 29

now in this second screenshot the ios app logs write transaction at the bottom are between 36 and 46 and thats 10x times lower , which made us wonder why ,

ji

for the ios we are using the free plan ,, in the android app we are using M30 cluster

ehocine commented 2 months ago

Hi @kneth, thanks for the reply. As for using findLatest(trip), when I try to update the object without using findLatest I got this error saying I cannot modity the object:

Screenshot 2024-04-08 at 9 49 03 AM

In the documentation,, it says that frozen objects must be first converted to live objects using findLatest.

nirinchev commented 2 months ago

So just to confirm, those two apps (iOS and Android) are synchronizing with two different Atlas App Services applications? If that's the case, then the most likely reason is how they're setup on the backend. For optimal results with sync, you want a local deployment model and make sure that the app services application is colocated with the Atlas cluster.

mohamed00736 commented 2 months ago

the 2 apps , have 3 simple collections , Trip , Rider and Driver , for the android app we have chosen the closest region , u can see screenshot below :

Screenshot 2024-04-08 at 10 42 00
nirinchev commented 2 months ago

Is your Atlas cluster also running on AWS in Frankfurt?

mohamed00736 commented 2 months ago

GCP Belgium (europe-west1)

M30 (General)

Screenshot 2024-04-08 at 10 59 55
ianpward commented 2 months ago

The latency is almost certainly due because your Device Sync app servers are not in the same region as your Atlas cluster. If you place them in the same region you will greatly improve your latency.

mohamed00736 commented 2 months ago

i think you are right , we made device sync in same region as atlas cluster , the layency is now between 30 and 60 as you see in pic below , and this is great , thank you for your collaboration @ianpward , @nirinchev , @kneth

Screenshot 2024-04-14 at 14 34 11