OGXOGX

Performance

Real-world benchmarks and optimization strategies

OGX is engineered for speed. This page documents real-world performance metrics and provides strategies to optimize your OG image generation.

Benchmark Results

The following benchmarks were run on Node.js 24 with 100 iterations per scenario.

ScenarioMeanMedianP90Notes
Minimal Preset39.23ms38.46ms42.68msFast and lightweight, perfect for simple images and blogs.
Social Preset55.63ms54.89ms58.91msRich gradients and layouts with optimized rendering.
Docs Preset46.96ms46.11ms50.98msIdeal for documentation pages or content-heavy layouts.
Custom Layout47.5ms46.8ms52.1msBuilder API performs similarly to presets.
With Cache0.03ms0.02ms0.04ms1000x faster than cold render. Instant retrieval via LRU cache.

[!TIP] Cache v2 provides sub-millisecond response times using FNV-1a hashing and LRU eviction.

Why OGX is Fast

1. No Browser Required

Unlike Puppeteer-based solutions, OGX uses Satori for layout and Resvg for rasterization—both are native/WASM-based and don't require a browser instance.

2. Parser v2 with O(1) Lookups

OGX uses a high-performance parser with Map-based lookup tables for ~170 static classes. Dynamic classes are handled by modular prefix handlers. Multi-level caching ensures parsed classes are reused across elements.

3. Cache v2 with LRU Eviction

Fast sync hashing using FNV-1a (~20x faster than SHA-256) combined with O(1) LRU eviction. Memory-bounded with configurable TTL support.

Optimization Strategies

Use Simpler Presets

All presets in v0.2.0 are optimized for performance:

// Fastest (~39ms)
await ogx({ preset: "minimal", title: "Hello" });

// Fast (~55ms)
await ogx({ preset: "social", title: "Hello", brand: "OGX" });

// Fast (~47ms)
await ogx({ preset: "docs", title: "Documentation" });

Enable Caching

Always enable caching in production for repeated configurations:

await ogx({
  preset: "docs",
  title: "My Page",
  cache: true, // Enable built-in cache
});

Pre-register Fonts

Register fonts before rendering to avoid per-request font loading:

import { fontRegistry } from "@ogxjs/core";

// Do this once at startup
await fontRegistry.registerInterFromUrl([400, 700]);

Use Static Generation

In Next.js, prefer static generation over on-demand rendering:

// app/og/[slug]/route.ts
export const dynamic = "force-static";
export const revalidate = 3600; // Revalidate every hour

export async function GET(req: Request) {
  return ogxResponse({ preset: "docs", title: "..." }, req);
}

Run Benchmarks Yourself

You can run the official benchmarks locally:

pnpm -F @ogxjs/core bench

This will generate:

  • benchmarks/results.json - Raw data
  • benchmarks/BENCHMARKS.md - Formatted report

Environment

Benchmarks were run on:

  • Runtime: Node.js v24.12.0
  • Platform: Linux (x64)
  • Iterations: 100 per scenario

On this page