How does realm determine if something has changed (has consequences for performance)

Hi to cut to the chase the performance of our react native app is terrible and its down to how we are using realm.

We are leaning heavily on adding listeners to collections to update the UX, and these listeners fire all too frequently, and with seemingly massive amounts of changes reported.

After looking into it, I think this is due to my misunderstanding of how realm works WRT the schema and modifications to entities - Ive done some tests to confirm my suspicions, but Id really appreciate some clarity around the issue so that I can work out a proper solution.

The main issue is that our schema has an entity type that is commonly related to a bunch of other entities. Ill give an example.

lets say we have many Pets, Toys & Books. Also a couple of Childs.

This relationship is common: Pet.child Toy.child Book.child

Such that, if I update a specific Child, I am likely to trigger an update in many Pets, Toys & Books that have a relationship with that Child

So this is one source of inefficiency - am I right so far?

If each item had a ‘foreign key’ type of reference to its Child owner, or the Child itself had a collection of owned items, then this disproportionate update would not occur?

Second source of inefficiency is how our app creates/updates entities from the backend. We use a ‘PUT’ type of operation, rather than a ‘PATCH’. That is, the schema is almost identical to the structure of the entities coming from the backend. Our Pet API does return a Pet with a Child relationship. We know that something about the Pet has changed, but we dont know what - so we PUT the entire Pet and Child when we update the database, rather than writing only a specific attribute that has changed.

example. Lets say the backend sends us a modified Pet , which is owned by John. The Pets colour has changed for some reason. We write the new Pet and Pet.child to the DB. Realm considers John has been changed because we are writing it, and now every Pet, Toy and Book owner by John is also changed, even though we just updated a single Pets colour.

This is what I observe from our collection listeners firing and the nature of the changes they are reporting

The upshot is that whenever something changes it seems that many other types things are updated as a consequence, even though they havent changed.

Lastly, another thing we are doing which Id like clarification about is when the backend does not supply the Child belonging to a Pet with the Pet, but only the Child’s id…

To be clear, our example Schema looks like this:

Pet {
id: string
name: string,
colour: string,
owner: Child
}

Child {
id: string,
name: string
}

And in some circumstances we would recieve this from the backend:

Pet.id = 3, Pet.name = fido, pet.colour=brown, owner.id = 9

And we would write this to the DB

Pet = {
id: 3,
name: fido,
colour: brown,
owner: {
id:9
}
}

which will write any changes to Pet, and simply maintain the 1:1 relationship with the Child , without writing any changes to the Child itself.

In this situation, I believe that Realm still considers the Child to have been modified? Is this correct?

phew, thats enough for now. I can anticipate that some comments will be, why is your schema like that? In part its because it mirrors the structure of entities coming to us from the backend, and … we didnt know any better. And also having the relationship in the Pet/Child/Toy is simple and useful. If you are dealing with a list of Books, finding the owner is easy. It seems natural to structure the schema this way.

Thanks for any help, confirmation, discussoin this generates.

Steve

Still experimenting.

Ive noticed that if I load a managed entity from realm, dont change anything , and immediately write it back, I get single change recorded - one modification of that entitty, as you would expect.

However, our app doesnt work like that - it makes a rest call to our backend to sync any changes that have occured recently. So we receive the changed entity, marshall it into a format compatible with our schema, and write it to the DB with a create/modified flag set to update it.

When we do this, Realm considers everything about the entity has changed, and thats when the massive amount of changes propagate through, due to the relationships

How should we approach this?