The Nginx Memory Guard watches, every minute, how much memory the reverse-proxy engine (nginx) really uses on the appliance: the heap of the master process, the private memory of each worker, the memory still available on the host and the Linux memory-pressure indicator.
It keeps 30 days of measurements, shows them as curves, and when the engine has visibly bloated and the host is running short of memory, it replaces the nginx master process on the fly, without dropping a single connection.
A preventive replacement also runs every night. Everything the watchdog does, or refuses to do, is written in an event journal and, for restarts, sent as a notification to the administrator.
The feature is enabled by default on every appliance running the reverse-proxy, and needs no configuration.
Every time the reverse-proxy configuration is rebuilt (a site is added, a certificate is renewed, a rule is changed…), nginx is reloaded:
The master process re-reads the whole configuration and starts a fresh generation of workers.
This is the normal way to apply a change without downtime. It has a cost that grows silently over time:
Only a new master process puts the heap back to its initial size.
Stopping and starting nginx would do that, at the price of an interruption.
The Memory Guard uses instead nginx's built-in binary-upgrade sequence, which was designed for zero-downtime upgrades:
Each step is bounded in time and verified:
The watchdog checks that the new master really appeared, that it is a master process (not a recycled PID), and that the old one really left.
If the sequence does not complete, the event is marked as failed and a severity 0 notification is raised, because two masters sharing the same sockets must never stay unnoticed.
The watchdog is deliberately conservative:
A restart, even a hot one, is not free (a few seconds of double memory usage, a cold cache for the new workers), so it only acts on two independent witnesses out of three:
some over 60 s) exceeds a threshold (10 by default).A bloated heap on a host that still has plenty of memory does nothing; a host under pressure because of another process does nothing either.
When both fire, a battery of safety guards is still consulted before anything happens, in this order:
The cooldown starts at the attempt, not at the success: a replacement that fails because the host cannot fork a new master, which is precisely the situation the watchdog is meant for, is not retried every minute with a notification each time.
Independently of the memory thresholds, a worker of a previous generation that is still shutting down after the configured age (10 minutes by default) is asked to leave with an escalating sequence, one step per minute:
QUIT, TERM, KILL. The master is never touched by this rule.
The connections still held by such a worker are, by definition, older than the threshold.
Every night at 05:45, the same hot replacement is performed regardless of memory usage, so that the master heap returns to its baseline once a day and the daytime watchdog rarely has anything to do.
A notification Restarted reverse-proxy engine for cleaning memory is sent to the administrator with a memory report taken before and after the replacement.
If the hot replacement fails, the daemon falls back to a plain restart of nginx; if that fails too, a severity 0 notification nginx is DOWN after a failed nightly restart is raised.
Because each worker carries its own copy of the heap, the number of workers is now sized on memory as well as on CPUs:
The automatic value is the number of CPU cores, capped so that all workers together fit in a quarter of the host memory at 384 MB each, with a minimum of 2.
An 8-core, 8 GB appliance therefore runs 5 workers instead of 8.
The value can be pinned in the settings.
In the left menu, open Web services and click Monitoring
The page has three tabs:
Three buttons are available from every tab: Refresh, Settings, and Restart now.

The range buttons select the last hour or the last 24 hours (one point per minute), the last 7 days (hourly averages) or the last 30 days (daily averages).
Older points are purged nightly; the database is compacted once a day.
The Performance nginx chart shows, in MB:
The Performance system & hardware chart shows the host side:
The percentage of memory still available, the memory of the reverse-proxy daemon itself, and the memory-pressure indicator.
A point is missing rather than drawn at zero when a measurement could not be taken.

Each line is one decision of the watchdog, with its date, its kind, its reason, the memory before and after (master heap and nginx total) and its result:
| Kind | Meaning |
|---|---|
| Baseline heap recorded | The reference heap was measured on a fresh master. All later heap comparisons use this value. |
| Automatic hot restart (watchdog) | The two witnesses fired and every guard agreed: the master was replaced. |
| Hot restart refused by a safety guard | The witnesses fired but a guard refused (cooldown, replacement already in progress. The reason names the guard. Written once per distinct reason, not every minute. |
| Old workers terminated | Workers of a previous generation older than the threshold were signalled. The reason lists the PIDs and the signal used. |
| Nightly preventive restart | The 05:45 replacement, with its before/after report. |
| Nightly preventive restart failed | The hot replacement failed; the reason says whether the fallback restart succeeded. |
| Manual restart | A replacement started from the Restart now button. |
A result of Failed on a restart event means the sequence did not complete as verified:
Read the reason, and check the Status tab for an old master still alive.

The Current state card is the latest one-minute measurement:
master PID and heap, workers private memory, nginx total, number of workers and of old workers,
The baseline heap, the available memory, the daemon memory, the memory pressure,
The last watchdog decision with its reason.
none (thresholds not reached) is the normal state of a healthy appliance.
Not available means the measurement could not be taken, which is different from zero.
The Watchdog card summarises the settings; the pencil opens the settings dialog.

| Setting | Default | Range | Effect |
|---|---|---|---|
| Enable the memory watchdog | on | Off: measurements and curves continue, no automatic replacement is ever performed (the nightly restart and the manual button still work). |
|
| Heap growth factor | 3 | 2 – 10 | The master heap must exceed this multiple of its baseline for the first witness to fire. |
| Minimum available memory (%) | 15 | 1 – 90 | Second witness: available memory below this share of the total. |
| Memory pressure threshold (PSI) | 10 | 1 – 100 | Alternative second witness: PSI memory some average over 60 s above this value. |
| Cooldown between restarts (minutes) | 60 | 5 – 1440 | Minimum delay between two automatic attempts, counted from the attempt. |
| Old worker age threshold (minutes) | 10 | 1 – 120 | Age after which a shutting-down worker is signalled (QUIT, then TERM, then KILL, one step per minute). |
| Nightly preventive restart | on | The 05:45 hot replacement with its notification. | |
| Worker processes | 0 (automatic) | Pins the number of nginx workers. 0 lets the appliance size them on CPUs and memory. Changing it rebuilds the engine configuration. |
An out-of-range value is refused with the name of the field and its range, and nothing is written.
Restart now performs the same hot replacement as the watchdog, immediately, without waiting for the thresholds. It is refused only when a replacement is really in progress
(a previous master is still handing over).

Restarts are also reported through the appliance notification system (Events Center and administrator e-mail):
The console talks to the reverse-proxy daemon on its local Unix socket. The same routes can be used from the appliance shell:
curl --unix-socket /run/reverse-proxy.sock http://x/nginx-memory/statuscurl --unix-socket /run/reverse-proxy.sock "http://x/nginx-memory/series?range=24h"curl --unix-socket /run/reverse-proxy.sock "http://x/nginx-memory/events?limit=50"curl --unix-socket /run/reverse-proxy.sock -X POST http://x/nginx-memory/restart
GET /nginx-memory/status: the latest snapshot, the effective settings, the baseline heap and the last decision with its witnesses.GET /nginx-memory/series?range=1h|24h|7d|30d: the points of the selected range, in kB. A value of -1 is a missing measurement.GET /nginx-memory/events?limit=N: the journal, newest first.POST /nginx-memory/restart: starts a hot replacement; started:true means started, not finished. Returns 409 while a replacement is in progress.
worker_shutdown_timeout is only needed when legitimate requests are longer than 30 seconds.ps that a single nginx: master process is running; if two are, the old one has not exited: