A Server Action is a React Server Function that runs on the server and is invoked over the network. When you write one, the client receives a reference instead of the code, and each call becomes a POST request that can return both data and re-rendered UI in a single response.
Understanding Server Actions under the hood helps you predict when a page re-renders, why actions queue up behind each other, and why every action must validate its own input.
The client gets a reference, not the code
At build time, the use server directive tells the compiler to swap the function's implementation in client bundles for a reference: an action ID plus a dispatcher. The implementation stays on the server, which keeps secrets out of the browser and keeps the bundle smaller.
When the client calls the action, the dispatcher sends the action ID and the serialized arguments over POST. Actions use the POST method, and it is the only method that can invoke one.
The request goes to the URL of the page the visitor is on, not to a separate action route. Next.js tells the two apart by a header carrying the action ID, which is why actions have no public path you can document.
One action at a time
Next.js dispatches Server Actions one at a time per client. If a visitor triggers three actions quickly, the second waits for the first and the third waits for the second. This keeps the re-rendered server tree consistent with the action result that produced it.
The consequence is that you cannot use Promise.all to parallelize Server Actions from the client. For parallel work, do it inside a single action, or use a Route Handler for non-mutation requests.
This is a property of the client dispatcher, not of Server Functions themselves. On the server an action runs in its own request and can do anything an async function can do, including fetching several sources at once.
One response carries data and UI
When an action triggers an immediate revalidation, Next.js does the work in one HTTP request: it runs the action, then re-renders the current route server-side. The response is a Flight stream that carries the action's return value plus a newly rendered RSC Payload for the route.
The client sends the action ID and arguments, the server runs the action and re-renders the route, and the response carries both pieces. The client commits the RSC Payload as a navigation, so the page updates with no follow-up fetch.
That re-render is included when the action calls updateTag, revalidatePath, refresh, mutates cookies, or calls redirect. An action that does none of these returns only its value, and the route is not re-rendered.
The security boundary
Every action is reachable by anyone who can send the same POST, so Next.js enforces framework-level protections on top of your own. A CSRF check compares the request Origin to the Host, action bodies are capped at 1MB by default, and action references are encrypted at build time.
Unused Server Functions are stripped from client bundles so they have no public endpoint, and inline actions get their closure variables encrypted.
None of that is a substitute for application checks. Authenticate and authorize inside every action, and validate all input. A well-formed request can still target a row the caller does not own, so re-read ownership from the session rather than trusting an id the client supplied.
Progressive enhancement
Forms that call Server Actions submit even before JavaScript loads. In Server Components the form posts directly, while in Client Components the submissions queue until hydration and are prioritized for it.
After hydration the browser no longer does a full page submit. The same action therefore has two paths into it, one with JavaScript and one without, and both reach the same server code.
For the mutation pattern that sits on top of this, see how to mutate data with a Server Action. For the checks every action needs, see securing Server Actions. When an action appears to do nothing, see debugging Server Actions that silently do nothing.
Rune AI
Key Insights
- The client receives an action reference, never the server code.
- Actions are invoked only over POST requests.
- Next.js dispatches actions one at a time per client.
- One response carries the return value and a re-rendered RSC Payload.
- CSRF checks, body limits, and encryption guard the endpoint.
Frequently Asked Questions
Do Server Actions use POST or GET?
Why do my actions run one at a time?
What is in the action response?
Conclusion
A Server Action is a server function the client calls over POST through a reference. Next.js runs actions one at a time, returns data and re-rendered UI in a single Flight stream, and guards the endpoint with CSRF checks, size limits, and encrypted references.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.