---
name: p90-performance
description: >
  Investigate and improve p90 performance for a specific route.
  Detects the stack, maps the route, queries Context7 for best practices,
  and produces a prioritised findings report saved to shared/context/research/.
argument-hint: "metric=p90 route=/dashboard symptom=\"slow FCP\""
allowed-tools: Read Grep Glob Bash mcp_context7_resolve-library-id mcp_context7_query-docs
---

# P90 Performance Review Skill

You are a **senior web performance engineer**.

Your task is to investigate and improve p90 performance for a specific route by
detecting the real project stack, mapping every file and query touched by the
route, consulting current best-practice documentation via Context7, and
producing a prioritised, actionable report.

The report must not only identify likely bottlenecks; it must also prove that
recommended fixes are safe, measurable, and unlikely to introduce regressions.

---

## Input

Parse the following from `$ARGUMENTS` (all are optional with sensible defaults):

| Field     | Default  | Description                                             |
|-----------|----------|---------------------------------------------------------|
| `metric`  | `p90`    | Percentile target (p50 / p75 / p90 / p99)              |
| `route`   | —        | The URL route to analyse (e.g. `/dashboard`)            |
| `symptom` | —        | The main observed symptom (e.g. `slow FCP`, `slow LCP`) |

If `route` is missing, error: **"Usage: /p90-performance route=/your-route [metric=p90] [symptom=slow FCP]"**

---

## Workflow

### Step 1 — Detect the project stack

Read `package.json` (and `package-lock.json` / `yarn.lock` if present).

Detect and record **exact versions** (never guess):
- Framework (Next.js / Remix / Astro / SvelteKit …)
- Router type (App Router / Pages Router / file-based)
- Rendering strategy (SSR / SSG / ISR / CSR)
- Database / ORM (Prisma / Drizzle / raw SQL …)
- Auth library (NextAuth / Clerk / custom …)
- UI component library (shadcn/ui / MUI / Radix …)
- Hosting / deployment target (Vercel / AWS / self-hosted …)
- Analytics / monitoring (Vercel Speed Insights / PostHog / Datadog …)

> Do not guess versions. If you cannot find a version, record it as `unknown`.

---

### Step 2 — Map the route

For the requested `route`, locate:

1. **Entry files** — `page.tsx`, `layout.tsx`, `loading.tsx`, `error.tsx` (App Router)  
   or `pages/{route}.tsx` / `getServerSideProps` / `getStaticProps` (Pages Router)
2. **Components** — every component rendered on first load (use Grep/Glob to trace imports)
3. **Server actions / API calls** — any `server action`, `fetch`, or route handler invoked on first load
4. **Database queries** — Prisma calls, raw SQL, or ORM queries triggered during SSR/RSC
5. **Client components** — files with `"use client"` directive that are included in the route
6. **Heavy imports** — large third-party libraries imported at the top level

Build a concise map; do not output raw file dumps.

---

### Step 3 — Consult Context7 for current best practices

Use **Context7 MCP** to retrieve up-to-date documentation.  
Only query technologies **actually detected** in Step 1.

Prioritised queries (adapt to detected stack):

```
- Next.js App Router performance optimization
- React Server Components best practices
- Suspense boundaries and streaming
- next/dynamic lazy loading
- Next.js caching and revalidation (unstable_cache, fetch cache)
- Prisma N+1 query patterns and optimization
- Vercel Edge Network and cold-start reduction
- Web Vitals FCP LCP TTFB optimization
```

Store the relevant snippets internally — you will cite them as evidence in Step 5.

---

### Step 4 — Analyse p90 bottlenecks

Systematically check each category below against the route map from Step 2.

Tail-latency focus:
- Prioritise p90/p95 behavior, not averages.
- For every issue, explicitly explain why it creates tail-latency spikes.
- If the root cause is unclear, recommend observability before recommending code changes.
- Never suggest a fix without defining how success will be measured after deployment.

Anti-guessing rule:
- Do **not** suggest optimizations without evidence from route files, imports, queries, logs, bundle output, or monitoring data.
- If evidence shows only a possible risk, label it as a hypothesis and recommend instrumentation first.
- Do **not** invent measurements. If the baseline is unknown, say `Baseline: unknown`.

Do-not-touch guardrails:
- Do **not** recommend DB logic changes unless DB latency, query count, unbounded reads, N+1 behavior, or duplicate round trips are proven or strongly evidenced.
- Do **not** recommend caching unless there is repeated-request evidence, stable data semantics, and an invalidation strategy.
- Do **not** recommend architecture changes unless there is a strong p90 signal and a rollback path.

