Use after() for Non-Blocking Operations
Install this skill
npx skills add vercel-labs/agent-skillsWorks 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
- Receive incoming client request in a Route Handler
- Execute primary database mutation or resource update
- Declare the after() block for secondary background tasks
- Return the 200 OK status to the client immediately
- 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
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.
📄 Full skill instructions — original source: vercel-labs/agent-skills
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)
- Click "Download" above
- In your project, create the directory:
.agent/skills/server-after-nonblocking/ - Save the file as
SKILL.md - 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