conradkoh
conradkoh8mo ago

Debugging slow performance of queries

I am encountering an issue where the queries seem to be running pretty fast on the server, but yet the client seems to have visible delays before the data is available. In the console for execution time, it tells me that it took 32ms to run the query on the server. Loading type on the client is roughly 3 - 6 seconds for each time a new query is run. Am I doing something wrong (based on how you see the queries are sent over the web socket)?
No description
14 Replies
conradkoh
conradkohOP8mo ago
Additional info - I am accessing convex from Singapore. I understand that convex primarily runs in us-east. Even with that factored in, I think 3 - 6 seconds still sounds unexpected and I'm probably doing something wrong.
conradkoh
conradkohOP8mo ago
here's another data point - it seems like it loads much faster when I do a hard refresh than if it came from another page in the app
conradkoh
conradkohOP8mo ago
the timing was added simply by recording the start time using useRef of a date, and then recording the time that the value was not undefined.
No description
conradkoh
conradkohOP8mo ago
yet another datapoint - i managed to get the timing down to ~ 400ms by avoiding using the react library / libraries and using the Convex Client directly.
No description
sshader
sshader8mo ago
Yeah agree that 3-6s sounds especially slow. Your investigation all makes sense. One thought is that the react client batches all query updates to make sure we're showing a consistent snapshot, so if you have some other query loaded that's slower, that could potentially explain the behavior. There's a verbose flag you can pass into the constructor of ConvexReactClient / ConvexClient that will print out some more info to the console which might give us a little more insight Side note: console.time is pretty neat -- you could probably do a console.time("myQuery") in a parent component and a console.timeLog("myQuery", queryValue) in your useEffect
conradkoh
conradkohOP8mo ago
could you share a little more about this:
One thought is that the react client batches all query updates to make sure we're showing a consistent snapshot, so if you have some other query loaded that's slower, that could potentially explain the behavior.
considering that all the testing I did in the videos had no state updates, it seems unlikely that there is some update is causing the queries to take longer. what you’re referring to should only happen if a mutation happens? also, what kind of consistency is expected on the client side? interested to know the pitfalls. i thought it would just subscribe to the query and receive updates. why would queries depend on each other? or is the library trying to preserve the order of updates provided by the server? thanks for sharing the timelog too! that’s a nice tip. for the example i showed though - it kinda shows that the component already began rendering correct? in this case i don’t think there can be any parent context preventing the render. the only case that remains is that the convex libraries are not sending the update as soon as they have the result, but rather waiting for something - maybe for consistency across all open queries. have you ever noticed such an issue so far though! or am i the only one? 🤔 i don’t feel like i’m doing anything super complex tbh. just simple queries and redirects between pages.
sshader
sshader8mo ago
it seems unlikely that there is some update is causing the queries to take longer. what you’re referring to should only happen if a mutation happens?
This is true provided that you're the only user and your queries don't depend on something like Date.now() which would cause them to not be cached.
what kind of consistency is expected on the client side?
Our React client provides all queries at a consistent snapshot -- so you can actually do things like joins on the client (e.g. load a user object with a list of team IDs in one useQuery, and load the teams in another useQuery). It does mean that we have to wait for both queries vs. giving results for one while the other is still loading, but generally the performance hit isn't noticeable and the benefit of not having to deal with inconsistency outweighs it.
have you ever noticed such an issue so far though! or am i the only one?
I haven't seen this before, so curious what's happening here. All your debugging steps so far make a lot of sense to me. I'd be happy to poke around a bit if you're willing to send over some of your code to me (here, or in a DM). My next step would probably be trying to determine whether the slowness is coming from the React client by looking at the timings of the messages sent by the server (which is what verbose prints out, but you can also look at websocket messages in the network tab -- ModifyQuerySet usually means subscribe / useQuery and Transition means query results were sent from the server)
conradkoh
conradkohOP8mo ago
I narrowed down the issue a little more. The issue happens if the ConvexReactClient is initialised more than one (e.g. due to a re-render). if I just simply move the initialisation outside of react - the problem goes away.
conradkoh
conradkohOP8mo ago
this fixed it for me.
No description
conradkoh
conradkohOP8mo ago
or this for simplicity. probably my bad since the constructor probably does connection work on init.
No description
Michal Srb
Michal Srb8mo ago
This seems to be a somewhat common issue when our quickstarts aren't followed correctly for setting up the ConvexReactClient. @conradkoh did you clone a template with this setup or have another reason to not put the client in the module scope?
conradkoh
conradkohOP8mo ago
@Michal Srb I am actually using remix, so passing variables to the client is slightly different from normal react. regarding the template - I actually set it up from scratch. at the point of writing there was no remix example haha. I contributed the remix example in this thread, and I see that it is also now part of the docs. https://discord.com/channels/1019350475847499849/1228500762217418832/1229593216253169675 but I suppose didn't follow my own example 😂 apparently I remembered to make sure it was only initialised once in the sample project but not my main project. anyways! wondering if maybe there can be some way to warn people of such a mistake, either by way of warning or outright throwing an exception. failing silently with 10x query response time seems like an unexpected behavior. better to catch in dev I think
Michal Srb
Michal Srb8mo ago
Agreed, you're not the first to run into this. Filing internally for us to have a look.
conradkoh
conradkohOP8mo ago
thank you!

Did you find this page helpful?