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

> Discover how OpenMAIC resource profiling sets CPU and memory limits for render jobs. Learn about hardware tiers and environment variables for efficient rendering.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-09-13

---

**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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/render-service/src/render-executor.ts) and [`render-service/src/chunk-executor.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.

```typescript
// 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`);

```

```bash

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

docker run -e RENDER_RESOURCE_PROFILE=low-memory openmaic/render-service:latest

```

```typescript
// 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.