# Performance Benchmarks for Open-SEO: Lighthouse Scoring and Thresholds Explained

> Discover Open-SEO performance benchmarks. Learn how Lighthouse scores and thresholds identify optimization opportunities for your web pages.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: performance
- Published: 2026-08-06

---

**Open-SEO evaluates web page performance using Lighthouse scores normalized to a 0-100 scale alongside hard-coded thresholds—such as a 1.5-second Time-to-First-Byte limit—to flag optimization opportunities.**

The `every-app/open-seo` repository is a Cloudflare-based SEO auditing platform that leverages the Lighthouse engine to generate actionable performance metrics. Understanding the **performance benchmarks for open-seo** requires examining how raw Lighthouse data is transformed into stored scores and how specific timing thresholds trigger audit warnings.

## Lighthouse Score Normalization and Categories

Open-SEO does not store raw Lighthouse decimals. Instead, [`src/server/lib/dataforseoLighthousePayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseoLighthousePayload.ts) converts the Lighthouse `categories.performance?.score` (a 0-1 float) into a percentage using `scoreToPercent`, producing the **0-100 scale** used throughout the application【/src/server/lib/dataforseoLighthousePayload.ts†L12-L15】.

The available audit categories are defined in [`src/shared/lighthouse.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/lighthouse.ts), which explicitly lists `"performance"` as a primary category driving the benchmark calculations【/src/shared/lighthouse.ts†L2-L4】.

## Hard-Coded Timing Thresholds

Beyond numeric scores, the platform enforces strict timing benchmarks. In [`src/shared/audit-issues.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-issues.ts), Open-SEO flags a **slow Time-to-First-Byte (TTFB)** when the HTML response exceeds **1.5 seconds** (1500 ms), generating the warning: "The HTML response took over 1.5 seconds. Slow time-to-first-byte drags down every downstream performance metric"【/src/shared/audit-issues.ts†L207-L209】.

## Data Storage and Schema

Performance scores are persisted using the schema defined in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts). The field is defined as `z.number().nullable()`, allowing the database to store integer scores (0-100) or `null` when Lighthouse fails to complete【/src/server/lib/lighthouseStoredPayload.ts†L70-L71】.

## Client-Side Filtering Logic

The audit results UI implements benchmark filtering in [`src/client/features/audit/results/AuditResultsTableFilterLogic.ts`](https://github.com/every-app/open-seo/blob/main/src/client/features/audit/results/AuditResultsTableFilterLogic.ts). This logic handles `null` performance scores by excluding them from numeric comparisons and supports range-based filtering via `minPerf` and `maxPerf` parameters. The code checks `row.performanceScore == null` and applies `matchesRange(row.performanceScore, filters.minPerf, filters.maxPerf)` to enforce user-defined thresholds【/src/client/features/audit/results/AuditResultsTableFilterLogic.ts†L12-L14】.

## Interpreting Performance Scores in Practice

When analyzing results, consider the following benchmark tiers:

- **90-100 (Excellent):** Indicates optimal Core Web Vitals and loading performance.
- **70-89 (Good):** Acceptable performance with minor optimization opportunities.
- **0-69 (Needs Work):** Signals significant speed issues requiring immediate attention.

Any TTFB measurement exceeding the **1.5-second** threshold automatically triggers a warning regardless of the overall Lighthouse score, as this metric directly impacts every downstream performance indicator.

## Code Examples: Working with Performance Benchmarks

The following snippets demonstrate how to retrieve benchmarks, check thresholds, and filter results programmatically:

```typescript
// 1️⃣ Retrieve a page’s Lighthouse performance score (0‑100)
import { getAuditById } from '@/server/lib/audit';
const audit = await getAuditById(auditId);
const perfScore = audit.performanceScore; // e.g., 84

// 2️⃣ Detect a slow TTFB (threshold > 1.5 s)
if (audit.timing?.ttfb && audit.timing.ttfb > 1500) {
  console.warn('Slow TTFB – exceeds 1.5 s benchmark');
}

// 3️⃣ UI filter: only show pages with performance ≥ 80
const filtered = audits.filter(a => 
  a.performanceScore != null && a.performanceScore >= 80
);

```

## Summary

- **Lighthouse Conversion:** Raw 0-1 scores are converted to a 0-100 scale in [`src/server/lib/dataforseoLighthousePayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/dataforseoLighthousePayload.ts).
- **TTFB Threshold:** A hard limit of **1.5 seconds** is enforced in [`src/shared/audit-issues.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-issues.ts).
- **Storage:** Scores are stored as nullable integers via [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts).
- **Filtering:** The UI respects null values and supports min/max range filters as implemented in [`src/client/features/audit/results/AuditResultsTableFilterLogic.ts`](https://github.com/every-app/open-seo/blob/main/src/client/features/audit/results/AuditResultsTableFilterLogic.ts).

## Frequently Asked Questions

### What is the minimum passing performance score in Open-SEO?

While Open-SEO does not enforce a strict "passing" gate, industry standards applied within the platform consider scores below **70** as requiring immediate optimization. The UI filtering logic allows users to set custom minimum thresholds (e.g., 80 or 90) to match their specific quality benchmarks.

### How does Open-SEO handle pages that fail to generate a Lighthouse score?

Pages that fail to run Lighthouse are stored with a `null` performance score according to the schema in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts). The filtering logic in [`src/client/features/audit/results/AuditResultsTableFilterLogic.ts`](https://github.com/every-app/open-seo/blob/main/src/client/features/audit/results/AuditResultsTableFilterLogic.ts) explicitly checks for `row.performanceScore == null` and excludes these rows from numeric range filters to prevent data pollution.

### Why is the Time-to-First-Byte threshold set at 1.5 seconds?

The **1.5-second** TTFB limit defined in [`src/shared/audit-issues.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-issues.ts) aligns with industry best practices for server response times. Exceeding this threshold indicates backend latency that inevitably degrades subsequent metrics like First Contentful Paint and Largest Contentful Paint, making it a reliable early warning signal for infrastructure issues.

### Where is the performance benchmark data stored in the Open-SEO database?

Performance scores are persisted in the database according to the `lighthouseStoredPayload` schema found in [`src/server/lib/lighthouseStoredPayload.ts`](https://github.com/every-app/open-seo/blob/main/src/server/lib/lighthouseStoredPayload.ts). This schema defines the `performance` field as `z.number().nullable()`, ensuring compatibility with the 0-100 integer scale while accommodating failed audits with null values.