Title: Memory exhaustion in loop executions with agent blocks making tool calls · Issue #2525 · simstudioai/sim · GitHub
Open Graph Title: Memory exhaustion in loop executions with agent blocks making tool calls · Issue #2525 · simstudioai/sim
X Title: Memory exhaustion in loop executions with agent blocks making tool calls · Issue #2525 · simstudioai/sim
Description: Summary When running workflows with loops containing agent blocks that make many tool calls (e.g., MCP file operations), memory accumulates unbounded until system OOM. This caused my 64GB system to run out of memory during workflow execu...
Open Graph Description: Summary When running workflows with loops containing agent blocks that make many tool calls (e.g., MCP file operations), memory accumulates unbounded until system OOM. This caused my 64GB system to...
X Description: Summary When running workflows with loops containing agent blocks that make many tool calls (e.g., MCP file operations), memory accumulates unbounded until system OOM. This caused my 64GB system to...
Opengraph URL: https://github.com/simstudioai/sim/issues/2525
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Memory exhaustion in loop executions with agent blocks making tool calls","articleBody":"## Summary\n\nWhen running workflows with loops containing agent blocks that make many tool calls (e.g., MCP file operations), memory accumulates unbounded until system OOM. This caused my 64GB system to run out of memory during workflow execution.\n\n## Environment\n\n- Self-hosted via Docker\n- macOS with 64GB RAM\n- Docker containers with no memory limits (default)\n\n## Root Cause Analysis\n\nAfter investigating the codebase, I identified **6 critical memory accumulation points** with no bounds:\n\n### 1. `allIterationOutputs` in LoopScope (CRITICAL)\n\n**File:** `apps/sim/executor/orchestrators/loop.ts` (line 144)\n\n```typescript\nif (iterationResults.length \u003e 0) {\n scope.allIterationOutputs.push(iterationResults) // UNBOUNDED\n}\n```\n\nEvery loop iteration pushes results to this array with no size limit or pruning.\n\n### 2. `blockLogs` array in ExecutionContext (CRITICAL)\n\n**File:** `apps/sim/executor/execution/block-executor.ts` (lines 60-62)\n\n```typescript\nblockLog = this.createBlockLog(ctx, node.id, block, node)\nctx.blockLogs.push(blockLog) // UNBOUNDED - every block execution adds\n```\n\nEvery block execution (including each loop iteration) pushes to this array.\n\n### 3. TraceSpans accumulation\n\n**File:** `apps/sim/lib/logs/execution/trace-spans/trace-spans.ts`\n\nThe `buildTraceSpans()` function creates spans for ALL block logs and tool calls, building an unbounded in-memory tree structure.\n\n### 4. Tool calls array per agent\n\n**File:** `apps/sim/executor/handlers/agent/agent-handler.ts` (lines 250-318)\n\nEach agent execution stores all tool calls in `span.toolCalls` array. With 100 tool calls per agent × 1000 iterations = 100,000 ToolCall objects.\n\n### 5. File extraction unbounded recursion\n\n**File:** `apps/sim/lib/logs/execution/logger.ts` (lines 621-695)\n\n`extractFilesFromExecution()` recursively walks the entire trace span tree with no depth limits.\n\n### 6. Memory table JSONB concatenation\n\n**File:** `apps/sim/executor/handlers/agent/memory.ts` (line ~580)\n\n```typescript\ndata: sql`${memory.data} || ${JSON.stringify([message])}::jsonb` // Unbounded append\n```\n\n## Memory Growth Calculation\n\nFor a workflow with:\n- Loop: 1000 iterations\n- Agent block per iteration with 100 tool calls (file read/write via MCP)\n\n**Memory consumption:**\n- `blockLogs`: 1000 entries × 50KB = 50MB\n- `allIterationOutputs`: 1000 × 1MB = 1GB \n- Tool calls in spans: 100,000 objects = 1GB\n- TraceSpans tree traversal: O(GB) object graph\n- **Total**: 2-10+ GB in memory, persisted to `executionData` JSONB\n\n## Reproduction Steps\n\n1. Create a workflow with a Loop block (while condition)\n2. Inside loop: StateTracker function → Agent with MCP tools (file read/write) → Reviewer\n3. Run the workflow with multiple tasks that require many file operations\n4. Monitor Docker container memory with `docker stats`\n5. Observe memory climbing until OOM\n\n## Suggested Fixes\n\n### Short-term mitigations:\n\n1. **Add iteration limits check with memory awareness:**\n```typescript\nconst MAX_MEMORY_PER_LOOP = 100 * 1024 * 1024; // 100MB\nif (estimateSize(scope.allIterationOutputs) \u003e MAX_MEMORY_PER_LOOP) {\n logger.warn('Loop memory limit reached, truncating older iterations');\n scope.allIterationOutputs = scope.allIterationOutputs.slice(-10);\n}\n```\n\n2. **Stream block logs to database instead of accumulating:**\n```typescript\n// Instead of ctx.blockLogs.push(blockLog)\nawait this.persistBlockLog(blockLog);\n```\n\n3. **Truncate tool call results in spans:**\n```typescript\nconst MAX_TOOL_RESULT_SIZE = 10000;\ntoolCall.result = truncate(toolCall.result, MAX_TOOL_RESULT_SIZE);\n```\n\n### Long-term solutions:\n\n1. Implement streaming execution logs (write to DB incrementally)\n2. Add configurable memory limits per execution\n3. Implement log rotation/pruning during long-running executions\n4. Add memory pressure monitoring with graceful degradation\n\n## Workaround\n\nSet Docker memory limits to prevent system-wide OOM:\n\n```yaml\n# docker-compose.override.yml\nservices:\n simstudio-app:\n deploy:\n resources:\n limits:\n memory: 8G\n```\n\n## Related Files\n\n- `apps/sim/executor/orchestrators/loop.ts`\n- `apps/sim/executor/execution/block-executor.ts`\n- `apps/sim/lib/logs/execution/trace-spans/trace-spans.ts`\n- `apps/sim/lib/logs/execution/logger.ts`\n- `apps/sim/executor/handlers/agent/agent-handler.ts`\n- `apps/sim/executor/handlers/agent/memory.ts`\n- `packages/db/schema.ts` (executionData JSONB field)","author":{"url":"https://github.com/aadamsx","@type":"Person","name":"aadamsx"},"datePublished":"2025-12-22T18:38:27.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/2525/sim/issues/2525"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:32069f63-2ca0-f257-8f0e-ccfc0b92e7d4 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | EDAA:12D78F:1F66E88:2AC4B21:6964C28A |
| html-safe-nonce | 965edffddf74d5ae757c439597bf565a42fba26ef82fe20ac75028f2e39ce613 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFREFBOjEyRDc4RjoxRjY2RTg4OjJBQzRCMjE6Njk2NEMyOEEiLCJ2aXNpdG9yX2lkIjoiMTAwNDAyOTgyMDc0NDgxMTE0NyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | b4e26b9139647e4e66d98fc5de38fec99de96bb410b2272cf3e484b73d93a650 |
| hovercard-subject-tag | issue:3754813921 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/simstudioai/sim/2525/issue_layout |
| twitter:image | https://opengraph.githubassets.com/4bd02f6bd3c8b8987060a30b7655644579930d97eb2bb9bc25cf06257ad32423/simstudioai/sim/issues/2525 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/4bd02f6bd3c8b8987060a30b7655644579930d97eb2bb9bc25cf06257ad32423/simstudioai/sim/issues/2525 |
| og:image:alt | Summary When running workflows with loops containing agent blocks that make many tool calls (e.g., MCP file operations), memory accumulates unbounded until system OOM. This caused my 64GB system to... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | aadamsx |
| hostname | github.com |
| expected-hostname | github.com |
| None | 21df671ce2c9f1a16940ccbd3af6cb4f3f12a856929ca7eb1b4aea8e384ea442 |
| turbo-cache-control | no-preview |
| go-import | github.com/simstudioai/sim git https://github.com/simstudioai/sim.git |
| octolytics-dimension-user_id | 199344406 |
| octolytics-dimension-user_login | simstudioai |
| octolytics-dimension-repository_id | 912559512 |
| octolytics-dimension-repository_nwo | simstudioai/sim |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 912559512 |
| octolytics-dimension-repository_network_root_nwo | simstudioai/sim |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 5707c685ac172d50a0bdd7533dde4f8aabcf8eef |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width