Skip to content

About

k6 and TypeScript performance testing framework with governed workloads, reviewed baselines, observability, reports, and GitHub Actions performance gates.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

170 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

k6 Performance Framework

PR smoke Quality Security Main load Performance reports Release k6 TypeScript

Performance engineering as a governed system: typed k6 workloads, controlled targets, SLO-based gates, reviewed regression baselines, Grafana/InfluxDB observability, OpenTelemetry, and six distinct workload models for the RealWorld API.

Reviewer Proof

Evidence Direct link
Live reports Published performance evidence
Current release v0.4.0
Primary CI Main load workflow
Shared product target Bounded isolated load profile · Workflow
Safety and quality Quality · Security
Repository activity Default-branch commits · Pull requests
Architecture and decisions Architecture · ADR index
Failure evidence Threshold failure example · Interpretation guide
Controlled latency study Controlled latency experiment protocol and artifact workflow · Controlled latency CI runs
Reviewed baseline report Human-openable load report

Performance framework evidence overview

What This Framework Proves

Engineering question Implemented answer
How is unsafe load prevented? Public targets are read-only; sustained and write-heavy workloads require a controlled target and explicit override.
How are regressions distinguished from noise? Not reliably yet: the PR comparison is advisory (baseline/gate-mode.json) because the committed baseline's source inputs are unavailable and same-commit spread on shared runners exceeded its 20% tolerance. Recalibration is planned under docs/experiments/.
How is performance made diagnosable? Tagged metrics, JSON and Markdown summaries, Grafana/InfluxDB dashboards, and OpenTelemetry export.
How does the suite model different risks? Smoke, load, stress, spike, soak, and breakpoint workloads with separate intent and thresholds.
How does CI remain credible? Quality, security, main-load, reports, scheduled-soak, and release gates publish durable evidence.

Release Summary

Release v0.4.0 establishes the governed performance reference: controlled load targets, advanced workload gates, regression tooling, report publication, observability capture, security scanning, and documented operational limits. See release notes and the changelog.

Architecture

flowchart LR
  T["k6 test entry points"] --> S["Reusable scenarios"]
  S --> A["Typed API services"]
  A --> H["Tagged HTTP client"]
  H --> R["RealWorld API"]
  T --> O["JSON and Markdown summaries"]
  T --> I["InfluxDB v2"]
  T --> C["OpenTelemetry Collector"]
  I --> G["Grafana dashboard"]
  O --> P["CI gates and GitHub Pages"]
Loading

Tests never call k6/http directly. Endpoint services own paths, payload envelopes, authentication, and stable metric names. Write-heavy tests reject non-local targets unless explicitly overridden.

Test Types

Type Purpose Default target Command
Smoke Fast API and SLO validation Hosted API, read-only TARGET_ENV=staging npm run smoke
Load Expected traffic and user journeys Controlled local API npm run load
Stress Progressive degradation Controlled local API npm run stress
Spike Sudden traffic and recovery Controlled local API npm run spike
Soak Long-duration stability Controlled local API npm run soak
Breakpoint Capacity boundary Controlled local API npm run breakpoint

Use npm run breakpoint:search to run a binary-search capacity probe. Its JSON output reports lastHealthyVus, firstUnhealthyVus, and toleranceVus.

To inspect retained summaries without starting a load test, run the offline diagnostics panel:

npm run capacity:analyze -- --plan tests/fixtures/capacity-evidence/plan.json --out /tmp/capacity-evidence

The included plan is authored fixture data. It demonstrates bounded target-pressure and missing-data handling; it is not a measured capacity claim. See breakpoint evidence and limits.

Controlled Load Service Objectives

Scale and Scope

These objectives are controlled-target guardrails for a local RealWorld backend running on a GitHub-hosted Ubuntu runner. They are not production service SLOs and should not be compared to internet-facing latency targets. The reviewed baseline represents a 20-arrival-iterations/s journey profile with 100 max VUs; each iteration can make multiple HTTP requests. Historical targetRps fields contain iteration rates, not fixed request throughput. See the human-openable load report for the source workflow, target commit, framework commit, and measured percentiles.

Use TARGET_ITERATIONS_PER_SECOND to configure the existing journey. TARGET_RPS now fails with a migration message rather than silently changing units. For a separate one-request-per-arrival experiment, run npm run load:500rps against your owned local target; its report separates warm-up from achieved measurement load. See workload units and verification. Neither a configured rate nor a passing counting fixture proves application capacity.

Endpoint group p95 p99 Error rate
Authentication < 800 ms < 1500 ms < 1%
Article reads < 10 ms < 20 ms < 1%
Article writes < 1000 ms < 2000 ms < 2%
Comment reads < 5 ms < 10 ms < 2%
Profiles < 5 ms < 10 ms < 1%
Tags < 5 ms < 10 ms < 1%

See performance SLOs for enforcement details. The hosted read-only smoke test uses wider network-facing guardrails defined separately in config/thresholds/smoke.ts.

Quick Start

Prerequisites: Node.js 24.21.0 (see .nvmrc), npm 10.9.4, k6 2.0+, Docker Desktop, and Docker Compose.

npx --yes npm@10.9.4 ci
npm run typecheck
npm run lint
npm run test:unit
npm run build

Run the read-only validation profile:

TARGET_ENV=staging TEST_PROFILE=validation SUMMARY_NAME=smoke npm run smoke
$env:TARGET_ENV = 'staging'
$env:TEST_PROFILE = 'validation'
$env:SUMMARY_NAME = 'smoke'
npm run smoke

Start observability and run a local observed load:

npm run docker:up
npm run docker:health
npm run load:observed
npm run observability:capture

Grafana is available at http://localhost:3001 with local credentials admin / admin. Grafana evidence is produced by local observed runs because GitHub-hosted CI does not persist a remote InfluxDB. CI publishes JSON, Markdown, and Pages artifacts instead.

Authenticated scenarios create a disposable setup user against an authorized writable target:

export TARGET_ENV=local
export BASE_URL=http://localhost:3000/api
export TEST_PROFILE=validation
npm run load:journey
$env:TARGET_ENV = 'local'
$env:BASE_URL = 'http://localhost:3000/api'
$env:TEST_PROFILE = 'validation'
npm run load:journey

Set AUTH_USER_COUNT to size the setup user pool. VUs select credentials deterministically from that pool, avoiding a single-account bottleneck. Full non-local workloads also require explicit K6_STAGES; built-in full profiles are limited to the controlled local target.

CI and Evidence

  • PR smoke posts an aggregate Markdown summary to same-repository pull requests.
  • Main load, regression, and advanced workload workflows provision a pinned RealWorld backend.
  • Load regression checks compare aggregate, endpoint, and business-metric p95/p99 values with the committed baseline, but the comparator refuses a baseline without accepted provenance, and the comparison is advisory (baseline/gate-mode.json): it prints an ADVISORY line and a warning instead of failing. Full advanced runs compare with their latest compatible retained run.
  • Release publication waits for full stress, spike, soak, and breakpoint evidence.
  • GitHub-hosted segmented validation proves partition wiring; the manual distributed workflow is reserved for authorized self-hosted runners and a shared controlled target.
  • Security CI runs npm audit, creates a CycloneDX SBOM, and scans the lockfile with OSV.
  • Published performance reports

This is the most CI-heavy repository in the portfolio; see the CI workflow map for what each workflow is for and why it exists as a separate gate.

Documentation

Safety

Public endpoints are restricted to short read-only checks. Authenticated writes and sustained load default to a local target and require ALLOW_NON_LOCAL_LOAD=true elsewhere. Tokens, generated runtime reports, and unreviewed baseline captures are excluded from version control. The local observability stack ships with development credentials and anonymous Grafana viewer access; keep those ports local or rotate credentials before exposing the stack.

About

k6 and TypeScript performance testing framework with governed workloads, reviewed baselines, observability, reports, and GitHub Actions performance gates.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages