Skip to main content
A plugin runs on a small SBC alongside the rest of the agent. The supervisor budgets resources through systemd and the shared ados-plugins.slice cgroup. This page covers the budgets, how to spot when you blow them, and how to profile.

Default budgets

When a plugin’s manifest does not declare resources, it gets: Declare different caps in the manifest:
Honest declarations matter. The operator sees the requested budget in the install dialog. Asking for far more than you use is a bad signal; asking for too little ends with the kernel killing your process. The caps map straight to the per-plugin systemd unit: max_ram_mb to MemoryMax, max_cpu_percent to CPUQuota, max_pids to TasksMax.

Spotting cgroup throttling

max_cpu_percent is enforced by the cgroup CPU controller. A plugin that breaches it does not crash; it gets throttled. The symptom is “everything got slower for no reason.” Read the throttle stats from the unit’s cgroup (the unit name is ados-plugin-<id> with the dots in your plugin id replaced by hyphens):
The interesting field is nr_throttled. If it climbs every second, your plugin is over budget. Optimize the code or declare a higher max_cpu_percent.

Memory pressure

max_ram_mb is enforced by MemoryMax. A breach OOM-kills the process. The unit restarts on failure, and repeated kills that exceed the start limit move the plugin to failed.
memory.events shows low, high, max, oom, oom_kill counters. Any non-zero high or max means the kernel started applying pressure. To stay under the cap:
  • Process events on a bounded queue, not an unbounded list.
  • For ML models, prefer quantized weights (int8 over fp32).
  • Stream files; do not load whole logs into RAM.
  • Use array.array or numpy over a Python list of floats.

Inspecting a running plugin

ados plugin info <id> shows the plugin’s recorded state, granted permissions, and recent events. Pair it with the cgroup stat files above and the durable log query for a full picture:
A plugin running consistently near any cap is one bad input away from a throttle stall or an OOM kill.

Profiling Python plugins

The SDK does not bundle a profiler; use cProfile or pyinstrument inside your own start path:
Plugin stdout and stderr append to /var/log/ados/plugins/<id>.log, so profiler output lands there (or read it with journalctl -u ados-plugin-<id>.service).

Profiling TypeScript plugins

Open the GCS in developer mode, pick the plugin’s iframe in browser devtools (Sources tab), and use the Performance recorder. The iframe is a real browsing context with the standard devtools surface. Common GCS hot paths:
  • React re-renders triggered by every telemetry event. Coalesce with requestAnimationFrame and a local ref.
  • Heavy SVG redraws. Switch to canvas past a few hundred paths.
  • Synchronous JSON parse in the message handler. Move it off the main thread.

Event-loop discipline

The biggest cause of agent-plugin stalls is a blocked event loop. A plugin that blocks the loop stops responding and the supervisor restarts it. Don’t:
  • time.sleep(...) in async code.
  • Heavy CPU work directly in on_start.
  • Synchronous I/O on a slow disk.
Do:
  • await asyncio.sleep(...).
  • await asyncio.to_thread(heavy_work).
  • aiofiles or chunked reads for slow I/O.

Disk and network discipline

Disk I/O is a common cause of throttling. A plugin writing a megabyte of samples per second to an SD card is already at the sustained-write ceiling for the cheap end of the market. Batch writes (one fsync per second is plenty), compress logs, and rotate them. Plugins with network.outbound share the drone’s link with telemetry and video. Pulling large payloads in flight is a UX bug; pull during ground time and cache.

Thermal behavior

Sustained high CPU on a small SoC raises its temperature and the kernel eventually throttles the whole package, which shows up as cgroup throttle events on every plugin, not just yours. The agent reduces its own non-essential work as the SoC heats up. A well-behaved plugin watches the system telemetry and backs off before the kernel forces the issue.

See also