Your REST API is "up." Congratulations. That tells you almost nothing.
Uptime means the server responds. It doesn't tell you that /api/checkout is taking 4 seconds instead of 400 milliseconds. It doesn't tell you that 3% of requests to /api/users are returning 500 errors. It doesn't tell you that your most critical endpoint is 10x slower during peak hours.
Uptime is a binary metric. Real API monitoring is about understanding how well your API is performing, across every endpoint, every minute, every percentile.
This guide covers the 5 metrics every REST API should track, how to measure each one, and which tools to use depending on your team size and stack.
Metric 1: Uptime: But Measured Correctly
Uptime is the most basic metric, but most teams measure it wrong.
What most teams do: An external service pings /api/health every 60 seconds. If it returns 200, the API is "up." This gives you a number like 99.9%, which sounds great until you realize it means 8.7 hours of downtime per year, measured in 60-second increments that miss everything in between.
What you should do: Calculate uptime from real request data. If you served 1,000,000 requests this month and 2,000 returned 5xx errors, your effective uptime is 99.8%, regardless of what the health check says.
// Real uptime calculation
const totalRequests = 1_000_000
const serverErrors = 2_000 // 5xx responses only
const effectiveUptime = ((totalRequests - serverErrors) / totalRequests) * 100
// 99.8%, more accurate than any ping-based checkTargets by tier:
| SLA | Allowed downtime/year | Typical for |
|---|---|---|
| 99.0% | 3.65 days | Internal tools, staging |
| 99.9% | 8.7 hours | Most SaaS products |
| 99.95% | 4.4 hours | Payment / auth APIs |
| 99.99% | 52 minutes | Infrastructure APIs (AWS, Stripe) |
Metric 2: Latency Percentiles: P50, P95, P99
Average response time is a lie. If 99 requests take 50ms and 1 request takes 10 seconds, the average is 149ms. That single number hides the fact that 1% of your users are having a terrible experience.
Percentiles tell the real story:
- P50 (median)The typical experience. 50% of requests are faster than this. If your P50 is 80ms, most users are happy.
- P95The experience of your slowest 5% of users. This catches slow database queries, cold starts, and n+1 problems. If your P95 is 2 seconds, 1 in 20 requests is painfully slow.
- P99The worst 1%. This catches connection pool exhaustion, garbage collection pauses, and timeout cascades. If your P99 is 8 seconds, your most active users (who make the most requests) will hit this regularly.
Why P99 matters more than you think: A user who makes 100 API calls per session has a 63% chance of experiencing the P99 latency at least once. For your power users, P99 is the experience.
// The math: probability of NOT hitting P99 in N requests
// P(never hitting P99) = 0.99^N
// For N=100: 0.99^100 = 0.366 → 63.4% chance of hitting P99 at least once
// Latency percentiles per endpoint, what you should see in your dashboard
// GET /api/users → P50: 45ms | P95: 120ms | P99: 340ms
// GET /api/products → P50: 80ms | P95: 450ms | P99: 2100ms
// POST /api/checkout → P50: 200ms | P95: 1800ms | P99: 8500ms Targets: P50 under 100ms, P95 under 500ms, P99 under 2 seconds. Anything above P99 of 5 seconds needs immediate investigation.
Metric 3: Error Rate by Endpoint
A global error rate of 0.5% feels fine. But what if all those errors come from one endpoint?
// Global view: 0.5% error rate, looks fine
// Per-endpoint view:
// GET /api/users → 0.01% errors
// GET /api/products → 0.02% errors
// POST /api/checkout → 12.4% errors ← This is where all the errors are
// GET /api/analytics → 0.00% errors Per-endpoint error rates reveal problems that global metrics hide entirely. Your checkout endpoint could be failing for 1 in 8 users while your overall error rate looks healthy.
What to track:
- 4xx rateClient errors. A sudden spike in 400s or 422s often means a frontend deployment broke request payloads. A spike in 401s means auth is broken.
- 5xx rateServer errors. These are always your fault. Any sustained 5xx rate above 0.1% on a critical endpoint needs investigation.
- Error budgetIf your SLA allows 0.1% errors, and you've used 80% of your monthly budget by the 15th, slow down deployments and focus on stability.
Targets: 5xx rate below 0.1% per endpoint. 4xx rate tracked for anomalies (no fixed target since some 4xx is normal).
Metric 4: Throughput: Requests per Minute
Throughput tells you how much traffic each endpoint handles. By itself it's informational, but combined with latency and error rates, it becomes diagnostic:
- Throughput up + latency up = You're approaching capacity limits. Scale horizontally or optimize.
- Throughput up + errors up = You're past capacity. Something is rejecting requests under load.
- Throughput down + latency up = A dependency is slow and requests are queuing. Database or external API issue.
- Throughput down + errors same = Traffic dropped. Could be normal (off-peak) or a problem (DNS, CDN, frontend broken).
// Throughput patterns to watch
// Normal day:
// 09:00 → 1,200 rpm → P95: 120ms → Errors: 0.02%
// 12:00 → 2,800 rpm → P95: 135ms → Errors: 0.03% ← Peak, handling it fine
// 18:00 → 1,500 rpm → P95: 115ms → Errors: 0.01%
// Problem day:
// 09:00 → 1,200 rpm → P95: 120ms → Errors: 0.02%
// 12:00 → 2,800 rpm → P95: 890ms → Errors: 2.10% ← Can't handle peak load
// 12:15 → 1,100 rpm → P95: 3200ms → Errors: 8.40% ← Cascading failureTargets: No fixed target, track the baseline and alert on deviations (±30% from typical for that time of day).
Metric 5: Slow Endpoint Detection
Most monitoring tools let you set static thresholds: "alert if response time exceeds 2 seconds." This works until you have 30 endpoints with different normal ranges.
Slow endpoint detection means automatically identifying which routes are degrading relative to their own baseline:
| Endpoint | Normal P95 | Current P95 | Change | Status |
|---|---|---|---|---|
GET /api/users | 120ms | 125ms | +4% | Normal |
GET /api/products | 80ms | 340ms | +325% | Degraded |
POST /api/checkout | 200ms | 210ms | +5% | Normal |
GET /api/search | 150ms | 4200ms | +2700% | Critical |
A 2-second static threshold would miss /api/products at 340ms (it's under the threshold but 4x its normal speed). And /api/search at 4.2 seconds is obviously broken, but you'd want to know about the products endpoint too.
Monitoring Tools Compared
Two common platforms for REST API monitoring, plus the open-source route:
Datadog
- What it is: Full observability platform, APM, logs, infrastructure, synthetic checks
- How it works: Agent daemon (300-500MB RAM) + language library (
dd-trace) - Cost: $71/host/month (APM) + $15/host/month (infrastructure). A team with 3 servers: ~$258/month minimum
- Setup time: 2-4 hours. 10+ environment variables, YAML config, agent installation
- Best for: Large teams with dedicated DevOps, running Kubernetes with 50+ services
- Limitation for Next.js: The Datadog agent can't run on Vercel serverless. You get degraded "agentless" mode with higher latency and sampling
New Relic
- What it is: Full-stack observability with APM, browser monitoring, and AI ops
- How it works: Language agent (
newrelicnpm package) + cloud collector - Cost: Free tier (100GB data/month), then $49+/host/month. Data ingestion charges can spike unexpectedly
- Setup time: 1-2 hours. Simpler than Datadog but still requires config file and multiple env vars
- Best for: Mid-size teams that want full observability without Datadog's price tag
- Limitation for Next.js: The Node.js agent adds 200-400ms to cold starts via monkey-patching. Partial serverless support
OpenTelemetry (open source)
- What it is: A vendor-neutral standard and set of SDKs for traces, metrics and logs
- How it works: Instruments your app in-process (in Next.js, through the
instrumentation.tshook) and exports data to the backend you choose - Cost: The SDKs are free; you pay for wherever you store the data (self-hosted Prometheus/Grafana, or a hosted backend)
- Best for: Teams that want per-endpoint metrics without locking into one vendor
| Datadog | New Relic | |
|---|---|---|
| Monthly cost (small team) | $258+ | $147+ |
| Setup time | 2-4 hours | 1-2 hours |
| Lines of code | 50-100+ | 20-50 |
| Cold start impact | +200-800ms | +200-400ms |
| Works on Vercel serverless | Partially | Partially |
| Auto-discovers API routes | Yes (with agent) | Yes (with agent) |
| Per-endpoint P95/P99 | Yes | Yes |
Why Internal Monitoring Wins for REST APIs
External monitoring (pinging your API from outside) has fundamental blind spots for REST APIs:
- It samples. A ping every 60 seconds tests 1 request per minute. Your API handles 2,000. That's 0.05% coverage.
- It tests one endpoint. You have 20 routes. External monitors charge per endpoint, so most teams only monitor 2-3.
- It can't see error rates. An external ping hits
/api/healthand gets 200. Meanwhile,/api/paymentsis returning 500 for 8% of real users. - It measures network + server time. A 200ms response from Virginia might be 50ms of server time and 150ms of network. You're optimizing the wrong thing.
Internal monitoring runs inside your server and sees every request. No sampling, no blind spots, real server-side timing. This is the difference between knowing your API is "reachable" and knowing it's actually working well.
Setup: Per-Endpoint Monitoring in Next.js
If you're running Next.js, one vendor-neutral way to get these metrics is OpenTelemetry through the instrumentation.ts hook:
Step 1: Install
Add @vercel/otel and the OpenTelemetry packages its documentation lists as dependencies.
Step 2: Add instrumentation
// instrumentation.ts
import { registerOTel } from '@vercel/otel'
export function register() {
registerOTel({ serviceName: 'my-api' })
}Step 3: Point it at your backend
# .env.local (or your hosting dashboard)
OTEL_EXPORTER_OTLP_ENDPOINT=https://your-collector.example.comStep 4: Deploy and build the views
Once spans start arriving, build dashboards and alerts in your backend for:
- P50, P95, P99 latency per endpoint
- Error rate (4xx/5xx) per endpoint
- Throughput (requests per minute)
- Endpoints that are slow relative to their own baseline
- Real uptime calculated from actual request data
Route alerts to the channel your on-call engineer actually watches, with one message per incident, not one per failed request. Keep an external uptime check as well, for outages where no traffic reaches your server at all.
What to Do After Setup
Once monitoring is running, here's the playbook:
- Week 1: Observe. Don't set alert thresholds yet. Let the tool establish baselines for each endpoint.
- Week 2: Set P95 thresholds per endpoint based on observed baselines (2x the baseline is a good starting point).
- Week 3: Set error rate thresholds. 0.5% for critical endpoints (checkout, auth), 2% for everything else.
- Ongoing: Review weekly. Look for slow trends, a P95 that increases 10% per week will be a problem in a month even if it's fine today.
