OpenSimulator Region Hibernation Strategy
Near-zero CPU idle regions with near-instant wake-up on network activity
Recommended approach: keep each OpenSimulator/.NET region process resident in memory, freeze it with Linux SIGSTOP when idle, and resume it with SIGCONT when a lightweight TCP wake proxy detects an incoming connection.
Why this fits the requirement
Memory consumption is not a concern, so there is little benefit in shutting down and rebuilding the simulator process.
SIGSTOP removes the process from normal CPU scheduling. The process remains intact in RAM, including its loaded region, scripts, runtime state, and .NET environment.
SIGCONT resumes the same process rather than starting a new one, making wake-up much faster than a full OpenSimulator restart.
A small always-running proxy can remain responsible for the public TCP port while the simulator itself is frozen.
Recommended architecture
Viewer / external service
|
v
Public TCP port :9000
|
v
+—————-+
| Wake Proxy | always running; tiny CPU footprint
+—————-+
|
region awake?
/ \
yes no
| |
| SIGCONT
| |
+—-> OpenSimulator on private TCP port :19000
|
v
normal region traffic
Example port arrangement: the externally visible region port 9000 belongs to the wake proxy, while OpenSimulator listens internally on 19000. Additional regions can follow the same mapping (9001 -> 19001, 9002 -> 19002, and so on).
Sleeping and waking a region
Freeze the OpenSimulator process:
kill -STOP <pid>
Resume it:
kill -CONT <pid>
While stopped: the process consumes essentially no CPU because Linux does not schedule its threads. Its memory remains allocated, which is acceptable for this design.
Why use a TCP wake proxy?
A frozen process cannot execute application code to service new connections. Linux may still perform some kernel-level TCP work for an existing listening socket, but relying on that behavior makes wake-up timing and application response less deterministic. A proxy provides a clean boundary:
The proxy owns the externally advertised TCP port continuously.
When traffic arrives for a sleeping region, the proxy sends SIGCONT.
It waits briefly until the region process is responsive on its internal TCP listener.
It then forwards the original connection to OpenSimulator.
When the region is already awake, the proxy simply forwards traffic normally.
UDP handling
Start simple. If TCP activity is the critical signal that precedes useful region activity, use TCP as the wake-up “doorbell.” The OpenSimulator process can retain its normal UDP ports, and once SIGCONT is issued it can resume servicing them almost immediately. UDP proxying can be added later only if real-world testing shows it is necessary.
systemd integration
Each region can be managed as an instance service, for example:
opensim@region1.service
opensim@region2.service
opensim@region3.service
The sleep manager or proxy can then identify the region process through systemd and signal the entire service control group rather than keeping ad-hoc PID files.
Conceptually, the manager needs only two operations:
systemctl kill –signal=STOP opensim@region1.service
systemctl kill –signal=CONT opensim@region1.service
Exact service signaling should be tested with the OpenSimulator service layout, especially if child processes are involved.
Idle detection
A practical sleep manager could freeze a region after a configurable idle period, such as 15–30 minutes. Possible definitions of “idle” include:
No avatars present in the region.
No meaningful inbound TCP activity for the configured period.
No administrative or scripted task that explicitly marks the region as needing to remain awake.
Optionally, an OpenSimulator-side heartbeat or management endpoint reporting occupancy/activity to the sleep manager.
Important compatibility test
Before building the complete proxy, verify that OpenSimulator tolerates being frozen for long periods. A simple test is:
PID=$(pgrep -f OpenSim.dll)
kill -STOP “$PID”
# Leave it frozen for a while: first a few minutes, then an hour, then overnight.
kill -CONT “$PID”
After each resume, inspect the OpenSimulator console and logs for:
timer or scheduler catch-up storms;
grid heartbeat / region registration failures;
expired capabilities or authentication/session problems;
script timing problems;
physics anomalies;
network reconnect problems.
Suggested implementation sequence
Freeze test: Verify one existing region survives SIGSTOP for increasingly long periods and resumes cleanly.
Port split: Move that region’s actual OpenSimulator TCP listener to a private/internal port while retaining the original public port for the proxy.
Wake proxy: Create a tiny TCP proxy that sends SIGCONT when the first connection arrives, waits for the internal listener, then forwards the connection.
Idle manager: Add automatic SIGSTOP after an idle timeout.
Multi-region mapping: Generalize the proxy/manager to map public TCP ports to systemd region services and internal ports.
UDP validation: Test normal viewer arrival and operation. Add UDP-specific wake/proxy logic only if testing demonstrates a need.
Bottom line
Given that RAM is not a constraint, avoid checkpoint/restore, CRIU, swapping tricks, and full region shutdown as the first approach. A resident OpenSimulator process frozen with SIGSTOP provides the simplest path to essentially zero idle CPU while retaining near-instant SIGCONT wake-up. A lightweight TCP wake proxy makes the network behavior predictable and lets sleeping regions continue to present stable public endpoints.
OpenSimulator Region Hibernation Strategy