Back to Server-Side Performance

Use after() for Non-Blocking Operations

serverasynclogginganalyticsside-effects
28.0k🕒 2026-06-10Source ↗

Install this skill

npx skills add vercel-labs/agent-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The after() function in Next.js provides a controlled method for offloading secondary tasks that occur after the primary HTTP response cycle completes. By moving auxiliary logic outside the request-response stream, you eliminate unnecessary wait times for the end user. This prevents tasks like telemetry gathering or external API notifications from bottlenecking server performance. When you wrap asynchronous functions inside after(), the server finishes its primary commitment to the client while the remaining operations finish in a background execution context. This mechanism ensures that user interaction remains fast even if secondary background processes experience latency or require extra processing time. It is an essential pattern for maintaining high performance in Route Handlers and Server Actions where maintaining low latency is critical for user satisfaction and core web vital scores.

When to Use This Skill

  • Recording telemetry and event analytics for user traffic
  • Sending push notifications or transactional emails after status updates
  • Triggering secondary audit logs in security-sensitive systems
  • Purging stale cache entries for downstream consistency

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • Make this background task non-blocking
  • How to run code after returning a response in Next.js
  • Avoid blocking the API response for analytics
  • Execute logic after the server finishes sending
  • Speed up my route handler by offloading tasks

What this skill does

  • Defers execution until the response stream terminates
  • Prevents secondary tasks from blocking HTTP delivery
  • Maintains scope for async background operations
  • Executes code independently of response success or failure
  • Functions across Server Components and API endpoints

When not to use it

  • Critical tasks required before the user sees a success message
  • Operations that must be guaranteed to finish synchronously for data integrity

Example workflow

  1. Receive incoming client request in a Route Handler
  2. Execute primary database mutation or resource update
  3. Declare the after() block for secondary background tasks
  4. Return the 200 OK status to the client immediately
  5. Background process performs logging or notifications independently

Prerequisites

  • Next.js App Router environment
  • Familiarity with asynchronous JavaScript patterns

Pitfalls & limitations

  • !Does not provide strict guarantees if the server process crashes suddenly
  • !Avoid long-running tasks that exceed serverless timeout limits
  • !Variables passed into the callback should be explicitly handled to avoid closure traps

FAQ

Does after() block the client from seeing the page or API response?
No, the response is delivered immediately, and the background task continues execution silently.
What happens to the background task if the request fails?
The after() block will still execute even if the initial request returns an error or a redirect.
Can I use this for critical database updates?
No, only use it for side effects. Any operation that must be finished to keep your data accurate should occur before the response.

How it compares

Unlike manual promises which might be terminated when the response ends, after() specifically signals to the Next.js runtime that the task belongs in the background lifecycle.

Source & trust

28k stars🕒 Updated 2026-06-10
📄 Full skill instructions — original source: vercel-labs/agent-skills
## Use after() for Non-Blocking Operations

Use Next.js's after() to schedule work that should execute after a response is sent. This prevents logging, analytics, and other side effects from blocking the response.

**Incorrect (blocks response):**

import { logUserAction } from '@/app/utils'

export async function POST(request: Request) {
// Perform mutation
await updateDatabase(request)

// Logging blocks the response
const userAgent = request.headers.get('user-agent') || 'unknown'
await logUserAction({ userAgent })

return new Response(JSON.stringify({ status: 'success' }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
}


**Correct (non-blocking):**

import { after } from 'next/server'
import { headers, cookies } from 'next/headers'
import { logUserAction } from '@/app/utils'

export async function POST(request: Request) {
// Perform mutation
await updateDatabase(request)

// Log after response is sent
after(async () => {
const userAgent = (await headers()).get('user-agent') || 'unknown'
const sessionCookie = (await cookies()).get('session-id')?.value || 'anonymous'

logUserAction({ sessionCookie, userAgent })
})

return new Response(JSON.stringify({ status: 'success' }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
})
}


The response is sent immediately while logging happens in the background.

**Common use cases:**

- Analytics tracking
- Audit logging
- Sending notifications
- Cache invalidation
- Cleanup tasks

**Important notes:**

- after() runs even if the response fails or redirects
- Works in Server Actions, Route Handlers, and Server Components

Reference: [https://nextjs.org/docs/app/api-reference/functions/after](https://nextjs.org/docs/app/api-reference/functions/after)

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/server-after-nonblocking/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/vercel-labs/agent-skills/server-after-nonblocking/SKILL.md
  • Cursor: ~/.cursor/skills/vercel-labs/agent-skills/server-after-nonblocking/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/vercel-labs/agent-skills/server-after-nonblocking/SKILL.md

🚀 Install with CLI:
npx skills add vercel-labs/agent-skills

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid server-side performance issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Server-Side Performance and is published by Vercel Engineering, maintained in vercel-labs/agent-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.