# What Are the Page Limits for Site Audits in OpenSEO?

> Discover OpenSEO site audit page limits for free and paid users. Learn how OpenSEO manages audit scope to provide efficient SEO analysis and actionable insights.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: api-reference
- Published: 2026-09-10

---

**OpenSEO enforces strict page limits of 50 pages for free users and 5,000 pages for paid subscribers, with these thresholds defined as constants in [`src/shared/audit-limits.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-limits.ts) and enforced across both client and server components.**

OpenSEO is an open-source SEO auditing tool that crawls websites to identify technical issues. The application, maintained in the `every-app/open-seo` repository, implements hard caps on crawl size to manage infrastructure costs and ensure fair usage across different subscription tiers. Understanding these limits is essential for developers integrating the audit API or self-hosting the platform.

## Understanding OpenSEO Site Audit Page Limits

The codebase defines two primary thresholds that control how many pages can be crawled during a single site audit.

### Free Plan Limit: 50 Pages

Free-tier users are restricted to **50 pages per audit**. This constraint is implemented via the `FREE_MAX_AUDIT_PAGES` constant. When a user initiates a crawl without an active paid subscription, the system validates that the requested `maxPages` value does not exceed this 50-page threshold.

### Paid Plan Limit: 5,000 Pages

Subscribers on paid plans can audit up to **5,000 pages per crawl**. This higher limit is controlled by the `PAID_MAX_AUDIT_PAGES` constant. The application checks the user's subscription status before applying this expanded quota.

## Where Page Limits Are Defined

The authoritative source for these constraints resides in the shared constants file:

```typescript
// src/shared/audit-limits.ts
export const FREE_MAX_AUDIT_PAGES = 50;
export const PAID_MAX_AUDIT_PAGES = 5000;

```

These values are imported throughout the application to maintain consistency between the user interface and backend validation logic. By centralizing these limits in a shared module, OpenSEO ensures that both client-side previews and server-side enforcement remain synchronized.

## How Limits Are Enforced Across the Stack

OpenSEO implements a multi-layered validation strategy to prevent limit violations.

### Client-Side UI Constraints

The audit launch interface dynamically adjusts available options based on the user's plan. In [`src/client/features/audit/launch/LaunchFormCard.tsx`](https://github.com/every-app/open-seo/blob/main/src/client/features/audit/launch/LaunchFormCard.tsx), the application imports both constants and selects the appropriate limit:

```typescript
// src/client/features/audit/launch/LaunchFormCard.tsx
import { FREE_MAX_AUDIT_PAGES, PAID_MAX_AUDIT_PAGES } from "@/shared/audit-limits";

const maxPages = isFreePlan ? FREE_MAX_AUDIT_PAGES : PAID_MAX_AUDIT_PAGES;

```

This approach prevents users from submitting requests that exceed their tier capabilities before the data even reaches the server.

### Server-Side Validation

The audit capacity service performs authoritative checks before initiating any crawl. Located in [`src/server/features/audit/services/audit-capacity.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/audit/services/audit-capacity.ts), this logic ensures that the requested page count complies with the user's subscription tier:

```typescript
// src/server/features/audit/services/audit-capacity.ts
import { PAID_MAX_AUDIT_PAGES, FREE_MAX_AUDIT_PAGES } from "@/shared/audit-limits";

export function canRunAudit(requestedPages: number, isPaid: boolean) {
  const limit = isPaid ? PAID_MAX_AUDIT_PAGES : FREE_MAX_AUDIT_PAGES;
  return requestedPages <= limit;
}

if (audit.maxPagesPerAudit > FREE_MAX_AUDIT_PAGES) {
  // reject or prompt upgrade
}

```

### Error Messaging

