Next.js Discord

Discord Forum

Server actions taking too long to start executing... ?

Unanswered
Cape lion posted this in #help-forum
Open in Discord
Cape lionOP
Hi All,

I'm using NextJS 14 in dev mode, I'm noticing that when I call a react server action, it executes slowly.

I traced this to about a 250-300msec delay from when the function is invoked in my client component until the function begins executing....

In my client component....
import { updateFilename } from '@/actions'
// ...
const handleBlur = async () {
  const tstart = Date.now(); 
  await updateFilename({ file_id, name: e.target.value, go: tstart })
  const tend = Date.now()
  console.log(tend-tstart) // this takes about 500 msec.
}


In my server action...
export async function updateFilename({ file_id, name, go }) {
    const tstart = Date.now()
    console.log(tstart-go) // THIS IS A GOOD 250-300 MSEC

    // access database...
    // mutate data
    // revalidate path
}


I'm using RSC for rendering all my entry pages and want to mutate that data using server actions with revalidation...

Is this just due to it being used in dev mode ?

Or is this lag an inherent issue with server actions ?

Thanks!

8 Replies

I'm suspecting it's something to do with how you're accessing the database.
@Marchy I'm suspecting it's something to do with how you're accessing the database.
Cape lionOP
Hi, the full server action '@/actions/index.js' is as follows. I'm only initializing the database client after the function is invoked, and so I had thought this was not the reason for the delay.
'use server'
 
import { revalidatePath, revalidateTag } from 'next/cache'

import { auth } from '@clerk/nextjs';
import { neon, neonConfig } from '@neondatabase/serverless';
neonConfig.fetchConnectionCache = true;

import { drizzle } from 'drizzle-orm/neon-http';
import { and, eq } from 'drizzle-orm';
import { file } from '@/drizzle/schema';
export async function updateFilename({ file_id, name, go }) {
  try {

    const tstart = Date.now()
    console.log(tstart-go)

    // Authenticate
    const { sessionClaims } = auth()
    const owner_id = sessionClaims?.user_id;

    var tend = Date.now()

    // Validate
    if(!file_id || !name) return { isError: true, message: 'Failed to update' }
    if(name.length>255) return { isError: true, message: 'Name cannot exceed 255 characters' }

    const client = neon(process.env.NEON_DB_URL)
    const db = drizzle(client);

    tend = Date.now()

    const res = await db.update(file).set({ name }).where(and(
      eq(file.id, file_id),
      eq(file.owner_id, owner_id),
    )).returning()

    console.log(res)

    revalidatePath(`/docs/folders/${file_id}`)
    revalidatePath(`/docs/files/${file_id}`)

    tend = Date.now()
    console.log('Completed in', tend-tstart, 'msec')

    return { isSuccess: true, data: res }

  }
  catch (e) {
    console.log(e)
    return { isError: true, message: 'Failed to update' }
  }
}
Ah, yeah. You shouldn't need to create a new client/connection for every server action.

There's an example here
https://github.com/vercel/examples/blob/main/storage/postgres-drizzle/lib/drizzle.ts
There's also a guide here for Prisma - drizzle should be similar with using globalThis
https://www.prisma.io/docs/guides/other/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices
Cape lionOP
I tried that but without success. It seems more to do with the time it takes the browser to take the formData and submit the form. Here is a barebones example where I only record the time the button is clicked in the frontend and the time recorded by the server action.

Client code is...
"use client"

import { myAction } from "@/actions";

function TestForm() {

  return (
    <form action={myAction}>
      <button type="submit" onClick={()=>console.log(Date.now())}>Test...</button>
    </form>
  )
}

export default TestForm


and the server action is...

export async function myAction(prevState, formData) {

  const now = Date.now()
  console.log(now)

  return true

}
Cape lionOP
Thanks Marchy, I got it to work as expected after starting a new Next project. Before, I had only upgraded to 14 (from 13.5x). I see now that also the server actions are logging to the browser console instead of the terminal.