Instrumenting an app · 5 min read · Updated 2026-09-22

One incident

Monday: the funnel drops at checkout. You do not open three vendors. You follow the person, the replay, the issue, and the query.

Part 7 of 8 · Next: The operating model

The reason to keep errors, traces, analytics, and replay in one product is not a bundle discount. It is Monday. You shipped 1.4.2 on Sunday night. At 9:40 the support channel has three “pay button spins.” Finance will ask about conversion at noon. If those facts live in three SaaS accounts, you will spend the morning agreeing on timestamps.

This chapter is the same purchase as A checkout, end to end, read from the dashboard outward. No new APIs. If a join is missing, the missing call is back in chapter 6.

Start on the funnel, not the inbox

Open Analytics → Funnels → Checkout. The five steps from this course should already exist. This morning the last bar is wrong: checkout_started held, order_completed fell — a step with a list of people who went no further.

Checkout funnel · 24h window

storefront

production
  1. 01 $pageview9,318 · 100%
  2. 02 product_viewed5,140 · 55.2%

    −4,178 dropped here

  3. 03 add_to_cart2,106 · 22.6%

    −3,034 dropped here

  4. 04 checkout_started1,284 · 13.8%

    −822 dropped here

  5. 05 order_completed742 · 8.0%

    −542 dropped here

Entrants who never reached step 2 are listed by name, each with their replay, errors, and trace.

Drop-off is a list. Each row is a visitor or a user, with replay, errors, and trace when the ids exist.

If you had started on Issues, you might have seen a new fingerprint — or you might have seen nothing yet, because the failure is a 12-second query that has not thrown. The funnel does not care whether the code threw. It cares that the person did not finish.

Open one person

Pick someone who stopped at checkout. You are looking for three links, not a biography:

  • Their events — $pageview, product_viewed, add_to_cart, checkout_started, maybe checkout_failed with reason.
  • View replay — if the browser retained a recording (error-triggered by default). Watch the last seconds. Did the button spin? Did they bounce before the request?
  • View issue / View trace — if an exception fired on that session, or if the checkout request was traced.

Two cases fall out of that list. Treat them separately.

If checkout_failed says card_declined, that is a business fact, not a 1.4.2 regression. Group those people out of the incident before you page anyone. Chapter 6 is this case: Stripe threw, captureException ran, the issue has a stack.

If order_completed is missing and checkout_failed is also missing, the browser never heard back and the API never reached the track call. Look at the transaction, not the React component. This is the case that has not thrown yet — a slow query, an N+1, a peer that hung.

Replay is the last seconds, not the movie

You are not watching a ten-minute session for fun. You are confirming the moment: they clicked Pay, the button went busy, nothing returned. Console and network sit in the sidebar. Breadcrumbs on the issue still help when replay was not retained — privacy, sampling, or an API-only failure with no DOM.

Replay is a second public meter. The default profile does not record every session. That is why the funnel list is the index and replay is the evidence, not the other way around.

The issue is the group, not the latest event

When the charge did throw, you land on one issue — server-side fingerprint, count, first and last seen, release 1.4.2. Open the issue, not a raw event stream. Then open one event for the stack and the extra (sku: TR-900). Tags should already say feature: checkout.

One checkout, four rows

Checkout · TR-900

production

traceId 4bf92f35… · release 1.4.2 · user_123

Issue

PaymentException

traceId · replayId

Trace

POST /checkout

traceId · spanId

Event

checkout_failed

traceId · userId

Replay

session s_9d2…

replayId · sessionId

Correlation is a column on each row, not a join you invent later.

The same traceId on the issue, the waterfall, the failed analytics event, and the replay.

Resolve when 1.4.3 is in production and the fingerprint goes quiet. A reopen is a different alert than a brand-new issue — see errors, traces, and replay.

The query is often not the frame that threw

View trace. Read the waterfall before you reread the stack. In the Stripe case the charge child is red and you are done. In the slow case the Stripe child is fine and a newly added SELECT of related products on the checkout action, once per line item, is not. That is the N+1 Performance has been drawing since Sunday’s deploy — even when nothing threw.

Trace

00-3a91… · 184 ms

production
  1. POST /checkout

  2. SELECT related

    N+1
  3. SELECT related

    N+1
  4. SELECT related

    N+1
  5. POST stripe.com

  6. INSERT orders

If p95 rose and errors stayed flat, you would still be here — starting from RED, not from the funnel. Today both moved.

Performance → RED on POST /checkout should show throughput down or errors up alongside the duration bump. Release health on 1.4.2 should look worse than 1.4.1. Those are the same story at different zoom levels. Release health and N+1 are the concept guides; this is the order you click them.

What should have paged you

A well-run checkout does not discover this in Slack support. They discover it from a rule:

  • New issue on production — the Stripe or query exception, if it threw.
  • RED threshold on POST /checkout p95 or error rate — the slow path that does not always throw.

Email is on every plan; Slack and webhooks are on paid plans. AI tools can explain an event you already opened. They do not watch the funnel for you and they do not invent a stack. Performance alerts and AI.

The loop, once

  1. Funnel says where people stopped.
  2. One person says whether it was a decline, a spin, or a bounce.
  3. Replay confirms the moment.
  4. Issue groups the crash, if any.
  5. Waterfall names the child that ate the time.
  6. Release tells you which deploy to revert or patch.
  7. Alert is how the next one is shorter.

Related guides

  • Instrumenting an app · 6 min

    A checkout, end to end

    One purchase, every hop, the actual calls. This is what “instrumented” looks like when you are done.

  • Triage loop · 3 min

    From error to trace to replay

    Performance without grouping is a chart. Grouping without traces is a stack. Replay without either is a video. Talaria joins all three on one issue.

  • Product analytics · 4 min

    Funnels and drop-off

    A funnel tells you which step loses people. Talaria then hands you the people, and the replay of them leaving.

  • Triage loop · 3 min

    Performance alerts and AI on traces

    Alerts notice when RED crosses a line you set. Dashboard AI reads the issue, the replay, and the trace. Your coding agent uses MCP for the same evidence in the IDE.

Instrument the first three events

Install an official SDK, opt into tracing and analytics, and name the start, the middle, and the finish of your core action.