Is there a way to debug the speed of
Is there a way to debug the speed of queries being refreshed?
24 Replies
Is it better to issue one query that returns 10 docs, or query each of them individually?
I haven't benchmarked this myself, but I've thought a little about it. From a caching perspective, you're more likely to get a cache hit on individual docs. If you're using a websocket client like the React one, the requests and responses are all sharing the same websocket so I imagine it'd be pretty similar
Queries execution should be pretty fast. So don't think you will see it be measurabily slower if you fetch 10 instead of 1 document in a query.
We have graphs and logs that contain the execution speed for each query, which should help you figure out if query execution is getting slow.
It seems like actions are run serially?
Is that a free plan limitation?
or am I doing something wrong again?
Are these coming from multiple clients or from one client? If you await an action on the client before running the next one, it will be serial, but I'm guessing that's not what you're doing
one client
not awaiting
I am logging before and after on the client
that goes fast
but it can take a minute for all the other actions to run before it happens on the server
the actual runtime reported on the server is 8ms
so it is fast
but doesn't get scheduled for a long time
until all the other calls before it have finished
Chatted with folks. We do serialize execution from the client, even though actions from different clients are parallelized on the server. We added this before we supported actions, to provide guarantees to clients, especially around optimistic updates where you might be eagerly using optimistic data for a mutation. We're currently discussing the right parallelism strategy. Actions seem like an obvious one to parallelize. Until we add it, my suggestion would be to use the scheduler to fire each one off with
runAfter(0
.Yes, actions and mutation using a single web socket run in sequence. We did that in order to avoid mutation action failing due to implicit dependency but are revising this default behavior. In the meantime scheduling is a good workaround.
thank @Presley and @ian
is runAfter available on the browser?
No just in mutation / action. If you know the batch up front you can call a mutation which kicks each off. Otherwise it’d be one at time but they’d return almost immediately after scheduling
Are queries run serially too?
I have 50 of these cards on screen:

and the classification is updated asynchronously from an action
when I add one classification, it seems like all 50 queries might be run again, but sequentially
I dug in, it seems like they are run serially. But it was a major problem because I hadn't indexed
indexing solved it
Oh, yeah. Queries in a single web socket run serially too. Will be fixing this soon.
Is this related to anything I'm doing?

I'm getting a lot of the concurrency control failures
should I change my strategy?
or is this working as intended
Hmm... is that calling mutations from the React client? Do you mind sharing your instance?
In general, you should get optimistic concurrency control errors only if your mutations conflict with each other. Meaning one mutation is reading rows modified by another mutation. We only throw an error if we can't succeed a bunch of times.
I am calling an action that schedules a bunch of actions that all do mutations
perhaps an index would help?
I've had a bunch of random errors be resolved by indices
nope, i've already got indexes there
I've got an array of 50 URLs. I send an action saying "classify these 50 urls" Each one is then scheduled to runAfter 0 in a separate action which fetches the URL, classifies it, and mutates the entry back the db.
Oh, I'm not searching withIndex, I'm using filter
maybe that's the problem
yeah each of the mutations is depending on the whole table because of the filter (iirc), so if anything is modified in the table before they commit, they consider it a conflict. Using
withIndex
will let the mutation know it's only depending on that subset of the table.just got bit again by the serial nature of actions. I'm trying to use them from the browser, and they are slow when serial.
Yes, thanks for letting us know. We are discussing what the best way to allow you to run actions in parallel is (whether this is true by default or there is an opt-out).
Actions will now run in parallel!
https://blog.convex.dev/announcing-convex-0-14-0/
Convex News
Announcing Convex 0.14.0
Meet the brand new Convex Rust client! We’ve also open sourced the JS client, added schema validation, and more. 0.14.0 is the best version of Convex yet!
Ok, they should run in parallel now.