Performance Benchmarks for Terax AI: Bundle Size, Memory Footprint, and Runtime Metrics

Terax AI maintains a 7–8 MiB bundle size, caps renderer slots at 5 per pool, and keeps per-tab memory under 30 MiB through intelligent resource pooling and lazy-loaded architecture.

Terax AI is engineered as an ultra-lightweight terminal application that prioritizes runtime efficiency over heavyweight dependencies. According to the crynta/terax-ai source code, the project enforces strict performance benchmarks across bundle size, renderer memory pools, and per-tab resource consumption. These metrics ensure the application remains responsive on low-end hardware while delivering a full-featured terminal experience.

Bundle Size Benchmarks

The compiled web-view bundle for Terax AI measures approximately 7–8 MiB uncompressed, or roughly 2 MiB when gzipped. This minimal footprint is achieved through architectural decisions found in TERAX.md and the core source tree:

  • WebGL rendering via xterm.js: The terminal uses hardware-accelerated rendering without importing additional graphics libraries
  • Dependency-light TypeScript: Core logic resides in pure functions under src/modules/*/lib/, avoiding bloated third-party dependencies
  • Deferred feature loading: Optional components like language-server clients and AI providers remain outside the eager bundle until explicitly enabled by the user

Runtime Performance Architecture

The runtime performance of Terax AI relies on aggressive resource capping and intelligent memory reuse. The implementation in src/modules/terminal/lib/rendererPool.ts and src/modules/terminal/lib/useTerminalSession.ts establishes concrete limits on CPU and RAM usage.

Renderer Pool Management

The renderer pool maintains a maximum of 5 hidden renderer slots that are reused across terminal tabs. Only the active leaf receives render resources, while idle slots are automatically reclaimed after approximately 30 seconds (SLOT_STALE_MS). The pool uses performance.now() to timestamp slot usage, ensuring stale slots are discarded without maintaining extra timer threads.

When a leaf loses its renderer slot, its output history is preserved in a DormantRing buffer—a fixed-size 1 MiB circular buffer implemented in src/modules/terminal/lib/rendererPool.ts that avoids expensive full snapshots while allowing quick restoration when the tab becomes active again.

Memory Accounting and IPC Optimization

Memory monitoring occurs through src/modules/terminal/lib/useTerminalSession.ts, which checks performance.memory (when available in the browser environment) to track heap usage and prevent runaway allocations. Empirical measurements via Chrome DevTools show a typical per-tab memory footprint of less than 30 MiB, including PTY buffers.

All operating system interactions—spanning PTY processes, file-system operations, git commands, and AI inference—traverse a single-command Tauri IPC channel. This design minimizes round-trips and keeps the UI thread unblocked for rendering tasks.

Measured Performance Metrics

The following benchmarks are enforced in the current codebase:

  • Bundle size: 7–8 MiB (≈2 MiB gzipped) as documented in TERAX.md
  • Renderer pool capacity: Maximum 5 concurrent slots in src/modules/terminal/lib/rendererPool.ts
  • DormantRing buffer size: 1 MiB per inactive leaf
  • Slot staleness threshold: ~30 seconds (SLOT_STALE_MS)
  • Per-tab memory footprint: <30 MiB including PTY buffers

Practical Code Examples

Measuring Render Cycle Latency

You can instrument terminal render cycles using performance.now() to verify runtime performance:

import { useEffect, useRef } from "react";

export function TerminalRenderTimer() {
  const startRef = useRef<number>(0);

  useEffect(() => {
    // Called just before the xterm.js render pass
    startRef.current = performance.now();

    return () => {
      // Called after the render pass completes
      const duration = performance.now() - startRef.current;
      console.log(`Terminal rendered in ${duration.toFixed(2)} ms`);
    };
  }, []);

  return null;
}

Querying Renderer Pool Slot Ages

Monitor slot utilization directly from the renderer pool internals:

import { getRendererPool } from "@/modules/terminal/lib/rendererPool";

export function logSlotAges() {
  const pool = getRendererPool();
  pool.slots.forEach((slot, i) => {
    const age = performance.now() - slot.lastUsedAt;
    console.log(`Slot ${i} age: ${age.toFixed(0)} ms`);
  });
}

Monitoring Heap Usage

Implement memory accounting similar to useTerminalSession.ts:

import { useEffect } from "react";

export function useMemoryMonitor() {
  useEffect(() => {
    const mem = (performance as any).memory;
    if (mem) {
      console.log(
        `JS heap: ${(mem.usedJSHeapSize / 1024 / 1024).toFixed(2)} MiB / ${(mem.totalJSHeapSize / 1024 / 1024).toFixed(2)} MiB`
      );
    }
  }, []);
}

Summary

  • Terax AI distributes a 7–8 MiB production bundle (≈2 MiB gzipped) by leveraging WebGL rendering and deferred AI provider loading via src/modules/ai/config.ts
  • The renderer pool caps active slots at 5 and reclaims stale resources after 30 seconds to limit memory pressure
  • A 1 MiB DormantRing buffer preserves terminal history for inactive tabs without consuming renderer resources
  • Per-tab memory remains under 30 MiB through performance.memory monitoring and single-channel Tauri IPC optimization
  • Optional features incur zero cost until enabled, ensuring baseline resource consumption remains minimal

Frequently Asked Questions

What is the maximum bundle size for Terax AI deployments?

The compiled web-view bundle is capped at 7–8 MiB uncompressed, or approximately 2 MiB when served with gzip compression. This limit is enforced by the project's dependency-light architecture and lazy-loading strategy for AI providers defined in src/modules/ai/config.ts.

How does Terax AI manage memory for multiple terminal tabs?

Terax AI implements a renderer pool limited to 5 slots that are time-stamped with performance.now() in src/modules/terminal/lib/rendererPool.ts. Slots unused for roughly 30 seconds (SLOT_STALE_MS) are automatically discarded, while their content is archived in a 1 MiB DormantRing buffer to prevent data loss without retaining GPU resources.

Why does Terax AI cap renderer slots instead of creating unlimited terminals?

Capping renderer slots at 5 prevents GPU memory exhaustion and UI thread blocking on low-end hardware. By reusing slots across tabs and only rendering the active leaf, the application maintains responsive performance while keeping per-tab memory under 30 MiB according to benchmarks in TERAX.md.

How can developers verify Terax AI performance metrics in production?

Developers can import measurement utilities from src/modules/terminal/lib/rendererPool.ts to check slot ages, or use the performance.memory API (as implemented in src/modules/terminal/lib/useTerminalSession.ts) to monitor heap usage in supported Chromium-based environments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →