Bounded Origin is a Java 21 library and HTTP gateway that limits how much expensive origin computation incoming requests can cause. You define which requests mean the same work, how much new work may run, and which results can be reused.
flowchart LR
R[Request] --> P[Policy + semantic identity]
P --> S[Reuse or join]
P --> B[Bounded admission]
B --> O[Origin]
O --> S
S --> D[Response]
Serving a result can be cheap while producing it is expensive. Many URLs may name the same underlying operation; a stream of distinct requests may keep creating new work. Counting requests alone tells you neither how much computation they cause nor how much of it is redundant.
Bounded Origin puts the budget on that work. Equivalent requests can share one running computation. Distinct operations compete for explicitly limited capacity. Completed, reusable results can be served without computing them again.
The scraper-triggered rendering described in Creepy crawlies motivated this repository's approach to controlling origin work.
Routes define meaningful inputs, so irrelevant query noise need not create new
work. Global and per-policy budgets bound admission; full queues return 503 with
Retry-After, and unmatched requests are denied. Work whose completion is unknown
keeps consuming capacity across timeouts and restarts.
The reproducible campaign used a deterministic synthetic CPU workload, the packaged gateway, and independent origin-side work counts. It ran on Java 21 in a shared WSL2 Linux environment. The direct comparison uses the same origin, inputs and cost without the gateway or artifact reuse.
For 256 requests naming one operation at concurrency 64, across 10 measured repetitions, both gateway strategies used active capacity 1 and queue capacity 0:
| Path | Origin executions, mean [min, max] | Maximum actual origin concurrency |
|---|---|---|
| Direct origin | 256 [256, 256] | 45 |
BOUNDED_COMPUTE |
10 [9, 13] | 1 |
MATERIALIZE |
1 [1, 1] | 1 |
There is a latency cost. In the separate sequential-request comparison,
the median of per-trial p99 latencies was 81.5 ms through BOUNDED_COMPUTE
versus 20.4 ms directly.
Warm and restarted materialization required no origin recomputation. Distinct-key pressure stayed within capacity while rejecting excess work. Route matching and semantic-key costs grew with configuration complexity.
See Benchmarks for charts, complete results, limitations and reproduction commands, including overload runs with unsent client drops.
Download the 0.1.0 CLI distribution from
Releases:
bounded-origin-0.1.0.tar for POSIX or bounded-origin-0.1.0.zip for Windows.
The distribution includes its dependencies and requires Java 21.
For this local demonstration, also install Python 3 and save materialize.yaml and public_origin.py beside the downloaded archive. The configuration materializes public responses from a small loopback origin; the gateway itself needs no application code.
First, start the demonstration origin in its own terminal:
python public_origin.pyIn a second terminal, extract the distribution, validate the configuration and start the gateway:
POSIX
tar -xf bounded-origin-0.1.0.tar
./bounded-origin-0.1.0/bin/bounded-origin validate --config materialize.yaml
./bounded-origin-0.1.0/bin/bounded-origin run --config materialize.yamlWindows PowerShell
Expand-Archive .\bounded-origin-0.1.0.zip -DestinationPath .
.\bounded-origin-0.1.0\bin\bounded-origin.bat validate --config materialize.yaml
.\bounded-origin-0.1.0\bin\bounded-origin.bat run --config materialize.yamlvalidate exits silently with code 0 on success. In another terminal, send two
equivalent requests; on PowerShell use curl.exe:
curl "http://127.0.0.1:8080/hello/world?noise=one"
curl "http://127.0.0.1:8080/hello/%77orld?noise=two"Both return Hello from /hello/world. The configured path normalization and query
selection make them the same operation: the first request materializes the result,
and the second reuses it. Restart the gateway from the same working directory and
request it again to reuse the persisted artifact. The origin log shows which
requests actually reached it.
The example keeps state in bounded-origin-data/ and binds its listeners to
loopback. Its admin endpoint exposes metrics,
health and readiness. This is a wiring demonstration, separate from the benchmark
workload. Configuration changes take effect on restart.
The HTTP gateway is for public results that can be shared safely. Persisted results must remain valid for their versioned identity. Caller-specific, authenticated, conditional and range responses are outside this sharing model. The origin must explicitly affirm public sharing; see the representation contract.
The origin must guarantee that all work caused by an operation, including delegated work, finishes before its complete response. The gateway preserves uncertain work against its budget indefinitely. Deployments must preserve exclusive ownership state across restarts and route all bounded work through that domain. Read the ownership and recovery contract before deployment, including its filesystem and recovery requirements.
Bounded Origin complements authentication, TLS termination, ingress rate limits and CDN/WAF controls. It does not identify bots, eliminate incoming traffic or make arbitrary remote computation safe to cancel.
| Strategy | Behavior |
|---|---|
DENY |
Reject without origin computation. |
ARTIFACT_ONLY |
Serve a stored artifact; return 404 on a miss. |
BOUNDED_COMPUTE |
Share overlapping computation within budgets; do not persist new results. |
MATERIALIZE |
Reuse a stored artifact, or compute within budgets and publish the result. |
CLIENT_COMPUTE |
Return a JSON computation description for an application-supplied client implementation. |
Artifact reuse requires PUBLIC_IMMUTABLE; this also allows BOUNDED_COMPUTE to
reuse an existing artifact. PUBLIC permits sharing a running computation without
persistent reuse. The configuration reference covers these
contracts, every field, defaults, limits and operational metrics.
Java integrations can use the public API and execution core directly. Embedded producers must honor their computation-lifetime contracts and close owned result handles.
CI exercises Ubuntu and Windows, including packaged process tests, coverage and mutation gates, static analysis, dependency verification, reproducible archives and Docker smoke. Correctness tests cover concurrency, timeouts, disconnects, restart, representation boundaries and storage failures. Performance measurements run separately from ordinary correctness gates.
./gradlew clean check --init-script .github/spotbugs-reports.init.gradle --stacktraceWindows uses gradlew.bat. Report issues
with a reproducer and the version/configuration involved.
To build a CLI distribution from source, run ./gradlew :bounded-origin-cli:distTar
or gradlew.bat :bounded-origin-cli:distZip; archives are written to
bounded-origin-cli/build/distributions/.
The runtime is AGPL-3.0-only; bounded-origin-api is Apache-2.0.
See Licensing for component and third-party terms.