Configuration
BoxConfig, resource limits, caching, warm pool, and logging options
Configuration
A3S Box uses BoxConfig as the central configuration struct, controlling resources, networking, caching, warm pool, TEE, and logging.
BoxConfig
pub struct BoxConfig {
pub agent: AgentType,
pub business: BusinessType,
pub workspace: PathBuf,
pub skills: Vec<PathBuf>,
pub resources: ResourceConfig,
pub log_level: LogLevel,
pub tee: TeeConfig,
pub cmd: Vec<String>,
pub entrypoint_override: Option<Vec<String>>,
pub volumes: Vec<String>,
pub extra_env: Vec<(String, String)>,
pub cache: CacheConfig,
pub pool: PoolConfig,
pub port_map: Vec<String>,
pub dns: Vec<String>,
pub network: NetworkMode,
pub tmpfs: Vec<String>,
pub resource_limits: ResourceLimits,
}Resource Configuration
Control CPU, memory, disk, and lifetime for each VM:
pub struct ResourceConfig {
pub vcpus: u32, // Default: 2
pub memory_mb: u32, // Default: 1024
pub disk_mb: u32, // Default: 4096
pub timeout: u64, // Lifetime in seconds (0 = unlimited, default: 3600)
}CLI usage:
a3s-box run --cpus 4 --memory 2048 --timeout 7200 alpine:latestResource Limits
Fine-grained control via cgroup v2 and rlimits:
pub struct ResourceLimits {
pub pids_limit: Option<u64>,
pub cpuset_cpus: Option<String>,
pub ulimits: Vec<String>,
pub cpu_shares: Option<u64>,
pub cpu_quota: Option<i64>,
pub cpu_period: Option<u64>,
pub memory_reservation: Option<u64>,
pub memory_swap: Option<i64>,
}Prop
Type
a3s-box run --pids-limit 500 --cpuset-cpus "0,1" alpine:latestAgent Type
Controls how the coding agent is loaded into the VM:
pub enum AgentType {
A3sCode, // Built-in (default)
OciImage { path: PathBuf }, // Local OCI image
LocalBinary { path: PathBuf, args: Vec<String> },
RemoteBinary { url: String, checksum: String },
OciRegistry { reference: String }, // Registry image
}Business Type
Controls how user code is loaded:
pub enum BusinessType {
None, // No business code (default)
OciImage { path: PathBuf }, // Packaged OCI image
Directory { path: PathBuf }, // Mount directory as workspace
}Cache Configuration
OCI image and rootfs caching settings:
pub struct CacheConfig {
pub enabled: bool, // Default: true
pub cache_dir: Option<PathBuf>, // Default: ~/.a3s/cache
pub max_rootfs_entries: usize, // Default: 10
pub max_cache_bytes: u64, // Default: 10 GB
}The caching pipeline:
Registry → Layer Cache (compressed blobs) → Rootfs Cache (composed filesystem)- Layer cache: Content-addressable by compressed layer digest
- Rootfs cache: Content-addressable by combined layer digest (SHA256)
- Eviction: LRU when
max_rootfs_entriesormax_cache_bytesexceeded - Override: Set
A3S_IMAGE_CACHE_SIZEenvironment variable
Warm Pool Configuration
Pre-boot VMs for instant allocation:
pub struct PoolConfig {
pub enabled: bool, // Default: false
pub min_idle: usize, // Pre-warmed VMs to keep (default: 1)
pub max_size: usize, // Pool capacity limit (default: 5)
pub idle_ttl_secs: u64, // Idle VM time-to-live (default: 300s)
}How it works:
WarmPool::start()spawnsmin_idleVMs in background- Replenishment loop runs every second, keeping idle count at
min_idle pool.acquire()pops an idle VM instantly (no boot latency)pool.release(vm)returns VM to pool or destroys if at capacity- VMs exceeding
idle_ttl_secsare evicted automatically
pub struct PoolStats {
pub idle_count: usize,
pub total_created: u64,
pub total_acquired: u64,
pub total_released: u64,
pub total_evicted: u64,
}Pool activity is also tracked via Prometheus metrics: warm_pool_size (current idle count) and warm_pool_capacity (configured max_size), plus warm_pool_hits and warm_pool_misses counters.
Log Configuration
Docker-compatible JSON file logging with gzip-compressed rotation, plus syslog:
pub struct LogConfig {
pub driver: LogDriver,
pub options: HashMap<String, String>,
}
pub enum LogDriver {
JsonFile, // Docker-compatible JSON lines with gzip rotation (default)
Syslog, // Forward to syslog daemon (UDP or TCP)
None, // Disable logging
}Log format (json-file):
{"log":"hello\n","stream":"stdout","time":"2026-02-12T06:00:00.000000000Z"}json-file options:
Prop
Type
a3s-box run --log-driver json-file \
--log-opt max-size=50m \
--log-opt max-file=5 \
my-image:latestsyslog options:
Prop
Type
a3s-box run --log-driver syslog \
--log-opt syslog-address=udp://10.0.0.1:514 \
--log-opt tag=my-app \
my-image:latestState Persistence
All box state is persisted to ~/.a3s/boxes.json:
pub struct BoxRecord {
pub id: String, // Full UUID
pub short_id: String, // 12-char hex
pub name: String,
pub image: String,
pub status: String, // "created", "running", "stopped", "dead"
pub pid: Option<u32>, // Shim process PID
pub created_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
// ... 30+ additional fields
}Boxes can be referenced by full ID, short ID (12-char prefix), or name.
Environment Variables
Prop
Type