Architecture
This page covers the internals of RuleX. It is intended for a technical audience.
Build pipeline
When a Data Source is uploaded, RuleX transpiles the Excel formulas into Rust source code, which is then compiled into a WebAssembly module. This module is compiled Ahead-of-Time (AOT) into a native executable for each supported target architecture (x86_64-linux, aarch64-linux).
Endpoints depend on this executable. Until compilation is complete, an Endpoint returns HTTP 404.
Note
In demo.rulex.coverstack.in, only WebAssembly modules are generated. Executables are compiled on demand when you self-host.
Request-response cycle
Once the executable is ready, each request follows this flow:
Each request is authenticated and validated against the configured Schema. Failures are rejected immediately. Passing requests are sent to the runtime: inputs are fed in, outputs are read out, and the result is translated into an HTTP response.
Runtime
The runtime is powered by rulex-runtime, a Rust extension built on Wasmer with the LLVM compiler backend. It manages the lifecycle of WebAssembly instances, an LRU cache of recently used modules, and a thread pool for concurrent execution.
rulex-runtime is the package that powers Self Hosting. It is included as a dependency in rulex.zip.
Caching hints
Each calculation returns a caching hint alongside its output. RuleX uses this to determine whether a response can be cached and for how long:
| Hint | Meaning |
|---|---|
Forever |
Output depends only on the inputs. Safe to cache indefinitely. |
Today |
Output depends on the current date (e.g. a model using TODAY()). Safe to cache until midnight. |
Never |
Output depends on a volatile function such as NOW() or RAND(). Must not be cached. |
RuleX uses this hint internally to cache results in full access mode. The self-hosted server does not implement caching.
Concurrency
Each call to the executable is fully isolated and concurrent requests do not share state. The runtime releases Python's Global Interpreter Lock (GIL) before acquiring a thread slot, so multiple calculations run in parallel on separate OS threads.
When self-hosting, configure concurrency no higher than the number of physical CPU cores on the host.