This episode covers observability and production support: performance monitoring with real user metrics, error reporting with Sentry, logging server-side request and response metrics, and incident response with production support.

Your application is alive in production. The next question: how do you know it's healthy? Without data, everyone is guessing. Episode 22 is the art and science of observability — seeing into a running application.
Observability in Remix has two sides: server and client. On the server, loaders and actions are measurable, loggable points. On the client, real user metrics and error reports tell the story of the actual user experience. Together they form a complete picture of application health.
Episode 22 covers performance monitoring, error reporting with Sentry, server-side logging, and production support with incident response.
Loader and action execution time is the most useful server metric. Record the duration of each loader to find slow routes before users complain.
export async function loader() {
const mulai = performance.now();
const data = await ambilData();
const durasi = performance.now() - mulai;
console.log(`loader ambilData: ${durasi.toFixed(0)}ms`);
return data;
}performance.now gives millisecond accuracy for measuring a single operation. At production scale, collect these metrics into a monitoring service, not just the console.
Meanwhile, data from the browser tells the real experience. Metrics like LCP (time for the largest element to appear) and INP (responsiveness) are measured from users' devices. Real user monitoring complements synthetic tests: real data from real users' networks and devices.
An important difference between the two: synthetic tests measure under the same conditions every time, while real user monitoring captures actual conditions — slow networks, weak devices, and geographic variation. Combining the two gives the most complete view.
Sentry is the most common choice for error tracking in the Remix ecosystem. It captures errors on both the client and server, complete with stack traces and context.
npm install @sentry/remixAfter initialization, errors from loaders, actions, and components are reported automatically. Configure the DSN through environment variables — never write it in code.
A good error carries context: which route, which user, what kind of request. Sentry allows adding custom context so teams can prioritize fixes. Errors without context are hard to act on.
Structured logs — not just strings — are easy to search and analyze. Each log carries fields like timestamp, route, status, and duration. Structured logs are the language observability tools understand.
function logRequest(request, durasi, status) {
console.log(JSON.stringify({
waktu: new Date().toISOString(),
url: request.url,
status,
durasiMs: durasi,
}));
}This pattern records one JSON line per request with all the context needed. Serverless platforms often provide centralized logs that can be queried from JSON like this.
Besides logs, collect metrics: request counts, status code distribution, and latency percentiles. A simple dashboard with p95 and p99 gives a much better picture of performance than the average. One very slow request can inflate the average and mislead.
Start with a few of the most meaningful metrics, then expand gradually. Too many metrics from the start makes a dashboard hard to read and rarely used. Better three metrics everyone understands than thirty that nobody looks at.
When the application has problems, the team must know what to do. A runbook contains the diagnosis and recovery steps for common incidents: how to check logs, how to restart a service, when to roll back. Runbooks turn panic into procedure.
A good runbook is written while calm, not during an incident. Start with the most frequent incidents, document the steps, and update it with every new lesson. This documentation becomes the most valuable asset when the 3 AM call comes in.
Incidents are normal — what distinguishes good teams is how they respond. Communicate status, find the root cause with data, fix with the smallest change, and document the lessons. Every well-documented incident makes the application more resilient.
Observability isn't a goal; it's a tool for decisions. The collected data should be used: prioritize fixes, adjust resources, and schedule development. An observable application is a manageable application.
Observability also builds confidence: a team that knows its application can be monitored is bolder about making changes and releasing. Operational calm comes from data, not from blind faith.
Episode 22 completes production operations: performance monitoring on the server and client, error reporting with Sentry, structured logging with response metrics, and calm runbooks with incident response. Your application's condition can now be understood whenever needed.
The key takeaways:
In the next episode, episode 23 — the final one — we'll discuss stable modern features and future trends — Remix's stable features like data loaders, actions, and nested routes, full-stack React trends and server-driven UI, the Remix ecosystem and community tools, and strategies to keep your Remix skills relevant. This long journey closes with a look ahead.