gwilliamnn
gwilliamnn2d ago

Unexpected query invalidation behavior — mutation waits for refetches across unrelated queries

Hi Convex team, I built a minimal reproduction and wanted to report the unexpected behavior I observed when calling a mutation that inserts a new message. Short summary - Mutation (DB write) completes quickly on the server (~0-30ms). - The client-side mutation promise does not resolve immediately — it waits while multiple queries refetch. - Convex revalidates all queries that touch the messages table (including a global getAllMessages query and per-period queries), even when the mutation’s data clearly only belongs to one query (e.g. "after cutoff"). - This causes the mutation to appear to take the combined refetch time on the frontend (in my test ~765ms), even though the backend mutation duration is ~0ms. Reproduction steps (repo included) 1. Clone the public test repo: https://github.com/williamneves/convex-lab 2. Run Convex dev: npx convex dev 3. Start the frontend (Bun/Next): bun run dev and open the UI. 4. Click “Seed Users” and “Seed 20 Messages”. 5. Set a cutoff date and click “Generate Before Message” or “Generate After Message”. 6. Watch the Timing Analysis card and Convex logs. Observed logs (snippet) - insertMessage logs (server):
[insertMessage] Mutation started for timestamp: 2025-08-19T04:11:32.820Z
[insertMessage] DB operation took 0ms
[insertMessage] Total mutation duration: 0ms
[insertMessage] Created message by Carol Williams

[insertMessage] Mutation started for timestamp: 2025-08-19T04:11:32.820Z
[insertMessage] DB operation took 0ms
[insertMessage] Total mutation duration: 0ms
[insertMessage] Created message by Carol Williams

— Convex shows the mutation finished in ~0–26ms in the server logs. - Queries revalidation logs (server):
[getMessagesByPeriod] Query invoked - before 2025-08-20T02:46:44.651Z
[getMessagesByPeriod] Artificial delay (computation loop)...
simpleDelay: 478ms
[getMessagesByPeriod] Retrieved 16 messages (before cutoff) in 0ms

[getMessagesByPeriod] Query invoked - after 2025-08-20T02:46:44.651Z
[getMessagesByPeriod] Artificial delay (computation loop)...
[getMessagesByPeriod] Retrieved 47 messages (after cutoff) in 0ms

[getAllMessages] Query invoked
[getAllMessages] Artificial delay (computation loop)...
simpleDelay: 478ms
[getAllMessages] Retrieved 63 messages in 0ms

[getMessagesByPeriod] Query invoked - before 2025-08-20T02:46:44.651Z
[getMessagesByPeriod] Artificial delay (computation loop)...
simpleDelay: 478ms
[getMessagesByPeriod] Retrieved 16 messages (before cutoff) in 0ms

[getMessagesByPeriod] Query invoked - after 2025-08-20T02:46:44.651Z
[getMessagesByPeriod] Artificial delay (computation loop)...
[getMessagesByPeriod] Retrieved 47 messages (after cutoff) in 0ms

[getAllMessages] Query invoked
[getAllMessages] Artificial delay (computation loop)...
simpleDelay: 478ms
[getAllMessages] Retrieved 63 messages in 0ms

- Frontend timing (UI card): Backend Mutation: 0ms, DB Op: 0ms, Frontend Total: 765ms — frontend waited ~765ms for mutation promise to resolve. Observed behavior summary - The mutation completes on the server almost instantly. - The client-side mutation promise resolves only after all related queries have re-fetched (including ones whose args should not match the new message). - getAllMessages is refetched even when the mutation only affects the “after” list — this results in unnecessary refetches and the user-perceived latency of the mutation includes query refetch time. Expected behavior - Mutation resolution should reflect the mutation’s server-side work (DB write + any server work). - Query invalidation/refetch should be triggered but should not block the mutation promise resolution unless explicitly configured to do so. - Ideally, invalidations should be scoped: only queries whose arguments indicate they could be affected by the mutation should be revalidated. Questions / requests 1. Is the Convex client intended to wait for query revalidations before resolving a mutation promise? If so, is this configurable (non-blocking refetch vs. blocking)? 2. Is there a way to scope invalidation so only queries with matching args are revalidated (so getAllMessages would not refetch if I inserted a message that only matched after)? 3. If current behavior is intentional, can you document when mutations block on refetches, and whether there’s a way to change that behavior (e.g., optimistic updates, fire-and-forget revalidation)? 4. I can provide the small test repo link, console logs, and server logs; what additional info would be most helpful for triage? Repository & logs - Repo: https://github.com/williamneves/convex-lab - I can attach full terminal logs and Convex function logs if useful.
GitHub
GitHub - williamneves/convex-lab
Contribute to williamneves/convex-lab development by creating an account on GitHub.
No description
No description
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?