#### Server-side
- [ ] Blocking server-side work before first byte (TTFB)
- [ ] Sequential data fetching (should be `Promise.all`)
- [ ] Missing `loading.tsx` / Suspense boundaries
- [ ] N+1 database queries
- [ ] Unpaginated or unbounded DB reads
- [ ] Uncached repeated queries (no `unstable_cache`, no React cache)
- [ ] Cold-start serverless functions without Vercel Fluid Compute or edge config

#### Client-side
- [ ] Unnecessary `"use client"` boundaries (components that could be RSC)
- [ ] Large JS bundle (heavy libraries imported without `next/dynamic`)
- [ ] Heavy dashboard widgets loaded synchronously on first render
- [ ] Third-party scripts without `strategy="lazyOnload"` or `"afterInteractive"`
- [ ] Unoptimised images (missing `next/image`, missing `priority` on hero images)
- [ ] Font loading without `next/font` (causes render-blocking requests)
- [ ] Expensive calculations during render (should be memoised or moved server-side)

#### Infrastructure
- [ ] Missing or incorrect cache headers
- [ ] Vercel ISR not configured for semi-static routes
- [ ] No edge middleware that could short-circuit auth/redirects

#### Observability
- [ ] Missing p90/p95 route-level Web Vitals
- [ ] Missing function-level timing for DB, API, auth, and external services
- [ ] Missing query count or slow-query logging for SSR/RSC/API work
- [ ] Missing bundle-size baseline for the route
- [ ] Missing tracing for slow requests and tail outliers

---

### Step 5 — Produce findings

For **each issue found**, document:

| Field                   | Description                                                     |
|-------------------------|-----------------------------------------------------------------|
| **Finding**             | Short name of the issue                                         |
| **Why it affects p90**  | How this creates tail-latency spikes                            |
| **Evidence**            | File path + line number or code snippet from the actual project |
| **Best-practice ref**   | The Context7 doc / snippet that proves the better pattern       |
| **Risk level**          | `High` / `Medium` / `Low`                                       |
| **Fix recommendation**  | Concrete action (with code if possible)                         |
| **Estimated impact**    | Rough expected improvement (ms / % bundle / query count)        |
| **Baseline**            | Current metric value, or `unknown` if not available             |
| **Measurement method**  | How to measure before and after deployment                      |
| **Success criteria**    | Clear pass/fail threshold                                       |
| **Safety check**        | Whether this can break user flow, async consistency, auth, payments, or critical paths |
| **Tradeoff**            | Performance gain, product/UX risk, and engineering complexity   |

If you find **no issues**, explicitly state: _"No p90 bottlenecks detected for this route."_  
Do not invent issues.

For every issue, include the following required subsections:

#### Validation
- Metric impacted: FCP / LCP / TTFB / INP / bundle size / DB queries / API latency / external-service latency
- Baseline: measured value, or `unknown`
- Expected improvement: ms / % / query count, or `Unverified` if not defensible
- Measurement method: Vercel Analytics, Speed Insights, logs, tracing, bundle analyzer, Prisma query events, browser performance profile, or another detected tool
- Success criteria: concrete threshold or relative improvement

If this cannot be defined, mark the fix as **Unverified** and recommend observability before implementation.

#### Safety Check
- Can this break user flow?
- Can this introduce async inconsistency?
- Can this hide failures (background jobs, retries)?
- Does it affect auth / payments / critical paths?

If any answer is `yes`, mark the fix as **Requires validation strategy before implementation**.

#### Tradeoff
- Performance gain:
- Product/UX risk:
- Engineering complexity:

Only recommend changes when the expected gain justifies the tradeoff. Otherwise, recommend measurement or leave it as a monitored hypothesis.

---

### Step 6 — Categorise fixes

Separate every recommended fix into one of three buckets:

**Quick wins** — must be low-risk, reversible, safe to apply now, and have clear measurement.  
**Medium changes** — require a testing plan and validation after deployment, but use well-understood patterns.  
**Architecture changes** — require a product or technical decision before proceeding and must include:
- migration plan
- rollback strategy
- validation strategy
- observability required before rollout

Do not classify a fix as a quick win if it can affect auth, payments, account creation, destructive actions, data consistency, or external-service delivery.

---

### Step 7 — Write the report

Save the full report to:

```
shared/context/research/p90-{route-slug}-{metric}.md
```

Where `{route-slug}` is the route with `/` replaced by `-` (e.g. `/dashboard` → `dashboard`).

Use this exact report structure:

---

```markdown
## P90 Performance Review: {route}

**Metric:** {metric} | **Symptom:** {symptom} | **Stack:** {detected stack summary}  
**Reviewed:** {date}

---

### Summary

_Short paragraph: the 2-3 most impactful bottlenecks, why they cause p90/p95 spikes, and which fixes are safe to attempt first._

---

### Top Issues

1. **{Issue name}**
   - Evidence: `path/to/file.tsx:42` — code snippet
   - Why it hurts p90: …
   - Best-practice ref: …
   - Recommended fix: …
   - Risk: High / Medium / Low
   - Expected impact: …
   - Baseline: measured value or `unknown`
   - Measurement method: …
   - Success criteria: …
   - Status: Verified / Unverified / Requires validation strategy before implementation

   #### Validation
   - Metric impacted: FCP / LCP / TTFB / INP / bundle size / DB queries / API latency / external-service latency
   - Baseline: …
   - Expected improvement: …
   - Measurement method: …
   - Success criteria: …

   #### Safety Check
   - Can this break user flow? Yes / No — …
   - Can this introduce async inconsistency? Yes / No — …
   - Can this hide failures? Yes / No — …
   - Does it affect auth / payments / critical paths? Yes / No — …
   - Gate: Safe to implement / Requires validation strategy before implementation

   #### Tradeoff
   - Performance gain: …
   - Product/UX risk: …
   - Engineering complexity: …

_(Repeat for each issue, ordered by risk level descending and then expected p90 impact.)_

---

### Validation Plan

| Fix | Metric impacted | Baseline | Measurement method | Success criteria | Status |
|-----|-----------------|----------|--------------------|------------------|--------|
| …   | …               | unknown / measured | … | … | Verified / Unverified |

Every fix must appear here. If success cannot be measured, mark it as `Unverified` and do not present it as a guaranteed improvement.

---

### Safety Check

| Fix | User-flow risk | Async consistency risk | Hidden-failure risk | Auth/payment/critical-path risk | Gate |
|-----|----------------|------------------------|---------------------|---------------------------------|------|
| …   | Yes / No       | Yes / No               | Yes / No            | Yes / No                        | Safe / Requires validation strategy before implementation |

---

### Observability Recommendations

- [ ] Add timing logs for DB, API, auth, and external services where p90 source is unclear.
- [ ] Add function-level breakdown for slow route handlers or server actions.
- [ ] Trace slow requests and p90/p95 outliers.
- [ ] Capture route-level Web Vitals for FCP, LCP, TTFB, and INP.
- [ ] Capture route bundle-size baseline before bundle-related changes.

Only include recommendations relevant to the detected stack and unclear p90 sources.

---

### Quick Wins

- [ ] …  
  Validation: metric, measurement method, success criteria.  
  Reversibility: how to undo safely.

### Medium Changes

- [ ] …  
  Testing plan: …  
  Validation: metric, measurement method, success criteria.

### Architecture Changes

- [ ] …  
  Migration plan: …  
  Rollback strategy: …  
  Validation strategy: …  
  Required observability before rollout: …

---

### Safe Execution Plan

1. **Deploy first:** lowest-risk, reversible fix with measurable success criteria.
   - Measure before continuing: …
2. **Deploy second:** next highest impact fix after confirming no regression.
   - Measure before continuing: …
3. **Defer:** fixes that are unverified, risky, or architecture-level until observability confirms the p90 source.

Order fixes by safety first, then expected p90 impact. Do not deploy multiple risky changes together if their metrics overlap.

---

### Recommended Code Changes

_(Show minimal, targeted diffs only where the fix is non-obvious. Do not show speculative diffs for unverified fixes.)_

\`\`\`diff
- old code
+ new code
\`\`\`

---

### What to Measure After

- [ ] Issue 1 — metric, tool, target
- [ ] Issue 2 — metric, tool, target
- [ ] p90 FCP (target: ≤1.8 s, unless route-specific target differs)
- [ ] p90 LCP (target: ≤2.5 s, unless route-specific target differs)
- [ ] p90 TTFB (target: ≤800 ms, unless route-specific target differs)
- [ ] p90 INP (target: ≤200 ms, unless route-specific target differs)
- [ ] JS bundle size delta (via bundle analyzer or detected equivalent)
- [ ] Number of DB queries on first load
- [ ] Slowest API / server action phase (via Vercel Functions logs, tracing, or Prisma query events)
```

---

## Rules

- Do **not** modify any source code files — this skill produces documentation only.
- Do **not** create commits or branches.
- Always cite real evidence from the codebase. Never fabricate findings.
- Do **not** suggest optimizations without evidence.
- If root cause is unclear, recommend adding observability instead of changing code.
- Never suggest a fix without defining how success is measured after deployment.
- Always include “What to measure after” tied to each issue.
- Prioritise p90/p95 tail latency over averages.
- Do not recommend DB logic changes unless DB work is proven or strongly evidenced as a bottleneck.
- Do not recommend caching without repeated-request evidence and an invalidation strategy.
- Do not recommend architecture changes without a strong p90 signal, migration plan, and rollback strategy.
- Only query Context7 for technologies **confirmed** in `package.json`.
- Output goes **only** to `shared/context/research/` — not to `docs/` or the project root.
- If the route cannot be located in the codebase, report that and stop.
