Course navigationPhase 31
Volume 08 · Phase 31

Performance

Measure TaskFlow and improve bottlenecks systematically across browser, API, database, cache, and network without sacrificing correctness.

16lessons + labs
4klesson words
12source references
What you will ship

Phase outcome and project increment

Learning outcome

Measure TaskFlow and improve bottlenecks systematically across browser, API, database, cache, and network without sacrificing correctness.

Concrete deliverable

Before/after performance report with measured bottleneck, change, and regression guard.

Figure 31.1 — Where this phase lives in TaskFlow
measure baseline
locate bottleneck
form hypothesis
change one thing
remeasure
add regression guard
Trace the flow left-to-right for implementation and right-to-left for debugging. At every arrow, ask what data crosses the boundary and what proves it is trustworthy.
Instructor mental model

Principles to keep while coding

01

Measure before optimizing so work targets real bottlenecks instead of intuition.

02

Reduce unnecessary network requests, database queries, rendering work, and payload size before reaching for exotic caching.

03

Use indexes and query plans when database latency is the bottleneck.

04

Performance work must preserve correctness, observability, and maintainability.

Code-along path

Guided phase lab

Do these in order. Each step should end with evidence before the next one starts.

  1. 01

    Choose a user-visible flow and collect a baseline instead of optimizing globally.

  2. 02

    Inspect network waterfalls/payloads and frontend rendering for avoidable work.

  3. 03

    Measure API endpoint latency with enough context to separate application and database time.

  4. 04

    Inspect PostgreSQL EXPLAIN/ANALYZE for a representative slow query and validate index/query changes.

  5. 05

    Reduce N+1 or redundant requests before adding caches.

  6. 06

    Record the before/after result and add a budget/test where a regression would matter.

Debugging studio

Failures you should know how to diagnose

Failure drill 1

Optimizing from intuition only

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 2

Caching incorrect data or bypassing authorization

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 3

Adding indexes that slow writes without helping real queries

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Failure drill 4

Benchmarking development mode and assuming production behavior

Predict the symptom, capture evidence at the nearest boundary, change one variable, and verify the same reproduction after the fix.

Watch-order style

Lessons

The source chapters come first. Every phase now ends with a guided build, a debugging workshop, and an independent challenge so reading turns into transferable skill.

01

Performance Budgets and Measurement

Performance Budgets and Measurement Full Stack Developer 2026 Complete - TaskFlow A performance budget turns “fast enough” into a falsifiable statement. TaskFlow separates browser experience

2 min
02

Next.js Rendering Bundles and Core Web Vitals

Next.js Rendering, Bundles, and Core Web Vitals Full Stack Developer 2026 Complete - TaskFlow Next.js already gives TaskFlow useful performance defaults: Server Components do not add client

2 min
03

TanStack Query Network and Render Efficiency

TanStack Query Network and Render Efficiency Full Stack Developer 2026 Complete - TaskFlow TanStack Query already provides structural sharing and tracked-property render optimizations. TaskF

2 min
04

NestJS Fastify API Hot Path

NestJS + Fastify API Hot Path Full Stack Developer 2026 Complete - TaskFlow NestJS with Fastify is already a strong baseline. Most TaskFlow API latency will usually come from database/networ

2 min
05

Prisma Query Shape NPlusOne and Overfetching

Prisma Query Shape, N+1, and Overfetching Full Stack Developer 2026 Complete - TaskFlow Prisma performance depends more on query shape than on whether code lives in a repository. Repository

2 min
06

PostgreSQL EXPLAIN Indexes and Pagination

PostgreSQL EXPLAIN, Indexes, and Pagination Full Stack Developer 2026 Complete - TaskFlow Indexes are workload-specific. PostgreSQL can only choose well when statistics describe the data and

2 min
07

Connection Pooling and Supabase Topology

Connection Pooling and Supabase Topology Full Stack Developer 2026 Complete - TaskFlow Database connections are finite resources. TaskFlow already runs a persistent NestJS API, so the right

2 min
08

Caching Compression Data Locality and Background Work

Caching, Compression, Data Locality, and Background Work Full Stack Developer 2026 Complete - TaskFlow Caching is useful when it removes repeated expensive work and the invalidation model is

2 min
09

Load Testing with Autocannon

Load Testing with Autocannon Full Stack Developer 2026 Complete - TaskFlow Load testing answers a different question from unit/integration testing: how does the assembled system behave when

2 min
10