When a user attempts to exceed their limit, the system returns a specific error defined in [`src/client/lib/error-messages.ts`](https://github.com/every-app/open-seo/blob/main/src/client/lib/error-messages.ts):

```typescript
// src/client/lib/error-messages.ts
export const ERROR_MESSAGES = {
  AUDIT_PAGE_LIMIT_EXCEEDED: `Free plan audits are limited to ${FREE_MAX_AUDIT_PAGES} pages. Upgrade to run larger audits.`,
};

```

This message is displayed when the audit service rejects a request that violates the page constraints.

## Practical Code Examples

### Starting an Audit With Limit Checking

When initiating an audit from the client side, developers should handle potential limit violations:

```typescript
// Example: Starting an audit (client side)
import { startAudit } from "@/client/api";
import { FREE_MAX_AUDIT_PAGES } from "@/shared/audit-limits";

const start = async (url: string) => {
  const response = await startAudit({ 
    startUrl: url, 
    maxPages: FREE_MAX_AUDIT_PAGES 
  });
  
  if (response.error?.code === "AUDIT_PAGE_LIMIT_EXCEEDED") {
    alert(response.error.message); // Shows the limit warning
  }
};

```

### Server-Side Capacity Verification

For custom server implementations, validate requests against the appropriate constant:

```typescript
// Example: Server-side capacity check (audit-capacity service)
import { PAID_MAX_AUDIT_PAGES, FREE_MAX_AUDIT_PAGES } from "@/shared/audit-limits";

export function validateAuditRequest(requestedPages: number, isPaid: boolean) {
  const limit = isPaid ? PAID_MAX_AUDIT_PAGES : FREE_MAX_AUDIT_PAGES;
  
  if (requestedPages > limit) {
    throw new Error(`Audit exceeds page limit. Maximum allowed: ${limit}`);
  }
  
  return true;
}

```

## Summary

- **OpenSEO** enforces hard page limits of **50 pages for free users** and **5,000 pages for paid subscribers**.
- Limits are defined as constants `FREE_MAX_AUDIT_PAGES` and `PAID_MAX_AUDIT_PAGES` in [`src/shared/audit-limits.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-limits.ts).
- The **client-side UI** in [`LaunchFormCard.tsx`](https://github.com/every-app/open-seo/blob/main/LaunchFormCard.tsx) restricts input options based on subscription status.
- **Server-side validation** in [`audit-capacity.ts`](https://github.com/every-app/open-seo/blob/main/audit-capacity.ts) authoritatively rejects requests exceeding tier thresholds.
- Violations trigger the `AUDIT_PAGE_LIMIT_EXCEEDED` error with messaging from [`src/client/lib/error-messages.ts`](https://github.com/every-app/open-seo/blob/main/src/client/lib/error-messages.ts).

## Frequently Asked Questions

### What happens if I try to audit more pages than my plan allows?

The audit request will be rejected before crawling begins. The server returns an `AUDIT_PAGE_LIMIT_EXCEEDED` error code with a message indicating the specific limit for your plan. For free users, this message states that audits are limited to 50 pages and suggests upgrading to run larger audits.

### Can I increase the page limits for self-hosted OpenSEO instances?

Yes. Since OpenSEO is open-source under the `every-app/open-seo` repository, self-hosted instances can modify the constants in [`src/shared/audit-limits.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-limits.ts). Change `FREE_MAX_AUDIT_PAGES` or `PAID_MAX_AUDIT_PAGES` to your desired values and rebuild the application. Note that increasing these limits may require corresponding infrastructure adjustments to handle larger crawls.

### How does OpenSEO differentiate between free and paid users during limit checks?

The application checks subscription status through the `isPaid` boolean flag, which is evaluated in both the client and server components. In [`src/client/features/audit/launch/LaunchFormCard.tsx`](https://github.com/every-app/open-seo/blob/main/src/client/features/audit/launch/LaunchFormCard.tsx), this flag determines which constant (`FREE_MAX_AUDIT_PAGES` or `PAID_MAX_AUDIT_PAGES`) is applied to the UI. The server independently verifies this status in [`src/server/features/audit/services/audit-capacity.ts`](https://github.com/every-app/open-seo/blob/main/src/server/features/audit/services/audit-capacity.ts) to prevent client-side tampering from bypassing restrictions.

### Are page limits per audit or per month?

The limits described in [`src/shared/audit-limits.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/audit-limits.ts) apply **per individual audit crawl**, not as a monthly aggregate. Each time you initiate a site audit, the requested page count must fall within your plan's threshold (50 or 5,000 pages). The [`audit-capacity.ts`](https://github.com/every-app/open-seo/blob/main/audit-capacity.ts) service validates these constraints on a per-request basis.