Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
PerformanceJune 24, 20264 min read

Server-Timing API for INP Optimization: Debugging Backend Latency

Server-Timing API usage helps you master INP optimization by correlating backend latency with frontend responsiveness. Stop guessing—start measuring today.

Web PerformanceINPBackend LatencyServer-Timing APIObservabilityCore Web VitalsPerformanceWeb VitalsFrontend

Last month, we were chasing a mysterious spike in Interaction to Next Paint (INP) on our checkout page. The frontend metrics looked clean, the React render cycles were well within the "good" threshold, yet users were reporting sluggishness when clicking "Place Order." It turns out the bottleneck wasn't in the browser at all; it was a chain of serialized database queries sitting behind a slow API endpoint that was blocking the main thread just enough to delay the visual response.

If you’ve ever felt like you’re flying blind when optimizing for Core Web Vitals, you aren't alone. Connecting backend performance to client-side responsiveness is the missing link in most observability stacks.

The Role of the Server-Timing API in INP Optimization

When a user interacts with your page, the browser needs to handle that event, potentially fetch data, and update the UI. If your backend takes 400ms to respond, that latency eats directly into your interaction budget. By using the Server-Timing API, you can pass execution metrics from your server directly to the browser's Performance API.

Instead of guessing why a request took 600ms, you can see exactly how much time was spent in the database, the cache layer, or internal service calls. This data shows up right in your browser's Network tab under the "Server-Timing" header, which is invaluable for Core Web Vitals optimization: connecting backend latency to RUM.

Implementing Server-Timing Headers

To get started, you need to append a header to your HTTP responses. It looks something like this:

Server-Timing: db;dur=150, cache;dur=20, auth;dur=30

In a Node.js/Express or Next.js environment, this is trivial to inject. Here is a simplified middleware example:

JAVASCRIPT
// Middleware to inject Server-Timing
res.setHeader(CE9178">'Server-Timing', CE9178">`db;dur=${dbTime}, cache;dur=${cacheTime}`);

Once this header is present, the browser automatically makes this data available via performance.getEntriesByType('resource'). You can then log this to your telemetry service (like Sentry or Datadog) to correlate server-side delays with real-user INP reports.

Why We Initially Failed

We didn't get this right on the first try. We initially tried to log server latency via a separate analytics event sent after the request finished. This was a mistake. By the time that secondary event reached our monitoring dashboard, we had lost the context of the specific interaction that triggered it. We were looking at aggregate data rather than the specific request that caused the INP spike.

We also tried to include too much detail. We sent back every single function call duration, which bloated our header size and hit the 8KB limit for some proxies. When debugging INP optimization, keep the metrics high-level: database, external API calls, and authentication overhead.

Bridging the Gap to Frontend Observability

Once the data is in the browser, you can hook into the PerformanceObserver API. This allows you to capture the server-timing entries alongside your INP measurements.

JAVASCRIPT
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach((entry) => {
    if (entry.serverTiming) {
      console.log(CE9178">'Backend breakdown:', entry.serverTiming);
      // Send this to your telemetry backend
    }
  });
});

observer.observe({ entryTypes: [CE9178">'resource'] });

This approach creates a unified timeline. When an INP event exceeds 200ms, you can inspect the associated network request and instantly see if the backend was the culprit. If the db metric is high, you know exactly where to start your refactoring. If the db time is low but the total duration is high, you’re looking at network transit or middleware overhead.

Beyond Simple Metrics

Don't stop at just measuring. If your server-side execution is consistently pushing your INP into the "needs improvement" range, you have a few architectural levers to pull. We’ve found that Next.js request hedging can hide backend latency by firing multiple requests and taking the fastest one, while Next.js request memoization helps ensure you aren't doing redundant work that inflates your server-side duration.

Frequently Asked Questions

Does the Server-Timing API affect page load speed? The overhead is negligible. It’s just an HTTP header. As long as you don't include massive amounts of data, you won't see a performance hit.

Can I see this data in Google Analytics? Yes, but you need to manually push it. Use the PerformanceObserver logic shown above to capture the timing data and send it as a custom dimension or event property along with your INP report.

What if my backend is a microservices architecture? You can aggregate the Server-Timing headers from downstream services. It’s a bit of work to propagate them, but it provides incredible visibility into the entire request chain.

Final Thoughts

I’m still not convinced we have the perfect observability setup. We are currently struggling with how to handle "long tasks" that aren't strictly tied to a single network request. Sometimes the backend is fast, but the sheer amount of data being processed on the main thread causes the interaction delay.

We’re planning to look into more granular task-tracking next, but for now, the Server-Timing API has been the single most effective tool for stopping the "it's the backend's fault" vs. "it's the frontend's fault" finger-pointing. Start small, track the big-ticket items, and keep your headers lean. You’ll be surprised at how much clarity it brings to your performance monitoring.

Back to Blog

Similar Posts

PerformanceJune 22, 20264 min read

Server-Timing API: Correlate Backend Latency with Core Web Vitals

Use the Server-Timing API to correlate backend latency with Core Web Vitals. Stop guessing why your pages are slow and get full-stack observability today.

Read more
PerformanceJune 24, 20264 min read

Fetch Priority API: Optimize Resource Prioritization for Core Web Vitals

Master the Fetch Priority API to optimize resource prioritization. Learn how to resolve network congestion and boost your Core Web Vitals in production.

Read more
PerformanceJune 21, 20264 min read

Speculation Rules API: Achieving Instant Navigation in Modern Apps

Master the Speculation Rules API for predictive prefetching. Learn how to drive instant navigation and improve Core Web Vitals without breaking your server.

Read more