Green Software Roadmap
Status: planned (recorded 2026-10-01) for the v13 feature line. Nothing on
this page is a shipped capability unless it links to existing documentation.
Item 1 and parts of items 3 and 4 exist in the v13 development source
(13.0.0-alpha.4); see measured release defaults.
Goal
Rullst applications are compiled Rust services that render HTML on the server with little client-side JavaScript. Independent studies of programming-language energy efficiency rank Rust among the most efficient languages, and a small, long-running native process usually needs less CPU and memory than an interpreted stack for the same work. That is a real advantage, but it must be measured per application, not assumed.
The goal is to make the efficient path the default, and to let each team measure and report the footprint of its own Rullst application with a recognised, reproducible methodology.
Honest boundary: reports, not “greener than” certificates
Rullst will not issue certificates claiming that an application is “greener than” one built with another framework. Such comparative or generic environmental claims are regulated:
- In the European Union, Directive (EU) 2024/825 restricts generic environmental claims and requires claims to be substantiated.
- In the United States, the FTC Green Guides govern environmental marketing.
- In Brazil, consumer law and advertising self-regulation prohibit misleading environmental claims.
An unsubstantiated “green” badge could expose Rullst users to the very legal risk the legal & regulatory compliance roadmap aims to reduce. Instead, Rullst will produce dated, reproducible measurement reports that state the method, the environment and the limits, which teams can choose to publish.
Planned work
| # | Item | Notes |
|---|---|---|
| 1 | cargo rullst green report | 13.0.0-alpha.4 development source, Experimental command of the CLI: cargo rullst green (formerly footprint) reports only measured figures, each with its method: release binary size, a named local container image’s size, the started app’s idle resident memory, the Cargo.lock dependency count and, with --bench, the app’s CPU time per request under a bounded loopback load. It measures no energy; a Software Carbon Intensity figure (SCI, ISO/IEC 21031:2024) appears only as a labelled estimate from the measured CPU time and the power figure and grid intensity you supply. Still planned: a fixed multi-route reference scenario, repeated runs with a reported spread, and stated uncertainty for the estimate’s inputs. |
| 2 | Reproducible public benchmark | The same reference application implemented idiomatically in Rullst and in other frameworks, with published code, scenario, hardware and dates, so comparisons are verifiable instead of claimed. |
| 3 | Efficient release defaults | v13 source: generated projects get a tuned [profile.release] (thin LTO, one codegen unit, stripped symbols; panic stays unwind so one panicking handler cannot stop the server) and a distroless runtime image (CLI reference). Remaining: measured image sizes and fast start-up suitable for scale-to-zero hosting. |
| 4 | Efficient HTTP defaults | v13 source: the standard /static mount sends Cache-Control: public, max-age=31536000, immutable for content-hashed file names and no-cache with ETag/Last-Modified revalidation (304) for other files (static assets). Pre-compressed assets already exist: cargo rullst build writes Brotli/Zstandard siblings that the Core static handler serves. Remaining: fingerprinted names written by the asset pipeline itself and modern image formats. |
| 5 | Lean pages | Keep zero-bundle HTMX rendering the default, report page weight in cargo rullst dash, and warn on oversized assets. |
| 6 | Database efficiency | Development-time N+1 query warnings are in the v13 dash (N+1 query warning); slow-query hints are already visible there. Default pagination and index suggestions remain planned. |
| 7 | Carbon-aware jobs | Started in v13: see carbon-aware deferrable jobs. Region selection remains planned. |
| 8 | AI efficiency | Token usage is already reported by rullst-ai; add response caching, prompt-size budgets and guidance for choosing smaller or local models when they are sufficient. |
| 9 | Resource view in the dash | Show the app process’s CPU and memory next to the request metrics so developers see the cost of a change while they work. |
| 10 | Green hosting guidance | Document how to choose lower-carbon regions and providers, and show region information during cargo rullst deploy when it is available. |
Measured release defaults
Measured on 2026-10-08 with the 13.0.0-alpha.1 development source. The
numbers describe this one starter on this one machine; they are not a
prediction for other applications or hardware.
- Application:
cargo rullst new green_probe --default --skip-initial-migration(Blank starter, SQLite;rullstfeaturesorm,strict-sqlite,studio), dependency versions from the repositoryCargo.lock, built--offline. - Toolchain: Rust 1.98.1 (
RUSTUP_TOOLCHAIN=1.98.1),x86_64-unknown-linux-gnu, rustc’s default linker (the generated.cargo/config.tomlselected neither mold nor lld). - Machine: AMD Ryzen 5 7520U (8 logical CPUs), 3.4 GiB RAM, NVMe disk,
Ubuntu with GCC 15.2,
CARGO_BUILD_JOBS=2, a shared developer workstation. - Command:
/usr/bin/time -v cargo build --release --offline --target-dir <new empty directory>; size fromls -l <target-dir>/release/green_probe. - Samples: two cold builds per profile, in alternating order (default then generated, then generated then default).
[profile.release] | Binary size (bytes) | Wall-clock build (run 1 / run 2) | User CPU time (run 1 / run 2) | Largest process RSS (run 1 / run 2) |
|---|---|---|---|---|
| Cargo’s default (section absent) | 13,966,600 | 6:17 / 6:17 | 648 s / 648 s | 723 MiB / 726 MiB |
Generated: lto = "thin", codegen-units = 1, strip = "symbols" | 7,776,880 (−44.3 %) | 5:20 / 5:18 | 517 s / 516 s | 923 MiB / 970 MiB |
Each profile produced the same size in both runs. For comparison,
strip --strip-all applied to the default binary alone gives 10,031,552 bytes
(−28.2 %); thin LTO and one codegen unit account for the rest.
Limits of this measurement:
- With only two parallel jobs, a single codegen unit costs little parallelism; the lower CPU time is consistent with skipping the per-crate local ThinLTO across 16 units, but that cause was not isolated. With more parallel jobs the wall-clock result may reverse; that was not measured.
lto = true(fat LTO) was not measured: it needs more memory than this machine could spare alongside other work.- Runtime behaviour (requests per second, CPU time per request, memory) and energy were not measured.
- Container image size was not measured: Docker is not available on this
machine. Measure the generated distroless image with
docker image lsin CI or on a machine with Docker before publishing a number.
Carbon-aware deferrable jobs (v13)
Opt-in; first published in the 13.0.0-alpha.1 prerelease. A queue job or scheduled task can be marked deferrable with a deadline and daily time windows; see deferrable jobs and time windows. The mechanism:
- Time windows. The job becomes claimable at the start of the next allowed window (immediately inside an open one), never after its deadline; when no window opens in time, at the deadline.
- Optional intensity source. An application-provided
CarbonIntensitySourcereturns forecast slots with their unit. ACarbonAwarePlannerplaces the job at the lowest-value slot inside its windows before the deadline. Core ships no network source; if the source fails or times out, the window rule applies and one warning is logged per outage. - Persistence. Placement uses the queue’s existing scheduled-job timestamp, so no schema changes and 12.x rows keep working.
- Observability. The chosen time, the reason (
window,intensityordeadline) and the source name are returned inDeferredJoband recorded on arullst.queue.deferraltracing span.
The planner only shifts when a job runs, using the values the source reports. Whether that changes an application’s emissions depends on the grid, the workload and the data; Rullst does not measure or claim it.
Principles
- Measure, then claim: every number comes from a stated method and environment; estimates are labelled as estimates with their uncertainty.
- Defaults over options: efficiency should not require expert tuning.
- No hidden network calls: carbon-intensity data sources are opt-in, with an offline default.
- Small surface: measurement tooling lives in the CLI and development builds, never in production request paths.