Guides / Monitoring

How to Track API Response Times and Slow Endpoints

4 min read·Monitoring

The pattern

Log response time as metadata on every slow request. Set a threshold (e.g. 2000ms) and only log when it's exceeded to avoid noise.

Express middleware

ts
// middleware/response-time.ts
import { logit } from "@/lib/logit";

const SLOW_THRESHOLD_MS = 2000;

export function responseTimeLogger(
  req: Request,
  res: Response,
  next: NextFunction
) {
  const start = Date.now();
  res.on("finish", async () => {
    const duration = Date.now() - start;
    if (duration > SLOW_THRESHOLD_MS) {
      await logit.now("perf", {
        event: "Slow API response",
        description: `${req.method} ${req.path}${duration}ms`,
        icon: "🐢",
        notify: duration > 5000, // alert only for very slow
        tags: { method: req.method, status: String(res.statusCode) },
        metadata: {
          path: req.path,
          method: req.method,
          durationMs: duration,
          statusCode: res.statusCode,
        },
      });
    }
  });
  next();
}

Hono middleware

ts
// middleware/response-time.ts
import type { MiddlewareHandler } from "hono";
import { logit } from "../lib/logit";

const SLOW_MS = 2000;

export const responseTime: MiddlewareHandler = async (c, next) => {
  const start = Date.now();
  await next();
  const duration = Date.now() - start;
  if (duration > SLOW_MS) {
    await logit.now("perf", {
      event: "Slow endpoint",
      description: `${c.req.method} ${c.req.path}${duration}ms`,
      icon: "⏱️",
      notify: false,
      metadata: { path: c.req.path, durationMs: duration, status: c.res.status },
    });
  }
};

Next.js App Router

ts
// lib/timed-handler.ts
import { logit } from "./logit";

export function withTiming(
  handler: (req: Request) => Promise<Response>,
  route: string
) {
  return async (req: Request): Promise<Response> => {
    const start = Date.now();
    const res = await handler(req);
    const duration = Date.now() - start;
    if (duration > 2000) {
      await logit.now("perf", {
        event: "Slow route",
        description: `${route} took ${duration}ms`,
        icon: "🐌",
        notify: duration > 8000,
        metadata: { route, durationMs: duration },
      });
    }
    return res;
  };
}

What to alert on

ThresholdAction
> 2sLog to perf channel, notify: false
> 5sLog + notify: true
> 10sLog + notify: true + add to incident channel

Try LogIt free

7-day trial. No credit card required.

Start free