Monitoring
Know when production breaks. Init ships a health endpoint and dev-time logging; add error tracking and analytics as you grow.
What's Included
Health Endpoint
/api/health returns a liveness response (apps/web/src/app/api/health/route.ts). Point an uptime monitor (Vercel Checks, Better Stack, UptimeRobot) at it.
curl https://your-domain.com/api/health
# {"status":"ok"}Dev-Time Logging
- The oRPC client's
onErrorinterceptor logs failed procedure calls in development (apps/web/src/orpc/react.tsx) - TanStack Query Devtools ship in the provider tree
Recommended Additions
Start simple. Add pieces when you have users to lose.
Error Tracking (Sentry)
npx @sentry/wizard@latest -i nextjsThe wizard wires up client, server, and edge configs. Set SENTRY_DSN in Vercel. Tag errors with user and organization ids so you can trace multi-tenant issues:
import * as Sentry from "@sentry/nextjs";
Sentry.setUser({ id: session.user.id });
Sentry.setTag("organization.id", organization.id);Vercel Analytics
pnpm -F @repo/web add @vercel/analytics @vercel/speed-insights// apps/web/src/app/layout.tsx
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
// Render inside <body>
<Analytics />
<SpeedInsights />Covers page views and Core Web Vitals with zero config on Vercel.
API Timing
Add an oRPC middleware to catch slow procedures:
// packages/api/src/orpc.ts
const timingMiddleware = o.middleware(async ({ next, path }) => {
const start = Date.now();
const result = await next();
const duration = Date.now() - start;
if (duration > 1000) {
console.warn(`Slow procedure: ${path.join(".")} took ${duration}ms`);
}
return result;
});
export const publicProcedure = o.use(timingMiddleware);Vercel's log drains forward these warnings to your log store.
Database Performance
Query stats come from pg_stat_statements - enable it once (CREATE EXTENSION IF NOT EXISTS pg_stat_statements;), then read it directly or in your provider's dashboard:
SELECT query, mean_exec_time, calls
FROM pg_stat_statements
WHERE mean_exec_time > 100
ORDER BY mean_exec_time DESC;Slow query? Check for a missing index first - multi-tenant tables should index their organization_id (the todo table shows the pattern).
Best Practices
- Start simple - Uptime check + error tracking covers most failures
- Monitor user impact - Web Vitals and error rate over vanity metrics
- Avoid alert fatigue - Alert on symptoms (error spikes, downtime), not noise
- Scrub logs - No emails, tokens, or session ids in log lines
Next Steps
- Production checklist - Production readiness
- User analytics - User behavior tracking
- Feedback - User feedback systems