Skip to main content
Foglamp batches spans in memory and flushes them fire-and-forget. In a long-running server that is invisible; in serverless environments the process can freeze or terminate before a batch is sent. The rule:
Anything you don’t flush before the runtime suspends is lost. The buffer is volatile by design — it never blocks your model calls.
The collector auto-detects its runtime and picks a flush strategy. You can always override with fog.flush() or by passing a waitUntil hook.
Flushing is identical on both entry points. The examples below use the v7 foglamp() collector, but a wrap() handle exposes the same flush() / shutdown() methods, the same waitUntil config, and the same serverless auto-detection — they apply verbatim on AI SDK v4–v6.

Long-running (Node, Bun)

Nothing to do. The collector flushes every flushIntervalMs (default 5s) and on early batch limits. For clean shutdown, drain the buffer on exit:
process.on("SIGTERM", () => fog.shutdown());
process.on("SIGINT", () => fog.shutdown());

Vercel functions

Nothing to do. The collector auto-detects Vercel and reads waitUntil from the runtime’s request context — the same source @vercel/functions wraps — to keep the function alive until the flush completes. No extra dependency is needed. If detection ever doesn’t fire, pass it explicitly:
import { waitUntil } from "@vercel/functions";

const fog = foglamp({ waitUntil });

Cloudflare Workers

Workers don’t expose a global waitUntil; it lives on the request ctx. Thread it through so the flush survives the response:
export default {
  async fetch(req, env, ctx) {
    const fog = foglamp({ waitUntil: ctx.waitUntil.bind(ctx) });

    const result = await generateText({
      model: openai("gpt-4o"),
      prompt: "…",
      telemetry: {
        integrations: [fog.integration({ traceName: "worker-handler" })],
      },
    });

    return Response.json(result);
  },
};

AWS Lambda

Lambda freezes the execution environment the moment your handler returns, so a background flush may never run. Await the flush before returning — do not rely on process.on("beforeExit"), which won’t fire.
export const handler = async (event) => {
  const result = await generateText({ /* … */ });
  await fog.flush();
  return result;
};

Manual flush anywhere

fog.flush() works in every runtime and resolves when the request completes. It’s safe to call when the collector is disabled (it resolves immediately), so you can leave it in unconditionally.
await fog.flush();