Velocity Cache is a high-performance, asynchronous HTTP caching proxy written in Rust. It is an implementation of the Vinyl Cache concept—building a "Rust-native Varnish" that leverages Rust's memory safety and concurrency primitives (Tokio) to move bytes efficiently.
The project acts as a transparent proxy that sits between clients and your backend infrastructure, caching responses in memory to reduce load and latency. It supports programmable policies via WebAssembly (Wasm).
- High Performance: Built on
hyper,tokio, andrustlsfor fast, async I/O. - In-Memory Caching: Uses
mokafor efficient, concurrent cache storage with automatic expiration. - Request Collapsing: Prevents cache stampedes by merging concurrent requests for the same resource (implied architecture).
- Wasm Policies: Replaces complex configuration languages (like VCL) with Wasm modules, allowing you to compile logic for TTL overrides and header manipulation from languages like Rust, Go, or TypeScript.
- TLS Support: Native HTTPS backend support using
rustls.
The codebase is organized into modular components representing the lifecycle of a request:
src/main.rs: The entry point. It parses environment variables, sets up the TCP listener, initializes the Wasm engine pool, and starts the main application loop.src/velocity.rs: Contains the core logic for accepting incoming connections and orchestrating the proxy flow (The "Pipe").src/server.rs: Handles communication with the upstream backend. It manages the HTTP client, TLS handshakes, and executes Wasm hooks (e.g.,vcl_backend_response).src/cache.rs: Defines the storage layer structures (CacheKey,CachedResponse) and expiration policies usingmoka(The "Slab").src/wasm_engine.rs: Manages the lifecycle of Wasm instances (Extism) and provides the interface for running policy hooks.src/proxy_handler.rs: Handles the incoming client request logic.src/types.rs: Shared error types and definitions.
Velocity is configured primarily via Environment Variables.
| Variable | Description | Default |
|---|---|---|
VELOCITY_HOST |
The host to listen on. | 127.0.0.1 |
VELOCITY_PORT |
The port to listen on. | 8080 |
VELOCITY_CACHE_MAX_CAPACITY |
Cache max capacity (entries). | 10000 |
VELOCITY_BACKEND |
The default upstream backend host. | httpbin.org |
VELOCITY_WASM_POLICY_PATH |
Path to the compiled Wasm policy file. | policy.wasm |
VELOCITY_POOL_SIZE |
Number of Wasm instances to keep in the pool. | 4 |
| Argument | Short | Description |
|---|---|---|
--host |
-h |
The host to listen on. |
--port |
-p |
The port to listen on. |
--cache-max-capacity |
-cmc |
Cache max capacity (entries). |
--backend |
-b |
The backend host to proxy to. |
--wasm-policy-path |
-wpp |
Path to the Wasm policy file. |
--wasm-pool-size |
-wps |
Size of the Wasm instance pool. |
The command line arguments override environment variables if they are set in both places.
- Rust (latest stable)
- A compiled Wasm policy file (optional, but recommended).
To build the project in release mode for maximum performance:
cargo build --release-
Prepare a Wasm Policy (Optional): If you don't have a
policy.wasm, the server will start without the policy engine, printing a warning. To use policies, ensure a validpolicy.wasmis present in the root or specified viaVELOCITY_WASM_PATH. -
Run the Server:
# Run with defaults (Proxies to httpbin.org on port 8080) cargo run # Run with custom backend using arguments cargo run -- --backend example.com # Run on a different port with a specific Wasm policy cargo run -- -p 9090 -w ./my-policies/ttl.wasm
-
Test the Proxy: Open another terminal and make a request:
curl -v http://127.0.0.1:8080/get
The first request will be a MISS (fetched from backend). Subsequent requests to the same URL should be HITS (served from memory), provided the TTL hasn't expired.
Run the internal unit and integration tests:
cargo testThere is also a shell script provided for manual testing scenarios:
./test.shVelocity uses a "VCL-lite" approach but replaces proprietary scripting with WebAssembly.
test_policy.wasm is a simple example policy for test code purposes.
Loading a policy file is optional, but recommended for production use.
Warning: Policy loading increases startup time.