You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在Vercel的Next.js应用/api/webhooks POST请求504超时

解决Vercel上Clerk-MongoDB Webhook 504超时问题

核心原因

Vercel Serverless Function默认超时时间为10秒,你的Webhook在处理Clerk事件时,同步等待MongoDB的createUser/updateUser/deleteUser操作完成,导致请求超过10秒触发504错误。


代码层面解决方案

1. 异步处理数据库操作(优先推荐)

Webhook无需向Clerk返回数据库操作结果,只需快速返回200确认接收即可。将数据库操作改为异步执行,不阻塞响应:

修改api/webhooks/route.ts中的事件处理逻辑:

// 处理user.created事件
if (eventType === "user.created") {
  const { id, email_addresses, image_url, username, first_name, last_name } = evt.data;
  
  // 异步执行数据库操作,不等待结果
  void(async () => {
    try {
      await createUser({
        clerkId: id,
        name: `${first_name}${last_name ? ` ${last_name}` : ""}`,
        username: username!,
        email: email_addresses[0].email_address,
        picture: image_url,
      });
    } catch (err) {
      console.error("创建用户失败:", err);
    }
  })();

  return NextResponse.json({ message: "OK" });
}

// 处理user.updated事件
if (eventType === "user.updated") {
  const { id, email_addresses, image_url, username, first_name, last_name } = evt.data;
  
  void(async () => {
    try {
      await updateUser({
        clerkId: id,
        updateData: {
          name: `${first_name}${last_name ? ` ${last_name}` : ""}`,
          username: username!,
          email: email_addresses[0].email_address,
          picture: image_url,
        },
        path: `/profile/${id}`,
      });
    } catch (err) {
      console.error("更新用户失败:", err);
    }
  })();

  return NextResponse.json({ message: "OK" });
}

// 处理user.deleted事件
if (eventType === "user.deleted") {
  const { id } = evt.data;
  
  void(async () => {
    try {
      await deleteUser({ clerkId: id! });
    } catch (err) {
      console.error("删除用户失败:", err);
    }
  })();

  return NextResponse.json({ message: "OK" });
}

2. 优化MongoDB操作性能

  • 给用户集合的clerkId字段添加唯一索引,加速查询、更新和删除操作:
    // 在MongoDB shell或ODM(如Mongoose)中执行
    db.users.createIndex({ clerkId: 1 }, { unique: true });
    
  • 检查createUser/updateUser/deleteUser中的代码,移除不必要的查询或数据处理逻辑,减少耗时。

3. 复用MongoDB连接

确保数据库连接采用单例模式,避免每次Webhook请求都新建连接:

// lib/mongodb.ts示例
import { MongoClient } from "mongodb";

let client: MongoClient | null = null;

export async function getMongoClient() {
  if (!client) {
    client = new MongoClient(process.env.MONGODB_URI!);
    await client.connect();
  }
  return client;
}

Vercel平台层面解决方案

1. 调整Serverless Function超时时间

若使用Vercel Pro/Enterprise计划,可将函数超时时间从默认10秒延长至最大60秒:

  • 进入Vercel项目 → Settings → Functions
  • 在"Timeout"选项中设置更长时间(如30秒)

2. 改用Edge Functions

Edge Functions的超时时间为30秒(免费版也支持),适合处理耗时稍长的请求。只需在route.ts顶部添加:

export const runtime = "edge";

注意:Edge环境有部分Node.js API限制,需确保createUser等操作兼容Edge环境(如避免使用fs等仅Node.js可用的模块)。

3. 确认中间件配置

你的middleware.ts已将/api/webhooks加入ignoredRoutes,确保中间件不会对Webhook请求做额外认证处理,减少不必要的耗时。当前配置无需调整。


内容的提问来源于stack exchange,提问作者Kekoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:50:29