How OpenMAIC Resource Profiling Determines CPU and Memory Limits for Render Jobs

OpenMAIC determines CPU and memory limits by resolving a resource profile at startup via the resolveResourceProfile function, which selects from predefined hardware tiers based on the RENDER_RESOURCE_PROFILE environment variable or automatically based on available system RAM, then enforces these constraints through validation logic in render-service/src/resource-profile.ts.

The OpenMAIC repository implements sophisticated resource management for its render service to prevent job overload on constrained hardware. Resource profiling acts as the gatekeeper, automatically calculating appropriate worker counts and memory boundaries before any rendering begins. Understanding how the system selects and applies these profiles ensures optimal performance across diverse deployment environments.

Profile Selection Logic

The entry point for limit determination is the resolveResourceProfile function exported from render-service/src/resource-profile.ts. This function implements a two-tier selection strategy that balances explicit operator control with automatic hardware detection.

Explicit Environment Variable Configuration

When operators need deterministic resource allocation, they can set the RENDER_RESOURCE_PROFILE environment variable to a specific profile name (such as low-memory, standard, or high-performance). The resolver looks up this value in the static PROFILES map and returns the corresponding configuration object immediately. This approach is critical for containerized deployments where memory limits are explicitly capped regardless of host capacity.

Automatic Memory-Based Detection

If RENDER_RESOURCE_PROFILE is undefined, the system falls back to automatic selection by inspecting the host's available RAM. The code retrieves memory statistics (via process.memoryUsage() or process.env.NODE_TOTAL_MEMORY) and compares the detected capacity in GiB against each profile's minimumMemoryBytes threshold. The resolver selects the first profile whose memory requirement is satisfied, ensuring low-resource machines default to conservative limits while high-capacity servers unlock maximum concurrency.

Profile Structure and Hard Limits

Each entry in the PROFILES dictionary (defined in render-service/src/resource-profile.ts) represents a hardware tier with explicit caps on CPU utilization and memory reservation.

CPU Concurrency Controls

Resource profiles define granular limits on parallel execution through several numeric fields:

  • producerWorkers – The number of worker processes the render producer may spawn.
  • maxConcurrency – The total simultaneous render tasks the service will execute across all queues.
  • maxConcurrentExtractions – Parallel extraction jobs allowed during asset processing.
  • maxChunkWorkers and maxParallelChunks – Limits governing the chunk-processing pipeline's worker pool.

These values directly constrain thread pool sizing in render-service/src/render-executor.ts and render-service/src/chunk-executor.ts, preventing CPU thrashing on overloaded hosts.

Memory Requirements and Preview Constraints

The minimumMemoryBytes field establishes a hard floor for profile eligibility during automatic selection. Profiles also specify maxPreviewPixels and maxPreviewDeviceScaleFactor to cap memory-intensive preview generation operations, ensuring that auxiliary rendering tasks do not exhaust the heap allocated to the main job.

Validation and Runtime Enforcement

Selecting a profile is only the first step; OpenMAIC validates the configuration against runtime environment variables to prevent mismatched overrides.

Startup Validation via validateResourceProfileStartup

After resolution, the validateResourceProfileStartup function (also in render-service/src/resource-profile.ts) cross-checks the selected profile against explicit environment overrides such as PRODUCER_MAX_WORKERS or RENDER_MAX_CONCURRENCY. If an override exceeds the profile's defined limit, the function throws a configuration error with a descriptive message, forcing the operator to select a higher-tier profile rather than silently ignoring the constraint.

Runtime Configuration Integration

The resolved profile propagates through the system via render-service/src/config.ts, which exposes the profile object as config.resourceProfile. Downstream components reference this configuration object to initialize their worker pools:

  • Render Executor – Uses profile.producerWorkers to size the producer process pool.
  • Chunk Executor – Applies profile.maxChunkWorkers and profile.maxParallelChunks to throttle parallel chunk processing.

This centralized propagation ensures that every subsystem respects the CPU and memory boundaries established at startup.

Practical Implementation Examples

The following patterns demonstrate how to interact with the resource profiling system in OpenMAIC deployments.

// Resolve the active profile at service startup
import { resolveResourceProfile } from './render-service/src/resource-profile.js';

const profile = resolveResourceProfile(process.env);
console.log(`Active profile: ${profile.name}`);
console.log(`Worker slots: ${profile.producerWorkers}`);
console.log(`Memory floor: ${profile.minimumMemoryBytes} bytes`);

# Force the low-memory profile in a constrained container environment

docker run -e RENDER_RESOURCE_PROFILE=low-memory openmaic/render-service:latest
// Initialize chunk processing with profile-derived limits
import { publicResourceProfile } from './render-service/src/resource-profile.js';
import { ChunkExecutor } from './render-service/src/chunk-executor.js';

const profile = publicResourceProfile();
const executor = new ChunkExecutor({
  workers: profile.maxChunkWorkers,
  parallelChunks: profile.maxParallelChunks,
  maxMemoryMB: profile.minimumMemoryBytes / (1024 * 1024)
});

Summary

  • OpenMAIC selects resource profiles through resolveResourceProfile in render-service/src/resource-profile.ts, checking the RENDER_RESOURCE_PROFILE environment variable first, then falling back to RAM-based auto-detection.
  • Each profile defines concrete CPU limits (producerWorkers, maxConcurrency, maxChunkWorkers) and memory floors (minimumMemoryBytes) tailored to specific hardware tiers.
  • The validateResourceProfileStartup function prevents startup when environment overrides conflict with profile ceilings, ensuring operational safety.
  • Runtime enforcement occurs via config.resourceProfile in render-service/src/config.ts, which worker pools in the render and chunk executors consume to size their threads appropriately.

Frequently Asked Questions

What environment variable controls the resource profile selection?

The RENDER_RESOURCE_PROFILE environment variable explicitly sets the active profile by name (e.g., standard, low-memory). When unset, the system automatically selects a profile based on available system memory compared against each profile's minimumMemoryBytes threshold.

How does OpenMAIC handle machines with insufficient memory?

If no profile's minimumMemoryBytes requirement is met by the detected system RAM, resolveResourceProfile typically defaults to the most restrictive available profile or throws a configuration error depending on the specific implementation version, ensuring the service does not attempt to allocate resources the host cannot provide.

Can individual limits be overridden after profile selection?

While environment variables like PRODUCER_MAX_WORKERS can suggest higher limits, the validateResourceProfileStartup function in render-service/src/resource-profile.ts validates these against the selected profile. If an override exceeds the profile's defined maximum, the service exits with an error rather than violating the established resource contract.

Where is the profile validation logic implemented?

The validation logic resides in the validateResourceProfileStartup function within render-service/src/resource-profile.ts. This function ensures that any environment variable overrides align with the resolved profile's constraints before the render service begins accepting jobs.

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 →