Performance Regression Testing and CI Budgets

Performance Regression Testing and CI Budgets Full Stack Developer 2026 Complete - TaskFlow Performance tests become useful when they can detect meaningful regressions without creating flaky

2 min
11

Performance Debugging Case Studies

Performance Debugging Case Studies Full Stack Developer 2026 Complete - TaskFlow Case 1 - GET /tasks p95 jumps from 220 ms to 950 ms Trace shows 780 ms in PostgreSQL. Query logs reveal a new

2 min
12

Hands On Lab and Phase Exit

Hands-On Lab and Phase Exit Full Stack Developer 2026 Complete - TaskFlow Lab A - Establish baseline • Run Next.js production build, inspect bundle output, and record Core Web Vitals lab mea

2 min
LAB

Guided Build Lab

Purpose Measure TaskFlow and improve bottlenecks systematically across browser, API, database, cache, and network without sacrificing correctness.

3 min
LAB

Debugging Workshop

Goal Learn to diagnose this phase's failures systematically instead of reinstalling packages, changing random configuration, or copying a fix without understanding it.

2 min
LAB

Phase Synthesis & Independent Challenge

Mission Rebuild the capability of Phase 31 without following the exact code line-by-line. The goal is transfer: can you use the ideas when the variable names, UI, or route shape changes?

2 min
LAB

Mastery Capstone Lab

Integrate Phase 31 without following a transcript.

2 min
Practice ladder

Exercises that increase independence

Guided

Choose a user-visible flow and collect a baseline instead of optimizing globally.

Practice

Measure API endpoint latency with enough context to separate application and database time.

Debug

reproduce and diagnose — Optimizing from intuition only.

Independent

deliver Before/after performance report with measured bottleneck, change, and regression guard.

Explain-back

Can produce a baseline and Can identify bottleneck layer.

Mastery gate

Do not leave the phase only because you reached the bottom

Phase exit criteria

Knowledge check

Scenario and concept quiz

These questions test engineering choices rather than whether you remember a lesson title.

0/0 correct · 0/8 answered
01Which practice best matches Phase 31's engineering goal?
02Which practice best matches Phase 31's engineering goal?
03Which practice best matches Phase 31's engineering goal?
04Which practice best matches Phase 31's engineering goal?
05You are working through the Phase 31 lab. Which next action is the most disciplined step?
06You are working through the Phase 31 lab. Which next action is the most disciplined step?
07You are working through the Phase 31 lab. Which next action is the most disciplined step?
08You are working through the Phase 31 lab. Which next action is the most disciplined step?
Source snapshot

Reference files

Attempt the work first. Use snapshots to compare a checkpoint, not as a substitute for understanding.

reference/TaskFlow_Performance_Snapshot/BENCHMARK_RUNBOOK.md
# Benchmark runbook
1. Build/run production mode; never compare next dev.
2. Reset/seed representative data.
3. Confirm test environment, commit, versions, region, and DB topology.
4. Warm up.
5. Run the exact same scenario (route, token role, concurrency, duration, dataset).
6. Record p50/p95/p99, throughput, non-2xx, CPU/memory, DB latency/connections.
7. Change one variable.
8. Repeat.
9. Keep change only if improvement is meaningful and correctness/security tests pass.
reference/TaskFlow_Performance_Snapshot/PERFORMANCE_BUDGET.md
# TaskFlow performance budget (starting targets)

These are course targets, not universal SLAs. Revisit after production field data exists.

