vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.86k stars 26.97k forks source link

Parallel server action calls #69265

Open yehonatanyosefi opened 2 months ago

yehonatanyosefi commented 2 months ago

Link to the code that reproduces this issue

https://github.com/yehonatanyosefi/parallel-routes-example

To Reproduce

  1. start the application
  2. click start button
  3. see console logs come out as ABAB on the server side with two post requests, and on the client side it taking 2 seconds instead of one even though using promise.all

Current vs. Expected behavior

Current behavior of nextjs server actions are they are executed in sequential fashion, however there is no flag or option or a config to let them be executed in parallel. Causing them to block some ux. For example for ai image generation, you'd have to wait for the last call to finish before making your next one, causing you to need to wait over 15 seconds before you can even generate more images instead of the Expected behavior of being able to send them in parallel and stream in finished generations by awaiting them.

In the example I sent you can see even though I used Promise.all on 2 promises that each take a second that should be expected take only 1 second together but because of the sequential nature the current behavior is it takes 2.

Provide environment information

when hosted on vercel it happens, locally it happens too:
Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 32393
  Available CPU cores: 20
Binaries:
  Node: 20.10.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.0.0-canary.128 // Latest available version is detected (15.0.0-canary.128).
  eslint-config-next: N/A
  react: 19.0.0-rc-eb3ad065-20240822
  react-dom: 19.0.0-rc-eb3ad065-20240822
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

create-next-app, Parallel & Intercepting Routes, Performance

Which stage(s) are affected? (Select all that apply)

next dev (local), Vercel (Deployed)

Additional context

Edit: https://x.com/cramforce/status/1733240566954230063 Above's link to a reply by Vercel's CTO agreeing it should have control if we want it parallel

simonri commented 2 months ago

Server Actions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing Server Actions typically process one action at a time and do not have a way to cache the return value.

https://react.dev/reference/rsc/use-server#caveats

yehonatanyosefi commented 2 months ago

Server Actions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing Server Actions typically process one action at a time and do not have a way to cache the return value.

https://react.dev/reference/rsc/use-server#caveats

https://x.com/cramforce/status/1733240566954230063 Your CTO agrees with me

simonri commented 2 months ago

The docs mention that only sequential server action calls are supported, so running them in parallel shouldn't be expected.

musjj commented 2 months ago

I would also agree that it would be very cool to use server actions as an RPC system.

There's this other thread: https://github.com/vercel/next.js/issues/69265 that mentions:

I can confirm this is by design.

Why? To prevent things such as inconsistent states from navigation aborting, client fetching, etc.

But I'm not exactly sure what this means. If a server action is pure (only queries for data), there shouldn't be a problem right? If so, it would be nice if there is a way to mark a server action as a "query" and allow it to run parallel to other queries.

erikslatter commented 1 month ago

I've been using server actions for queries and it's been a great experience having type safety between frontend and backend, but the sequential nature of them is starting to get slowwww. Would love an option to run them in parallel. Has anyone heard news on this since the CTO's tweet in December 2023?

johnmangan commented 4 weeks ago

Similarly, we've used Server Actions for data fetching due to their RPC nature w/ built-in type-safety.

Additional advantages over standard Route Handlers is abstraction away some of the code organization decisions. We don't have to place the Route Handler's route.ts file in a specific place nor consider the endpoint route/path we need to fetch to call it. We don't have to rethink route-based middleware auth and permissions for the call the way we do with adding a new route.ts file. Server Actions take on the same permissions as the page that calls them. Simple.

I think there's definitely a place for full Route Handlers. I also can concede that there is other functionality that benefits from sequential execution of Server Actions, which some projects may want to keep.

It would be nice, however, to either tag a Server Action to not run sequentially or to create a new feature in NextJS with similar syntax to Server Actions but runs in parallel the way Route Handlers do (without requiring all the boilerplate code & code organization that Route Handlers require). Even if this new feature doesn't support the existing features that require Server Actions to remain sequentially executed.

Aside: For my team's use-case, I could even understand a decision to limit it to just GET requests, as opposed to Server Action POST requests, and say it can be used for data fetching and is not suggested for mutations. Basically the opposite of intended use for Server Actions, while maintaining the simplicity and elegant DX of Server Actions.

nikshepsvn commented 4 weeks ago

yes please +1, make this an option or configurable if the default is supposed to be sequential, will be a huge boost to application experience and DX