-
Notifications
You must be signed in to change notification settings - Fork 448
Memory Management
RedAmon runs everything on a single host: the databases (Neo4j and Postgres), the AI agent, the web app, and, on demand, several recon scans. Each scan launches its own set of tool containers (naabu, httpx, katana, nuclei, gau, and so on), so a few parallel scans can add up to a lot of memory very quickly.
The memory governor is the built-in system that watches how much RAM is actually free and automatically keeps the whole stack from running out of memory. It works out of the box, needs no setup, and most operators never have to touch it. This page explains what you will see in the interface, the one concept that commonly confuses people, how many scans you can realistically run, and the settings you can change if you want to tune it for your machine.
Related pages: Running Reconnaissance, Recon Pipeline Workflow, Fireteam, Parallel Specialists, Recon Presets, Rules of Engagement, Troubleshooting.
- Caps how many scans run at once so their combined memory can never exceed what your host can give. If you start more scans than fit, the extra ones are refused with a clear message (they are never crashed), and you can run them as soon as a running scan finishes.
- Gives every container a hard memory limit so one runaway tool is stopped in isolation instead of dragging down your database or the whole app.
- Turns tool settings down under pressure. When free RAM is low, a scan automatically runs with fewer parallel threads and smaller crawl lists, and it records exactly what it changed.
- Refuses to start on a host that is too small, with an upfront message, instead of failing in a confusing way later.
Everything is safe by default. If the governor cannot read memory information for any reason, it simply does nothing and RedAmon behaves exactly as it did before the feature existed.
A RAM and CPU meter in the bottom-right of the footer, for example:
RAM ▓▓▓▓░░░ 64% 11.3 GB free CPU ▓▓░░░░ 12% v5.3.0
Hover over it for a breakdown, including how much RAM is currently available to start a new scan. The bar updates every few seconds.
A pop-up when a scan cannot start. If you try to launch a scan that will not fit, a modal explains why:
- "Not enough memory" means it is a RAM limit. The scan will fit once a running scan finishes and releases its memory. You do not need to change anything, just retry shortly, or free up memory by stopping another scan.
-
"Scan limit reached" means you hit a configured ceiling (see
RECON_MAX_CONCURRENT_GLOBALbelow), not a memory problem. Raise the setting if you want more.
Red lines in the recon logs drawer that begin with [RESOURCE-CAP], for example:
[RESOURCE-CAP] nuclei NUCLEI_CONCURRENCY 25 -> 11 (avail 8.3 GB, ratio)
[RESOURCE-CAP] katana KATANA_PARALLELISM 8 -> 4 (avail 8.3 GB, ratio)
Each line means a tool setting was automatically lowered to fit the memory available when that scan started. The scan still runs and still produces results, it just runs with less parallelism (a little slower, a little less exhaustive). This is normal and expected under load, not an error.
None of these three signals indicate a fault. They are the governor doing its job.
The footer shows two different RAM numbers on purpose, and they are meant to disagree:
-
… GB free(next to the bar) is the RAM that is physically free right now. - "available for a new scan" (in the tooltip) is that free RAM minus the memory your already-running scans have reserved.
Here is why they differ. Suppose you have 11 GB free, but five scans are running and each one reserved about 3.7 GB up front. The governor has already set aside that memory for work in progress, so only about 5.9 GB is actually available to admit a new scan. That is why a scan can be refused even when the bar does not look full.
Think of it like a parking garage: "free spaces" is how many are empty this instant, but "available for a new car" also subtracts the spaces already promised to cars that are still driving in. Free RAM is what you have; "available for a new scan" is what is left after existing work is accounted for.
The governor reserves a fixed budget of memory per scan, then admits scans until that budget is used up. In round numbers, on a typical host it works out to roughly:
| Host RAM | Rough concurrent full scans |
|---|---|
| 8 GB | 1 (often best to run scans one at a time) |
| 16 GB | 2 to 3 |
| 32 GB | 5 to 6 |
| 64 GB | 12 to 14 |
These are conservative defaults chosen to keep you safe, not hard technical limits. If your targets are small and your scans are light, you can safely raise the count by telling the governor to reserve less per scan (see Tuning for your host). If a scan is refused, that simply means the budget is full for now, wait for one to finish.
This budget applies across all projects, and it counts every kind of scan: full recon, Partial Recon single-tool runs, Adversarial AI Recon, GVM, GitHub Secret Hunting, and TruffleHog.
- Recon Presets and per-tool settings. The values you set in Recon Presets and a project's recon settings are the ceilings. The governor only ever lowers them under memory pressure, never raises them above what you configured. When RAM is plentiful your scans run at exactly the settings you chose.
- Stealth mode. Stealth already forces low, quiet settings. The governor runs after Stealth, so it can tighten things further under pressure but never loosens what Stealth set.
- Rules of Engagement. RoE rate caps and time windows are unaffected; the governor manages memory, not request rates or scheduling permissions. Both apply together.
- Fireteam and the AI agent. The same idea protects the agent: Fireteam member count and the number of tools the agent runs in parallel are scaled down when memory is tight, and the number of simultaneous chat sessions and background jobs is capped. The agent stays responsive instead of exhausting its container.
| I want to | Do this |
|---|---|
| Turn the whole feature off | set REDAMON_MEM_GOVERNOR=0 in .env, then ./redamon.sh up
|
| Allow or limit how many scans run at once | set RECON_MAX_CONCURRENT_GLOBAL=N (a hard ceiling across all projects). 0 pauses all new scans. Leave it unset to let RAM decide. |
| Run more scans on a small host | reserve less per scan: lower RECON_JOB_ENVELOPE_MEM, SERVICE_BASELINE_MEM, OS_HEADROOM_MEM
|
| Get past a refused boot ("insufficient memory") | set REDAMON_SKIP_RAM_GATE=1, or a custom REDAMON_MIN_RAM_MB
|
| Add a cushion so brief spikes do not cause refusals | set REDAMON_ENABLE_ZRAM=1 (native Linux hosts only) |
| Limit concurrent agent chats or background jobs | set MAX_AGENT_SESSIONS or MAX_BACKGROUND_JOBS
|
| Give each tool container more or less memory | set BROKER_TOOL_MEM_BYTES (default 2g) |
| Tune the caps to this host by measuring its real usage | run bash tests/redamon_mem_calibrate.sh baseline
|
After changing any value in
.env, apply it with./redamon.sh up(or./redamon.sh update). Settings are read at startup, so a running stack does not pick them up until you restart it.
You almost never need this, but if you want the governor sized precisely to your machine, run the calibration once. It measures how much memory your services and scans actually use and writes the numbers into a profile the governor then uses in place of its conservative built-in guesses:
bash tests/redamon_mem_calibrate.sh baseline # measures the always-on services
The profile is specific to your host and is not shared or committed, so each machine measures its own. If you never run it, the safe built-in defaults are used.
Quick manual recipes:
-
Small host (16 GB or less), want more scans: set
RECON_JOB_ENVELOPE_MEM=2g(only if your scans are light), and considerREDAMON_ENABLE_ZRAM=1. -
Large host (64 GB or more), want maximum throughput: leave the defaults, or raise
RECON_MAX_CONCURRENT_GLOBALif you want an explicit higher ceiling. -
Shared machine, keep RedAmon polite: raise
OS_HEADROOM_MEMso more RAM is always left for the rest of the system.
Every setting is optional; the default shown applies when it is unset. Memory sizes accept 2g, 512m, or a plain number of bytes. The full technical detail lives in the developer reference at readmes/README.MEMORY_GOVERNOR.md.
| Variable | Default | When to change it |
|---|---|---|
REDAMON_MEM_GOVERNOR |
on | Set 0 or false to disable all dynamic capping (falls back to fixed limits only). |
| Variable | Default | When to change it |
|---|---|---|
RECON_MAX_CONCURRENT_GLOBAL |
RAM-decided | Hard ceiling on concurrent scans across all projects. 0 pauses all new scans. |
MAX_AGENT_SESSIONS |
20 |
Maximum simultaneous agent chat sessions. |
MAX_BACKGROUND_JOBS |
16 |
Maximum simultaneous background agent jobs. |
TERMINAL_MAX_SESSIONS |
5 |
Maximum Kali terminal sessions. |
| Variable | Default | When to change it |
|---|---|---|
OS_HEADROOM_MEM |
2g |
RAM always kept free for the operating system. Lower it to squeeze more work onto a small host; raise it to be a better neighbour on a shared machine. |
SERVICE_BASELINE_MEM |
measured, else 6g
|
RAM assumed for the always-on services. Lower to allow more scans; raise if your database is heavily loaded. |
RECON_JOB_ENVELOPE_MEM |
measured, else 4g
|
RAM reserved per scan. Lower to run more scans at once (only if your scans are light). |
| Variable | Default | When to change it |
|---|---|---|
REDAMON_SKIP_RAM_GATE |
off | Set 1 to boot even when RAM looks insufficient. |
REDAMON_MIN_RAM_MB |
derived | Custom minimum-RAM threshold, in MB, for the startup check. |
REDAMON_ENABLE_ZRAM |
off | Set 1 for a one-time compressed-RAM swap cushion (native Linux only; a no-op on Docker Desktop). |
REDAMON_ZRAM_SIZE |
half of RAM, capped at 8 GB | Explicit zram device size. |
| Variable | Default | When to change it |
|---|---|---|
BROKER_TOOL_MEM_BYTES |
2g |
Memory cap for each recon tool container (naabu, katana, nuclei, and so on). |
NEO4J_MEM, NEO4J_HEAP, NEO4J_PAGECACHE
|
host-sized | Neo4j container limit and JVM sizing. Change HEAP and NEO4J_MEM together (the container limit must exceed the heap). |
AGENT_MEM, POSTGRES_MEM, WEBAPP_MEM, RECON_ORCHESTRATOR_MEM, KALI_MEM, GVMD_MEM
|
host-sized | Per-service container caps. |
PER_CONTAINER_MAX |
about 55% of RAM | The most any single container may use, so one container can never take the whole host. |
WEBAPP_DEV_MEM |
4g |
Affects dev mode (up dev) only; the dev web server needs much more RAM than production. |
| Variable | Default | When to change it |
|---|---|---|
MEM_SCALE_HIGH |
0.50 |
Above this free-RAM fraction, tools run at full settings. Raise it to start throttling sooner. |
MEM_SCALE_LOW, MEM_SCALE_FLOOR
|
0.15 |
Below this fraction, tools run at their minimum. |
MEM_BUDGET_FRACTION |
0.10 |
Share of free RAM a single crawl list may use. |
AGENT_MEM_BUDGET_FRACTION |
0.5 |
Share of free RAM the agent's parallel work may use. |
MEM_SAFETY_TOLERANCE |
0.25 |
Safety margin (+25%) added on top of measured memory figures. |
"My seventh scan was refused." Expected. The governor admits as many scans as fit your RAM budget (about six on a 32 GB host) and refuses the rest with a memory message. Wait for a running scan to finish, its reservation is released automatically within about 30 seconds, or free up memory by stopping a scan.
"The bar shows 50% but the tooltip says only 5.9 GB left. Is that wrong?" No. The bar is physical RAM used. The 5.9 GB is what is available to start a new scan after subtracting the memory your running scans reserved. See The one concept that confuses people.
"RedAmon refused to start with an insufficient-memory message."
Your host has less RAM than the core services need. Free up memory, raise the Docker VM memory (on Docker Desktop), or set REDAMON_SKIP_RAM_GATE=1 to override the check.
"I see red [RESOURCE-CAP] lines during a scan."
That is the governor lowering tool settings to fit the memory that was available when the scan started. The scan still completes; it just runs with less parallelism. If you want full settings, free up RAM before starting the scan, or run fewer scans at once.
"In dev mode the web app will not finish loading, or shows Failed to fetch."
Dev-mode compilation needs far more memory than production. Its cap is WEBAPP_DEV_MEM (default 4g); raise it if your machine is very constrained, then ./redamon.sh up dev.
"How do I see current memory usage?" Use the RAM and CPU meter in the bottom-right of the footer. It updates every few seconds and its tooltip shows the full breakdown.
"A scan container was stopped mid-run." If a single tool used far more memory than expected, its container is stopped in isolation (the rest of the scan and the whole stack keep running) and the scan reports that tool as failed. This is the safety limit doing its job; it is rare, and usually means a very large target or an unusual response.
Getting Started
Core Workflow
- Red Zone
- Recon Pipeline Workflow
- Running Reconnaissance
- AI Agent Guide
- Fireteam — Parallel Specialists
- Agent Workspace
- Reverse Shells
Scanning & OSINT
- Adversarial AI Recon
- AI Gauntlet
- JS Reconnaissance
- GraphQL Security Testing
- Subdomain Takeover Detection
- VHost & SNI Enumeration
- Web Cache Poisoning
- GVM Vulnerability Scanning
- GitHub Secret Hunting
- TruffleHog Secret Scanning
AI & Automation
- AI Model Providers
- MCP Tool Plugins
- Knowledge Base & Web Search
- Agent Skills
- Chat Skills
- Tradecraft Lookup
- Playwright Browser Automation
- CypherFix — Automated Remediation
- Rules of Engagement (RoE)
HackLab
Analysis & Reporting
- Insights Dashboard
- Pentest Reports
- Attack Surface Graph
- Surface Shaper
- EvoGraph — Attack Chain Evolution
- Data Export & Import
Contributing
Reference & Help