- Core Web Vitals at p75: LCP <= 2.5 s, INP <= 200 ms, CLS <= 0.1.
- GET /tasks p95 API latency <= 300 ms under the recorded normal-load scenario.
- PATCH /tasks/:id p95 <= 400 ms under the recorded normal-load scenario.
- Unexpected 5xx under benchmark <= 1%.
- Query review required for repeated hot-path queries around/above 100 ms or any N+1 pattern.
- No unexplained client bundle regression after dependency changes.
reference/TaskFlow_Performance_Snapshot/README.md
# TaskFlow Phase 31 performance snapshot
Study snapshot only. Performance changes must be measured before/after in the same scenario. Keep correctness, authorization, data isolation, and security tests green.
reference/TaskFlow_Performance_Snapshot/SOURCES.md
# Official/current references used
- https://nextjs.org/docs/app/guides/production-checklist
- https://nextjs.org/docs/app/guides/lazy-loading
- https://nextjs.org/docs/app/getting-started/fonts
- https://www.npmjs.com/package/@next/bundle-analyzer
- https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults
- https://tanstack.com/query/latest/docs/framework/react/guides/render-optimizations
- https://docs.prisma.io/docs/orm/v7/more/best-practices
- https://www.postgresql.org/docs/18/sql-explain.html
- https://www.postgresql.org/docs/18/indexes-multicolumn.html
- https://www.postgresql.org/docs/18/indexes-examine.html
- https://supabase.com/docs/guides/database/connecting-to-postgres/pooling-and-limits
- https://supabase.com/docs/guides/database/connecting-to-postgres
- https://fastify.dev/docs/latest/Guides/Recommendations/
- https://fastify.dev/docs/latest/Reference/Validation-and-Serialization/
- https://web.dev/articles/vitals
- https://www.npmjs.com/package/autocannon
reference/TaskFlow_Performance_Snapshot/VERSION_LOCK.md
# Phase 31 version lock
- Prisma remains course-locked at 7.9.1.
- PostgreSQL 18 documentation is used for planner/index guidance.
- @next/bundle-analyzer 16.3.5 (optional development tool; keep aligned with your Next.js release line).
- autocannon 8.0.0 (benchmark tool).
reference/TaskFlow_Performance_Snapshot/apps/api/src/performance/performance-notes.md
# API hot-path notes
1. Remove unnecessary I/O before micro-optimizing framework code.
2. Keep payloads bounded and projections intentional.
3. Move long-running reports/imports/exports to background workers when the request budget is exceeded.
4. Do not solve DB saturation by blindly increasing connection counts.
reference/TaskFlow_Performance_Snapshot/apps/api/src/tasks/tasks.repository.performance-example.ts
// Example query-shape review: bounded projection + relation projection.
const tasks = await prisma.task.findMany({
  where,
  select: {
    id: true,
    title: true,
    status: true,
    priority: true,
    createdAt: true,
    assignee: { select: { id: true, displayName: true } },
  },
  orderBy: [{ createdAt: 'desc' }, { id: 'asc' }],
  take: pageSize,
  skip,
});
reference/TaskFlow_Performance_Snapshot/apps/web/next.config.performance.ts
import bundleAnalyzer from '@next/bundle-analyzer';

const withBundleAnalyzer = bundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
});

export default withBundleAnalyzer({});
reference/TaskFlow_Performance_Snapshot/apps/web/src/lib/performance/task-list-options.ts
// Example only - keep resource freshness intentional.
export const TASK_LIST_STALE_TIME_MS = 30_000;

// Do not disable structural sharing or tracked-property behavior unless profiling proves a problem.
reference/TaskFlow_Performance_Snapshot/database/task-list-explain.sql
-- Run ANALYZE first when appropriate so planner statistics are current.
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, title, status, priority, "createdAt"
FROM "Task"
WHERE "projectId" = '00000000-0000-4000-8000-000000000001'::uuid
  AND status = 'IN_PROGRESS'
ORDER BY "createdAt" DESC, id ASC
LIMIT 20 OFFSET 0;

-- Candidate only. Measure before/after; do not blindly add indexes.
-- CREATE INDEX CONCURRENTLY ... ON "Task" ("projectId", status, "createdAt" DESC, id);
reference/TaskFlow_Performance_Snapshot/load/tasks-list.ps1
# Requires a valid bearer token in TASKFLOW_TOKEN.
# Run against a disposable/staging environment you are authorized to load test.
pnpm dlx autocannon@8.0.0 `
  -c 20 `
  -d 30 `
  -m GET `
  -H "Authorization=Bearer $env:TASKFLOW_TOKEN" `
  "http://localhost:3001/tasks?page=1&pageSize=20"
reference/TaskFlow_Performance_Snapshot/tests/performance-test-matrix.md
# Performance verification matrix
- Compare production builds, never development mode.
- Record commit, dataset, environment, concurrency, duration, and auth role.
- GET /tasks benchmark captures p50/p95/p99, throughput, errors.
- PATCH /tasks/:id benchmark uses a safe repeatable fixture/workflow.
- Query count check catches accidental N+1 behavior.
- EXPLAIN (ANALYZE, BUFFERS) recorded for hot Task list query.
- Index change measured before/after and validated with correctness tests.
- DB connection usage observed during load.
- Bundle analyzer run after dependency/client-boundary changes.
- Core Web Vitals lab measurement paired with field telemetry when available.
- Security/authorization tests remain green after optimization.