FID retired Nov 1: keep a Sume generate button responsive

Vercel Speed Insights drops First Input Delay on November 1. A Sume generate button stays responsive if it submits async, gets a 202 and polls via your server.

4 min readSume
All posts

Vercel's October 1, 2026 changelog says Speed Insights deprecates First Input Delay on November 1. Whatever metric replaces it in your dashboard, a button that starts a Sume render should answer the click immediately. Submit with the default async mode, which returns 202 and a job id, then poll for the result.

The Vercel change

The Vercel changelog, read on 2026-10-03, announces the deprecation. This post does not say which metric replaces it or how your scores will move; read Vercel's note for that.

Why a generate button feels slow

Video, avatar-video and face-swap jobs routinely outlast the 30 second wait budget. sync and subscribe hold the HTTP request for at most 30 seconds, then hand back the job anyway. The docs recommend async or webhook for anything that can outlast that, which is most video work.

Communication modes (per Sume docs, read 2026-10-03)
ModeServer blocksUse when
async (default)No, returns 202Polling from a UI
syncUp to 30 sShort image jobs
subscribeSame as syncPorted queue clients
webhookNo, returns 202Server-to-server completion

Route handlers that never block

Keep the API key on the server. One handler submits and returns the job id, and a second returns status. The UI polls your status route with backoff and shows progress instead of freezing.

// app/api/render/route.ts
export async function POST(req: Request) {
  const { prompt, clientKey } = await req.json();
  const r = await fetch("https://api.sume.com/v1/videos", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SUME_API_KEY}`,
      "Content-Type": "application/json",
      "Idempotency-Key": clientKey,
    },
    body: JSON.stringify({ model: "sume/auto", prompt }),
  });
  const job = await r.json();
  return Response.json({ id: job.id }, { status: r.status });
}

// app/api/render/[id]/route.ts
export async function GET(_: Request, { params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const r = await fetch(`https://api.sume.com/v1/jobs/${id}/status`, {
    headers: { Authorization: `Bearer ${process.env.SUME_API_KEY}` },
  });
  return Response.json(await r.json(), { status: r.status });
}

Polling rules from the docs

Stop polling on completed, failed or canceled, use exponential backoff, and honor next_poll_after_seconds when it is present. Do not resubmit the paid request because the browser tab closed. Generate the clientKey once per user intent so a double click returns the original job.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume