# What Performance Metrics Does OpenSEO Capture via Lighthouse?

> OpenSEO captures key Lighthouse performance metrics like FCP, LCP, and TBT. Discover the exact metrics OpenSEO tracks and stores for your web performance analysis.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: deep-dive
- Published: 2026-09-01

---

**OpenSEO captures four core Lighthouse category scores—Performance, Accessibility, Best Practices, and SEO—alongside eight specific performance timing metrics including First Contentful Paint, Largest Contentful Paint, and Total Blocking Time, storing them as structured data in Cloudflare R2 storage.**

OpenSEO, from the `every-app/open-seo` repository, integrates Google Lighthouse into its automated site auditing workflow to track web performance at scale. Understanding exactly what data points the platform extracts helps developers integrate these metrics into custom monitoring pipelines. This article examines the specific performance indicators OpenSEO captures, the Zod schemas that validate them, and how the system persists this data for longitudinal analysis.

## Core Lighthouse Categories Captured

OpenSEO distills Lighthouse audits into four primary category scores. According to [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts), the system stores these as normalized values between 0 and 1:

- **performance** – Overall page speed and loading efficiency
- **accessibility** – Compliance with accessibility standards
- **best-practices** – Adherence to modern web development best practices
- **seo** – Search engine optimization factors

These scores are stored in the `scores` field of the Lighthouse payload, extracted directly from the raw Lighthouse JSON output.

## Specific Performance Metrics Tracked

Beyond high-level scores, OpenSEO extracts granular timing data defined in the `storedLighthouseMetricsSchema`. Located in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts) (lines 31-38), this schema validates eight critical performance indicators that drive Core Web Vitals and user experience analysis:

- **firstContentfulPaint** – Time when the first text or image is painted
- **largestContentfulPaint** – Time when the largest contentful element is painted
- **totalBlockingTime** – Sum of main-thread blocking time exceeding 50ms
- **cumulativeLayoutShift** – Measure of visual stability during page load
- **speedIndex** – Approximate time when most visible content is fully displayed
- **timeToInteractive** – When the page becomes reliably interactive
- **interactionToNextPaint** – Time from user interaction to next visual update
- **serverResponseTime** – Server response time for the initial document request

Each metric is converted to a `StoredLighthouseMetric` type and stored under the `metrics` field of the payload.

## Lighthouse Issues and Audit Failures

In addition to numeric scores, OpenSEO captures qualitative audit results through the `storedLighthouseIssueSchema` (lines 42-53). This schema records Lighthouse audit failures with three severity levels:

- **critical** – Blocking issues that severely impact user experience
- **warning** – Issues requiring attention but not blocking
- **info** – Recommendations for optimization

These issues enable developers to identify specific performance bottlenecks beyond metric values.

## Schema Validation and Storage Architecture

The data integrity of captured metrics relies on strict Zod schemas defined in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts). The `storedLighthouseMetricsSchema` validates the eight performance timing values, while `storedLighthouseIssueSchema` validates individual audit failures.

After validation, the compact payload is persisted to Cloudflare R2 storage via [`src/server/lib/lighthousePayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthousePayload.ts). This implementation creates a unique R2 key for each audit result and stores the JSON payload containing scores, metrics, and issues. The storage strategy separates raw Lighthouse JSON from the processed, queryable data structure used by the application.

## Retrieving Metrics Programmatically

Developers can access stored Lighthouse data through server functions or direct R2 reads. The primary interface resides in [`src/serverFunctions/lighthouse.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/lighthouse.ts), which exposes type-safe retrieval methods.

To fetch Lighthouse data for a specific audit result:

```typescript
// src/serverFunctions/lighthouse.ts
import { getAuditLighthouseData } from "@/server/lib/audit/lighthouse";
import {
  lighthouseAuditExportSchema,
  lighthouseAuditIssueSchema,
} from "@/types/schemas/lighthouse";

export async function getLighthouseReport(input: { resultId: string }) {
  // Validate input against schema
  lighthouseAuditExportSchema.parse(input);

  // Fetch stored payload containing metrics and scores
  const lighthouse = await getAuditLighthouseData({
    id: input.resultId,
  });

  return {
    scores: lighthouse.scores,     // performance, accessibility, best-practices, seo
    metrics: lighthouse.metrics,   // FCP, LCP, TBT, CLS, etc.
    issues: lighthouse.issues,     // array of issue objects with severity
  };
}

```

For custom reporting pipelines that require raw payload access, read the object directly from R2 using the key stored on the site record:

```typescript
import { readR2Object } from "@/server/lib/r2";

export async function fetchRawLighthousePayload(r2Key: string) {
  const raw = await readR2Object(r2Key);
  return JSON.parse(raw);
}

```

## Audit Workflow Integration

The Lighthouse capture process integrates into broader site audits through [`src/server/workflows/siteAuditWorkflowPhases.ts`](https://github.com/every-app/open-seo/blob/main/src/server/workflows/siteAuditWorkflowPhases.ts). This orchestrator controls whether Lighthouse executes based on the `lighthouseStrategy` configuration, allowing conditional performance auditing depending on site settings or crawl budgets.

When enabled, the workflow triggers Lighthouse analysis, processes the raw JSON through the stored payload schemas, and persists the compact representation to R2 for UI consumption and trend analysis.

## Summary

- OpenSEO captures **four category scores** (Performance, Accessibility, Best Practices, SEO) and **eight specific timing metrics** (FCP, LCP, TBT, CLS, Speed Index, TTI, INP, and server response time)
- Data validation occurs through **Zod schemas** defined in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts)
- Metrics and issues are persisted to **Cloudflare R2** as compact JSON payloads
- Programmatic access is available via `getAuditLighthouseData` in server functions
- Audit execution is controlled by the `lighthouseStrategy` configuration in workflow phases

## Frequently Asked Questions

### What specific Lighthouse performance metrics does OpenSEO store?

OpenSEO stores eight specific timing metrics defined in `storedLighthouseMetricsSchema`: First Contentful Paint, Largest Contentful Paint, Total Blocking Time, Cumulative Layout Shift, Speed Index, Time to Interactive, Interaction to Next Paint, and Server Response Time. These represent the most actionable web vitals for performance optimization.

### Where does OpenSEO persist Lighthouse audit results?

OpenSEO stores processed Lighthouse data in Cloudflare R2 storage. The [`src/server/lib/lighthousePayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthousePayload.ts) file handles creation of the payload filename and persistence, while the raw processed data is stored as JSON objects referenced by R2 keys stored in the site audit records.

### How can I access Lighthouse data programmatically in OpenSEO?

Use the `getAuditLighthouseData` function from `@/server/lib/audit/lighthouse`, passing the audit result ID. This retrieves the structured payload containing scores, metrics, and issues. Alternatively, use `readR2Object` from `@/server/lib/r2` with the stored R2 key to access the raw JSON payload directly.

### Does OpenSEO capture all Lighthouse audits or just specific ones?

OpenSEO captures a curated subset focused on actionable data. It stores the four main category scores, eight critical performance timing metrics, and specific audit failures classified as critical, warning, or info severity. This curated approach reduces storage overhead while preserving the metrics most relevant for tracking site performance trends.