nibab
nibab3mo ago

n1bab's Thread

im not sure if i should go to the support channel with this (please send me there if so) but im trying to understand more about the latency associated with httpactions specifically. mutations/queries are always under 250ms for me, but somehow httpActions themselves can take up to 3.5secs (for the same call). ie: Dec 24, 06:42:17 H POST https://rapid-egret-XXXX.convex.site/createRelationships 200 3.5s Dec 24, 06:42:17 M relationships:insert success 250ms what is it thats happening in there outside of data deserialization ? is there anything i can do to speed this up ?
10 Replies
convex-threads
convex-threads3mo ago
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. If this is a support-related question, please create a post in #support-community. If not, carry on! Thanks!
ampp
ampp3mo ago
There are quite a few factors but if you are using 'use node' for the action it will be subject to a cold start. Generally i notice the first time after I've deployed the functions generally return slowly. 3.5s is a bit suspicious if it is a consistent number but all depends on all that is happening.
lee
lee3mo ago
http actions can't be "use node" so the extra latency is unexpected. What is the http action doing?
nibab
nibabOP3mo ago
deserializing an object that has 4000 documents in it of the shape: "sheet_id": 123 "row_id": 123 i am actually noticing relatively similar latency just invoking the mutation from my python client too. i switched over thinking that would make a difference, but it actually looks slower from the client's perspective. in the convex logs im seeing 500ms for the mutation, from the client i see roughly 2 secs.
lee
lee3mo ago
In http actions, your function starts running before the request data is parsed or even received (this allows you to stream request.body). So if you have a slow internet connection, the transmission latency will show up in the http action's runtime. On the other hand, mutations parse args before running your function.
nibab
nibabOP3mo ago
im at 70Mbps upload. 3 seconds seems like a pretty bid difference between the start of request.body and the end. its a 300kb payload. now to be fair...calling the mutation instead of the http action takes just as long.
lee
lee3mo ago
Yeah so it's likely either transmission latency or parsing time. Either way, the http action's latency in the dashboard would count it while the mutation's wouldn't. But measuring from the client would always count it. 3 seconds does seem like a lot, but 300kb of json is pretty chonky You can try using console.time() to measure how long the await request.json() is taking
nibab
nibabOP3mo ago
request.json() is roughly 50ms. using conosle.time on the mutation itself is 3s. it seems that the mutation iteslf is slow. running the same payload without the mutation is 100ms. here is my function fwiw:
export const createRelationshipFromHttp = httpAction(async (ctx, req) => {
console.time("JSON Parse"); // Start timing

const { relationships, apiKey } = await req.json();

console.timeEnd("JSON Parse"); // End timing and log the duration

const pairs = [];
for (const relationship of relationships) {
pairs.push({
sheet_id: relationship.sheet_id as Id<"sheet">,
row_id: relationship.row_id,
row_number: relationship.row_number
})
}

console.time("Mutation start"); // Start timing

await ctx.runMutation(api.relationships.insert, { pairs: pairs, apiKey: apiKey });

console.timeEnd("Mutation start"); // end timing


return new Response("Relationships created", { status: 200 });
})
export const createRelationshipFromHttp = httpAction(async (ctx, req) => {
console.time("JSON Parse"); // Start timing

const { relationships, apiKey } = await req.json();

console.timeEnd("JSON Parse"); // End timing and log the duration

const pairs = [];
for (const relationship of relationships) {
pairs.push({
sheet_id: relationship.sheet_id as Id<"sheet">,
row_id: relationship.row_id,
row_number: relationship.row_number
})
}

console.time("Mutation start"); // Start timing

await ctx.runMutation(api.relationships.insert, { pairs: pairs, apiKey: apiKey });

console.timeEnd("Mutation start"); // end timing


return new Response("Relationships created", { status: 200 });
})
lee
lee3mo ago
Gotcha good deduction. Then it's probably the commit time, writing the data to the underlying persistence (mysql). That happens after the mutation's function runs, but before it returns to the action or to the client. I'm not sure why it would take so long, although 300kb is pretty big so it could just be the total size
nibab
nibabOP3mo ago
i keep switching back and forth between calling the http action and the mutation directly using the python client. whats curious is that the logs show a mutation time of 700ms when called directly, yet when measuring the time from within the http action using console.time("Mutation start"), i get 4 seconds.

Did you find this page helpful?