Quickstart¶
Get Felix up and running in under 5 minutes.
Prerequisites¶
- Rust: 1.92.0 or later (install rustup)
- Git: For cloning the repository
- Optional: Task for convenience commands
Clone and Build¶
# Clone the repository
git clone https://github.com/gabloe/felix.git
cd felix
# Build the entire workspace in release mode
cargo build --workspace --release
The release build is recommended for performance testing. Development builds have significantly higher overhead.
Start the Broker¶
Run the Felix broker in a terminal:
You should see structured log output:
2026-01-25T10:00:00.000Z INFO felix_broker: Starting Felix broker
2026-01-25T10:00:00.001Z INFO felix_broker: QUIC listening on 0.0.0.0:5000
2026-01-25T10:00:00.001Z INFO felix_broker: Metrics server on 0.0.0.0:8080
The broker is now ready to accept connections!
Default ports:
5000: QUIC data plane (publish, subscribe, cache)8080: Metrics/health endpoint
Run a Demo¶
Felix includes several self-contained demos that start an in-process broker and QUIC server. You do not need to run the broker separately for these demos.
This demo:
- Creates a client connection to the broker
- Subscribes to a test stream
- Publishes two messages to that stream
- Displays the received events
Sample output:
== Felix QUIC Pub/Sub Demo ==
Step 1/6: booting in-process broker + QUIC server.
Step 2/6: connecting QUIC client.
Step 3/6: opening a subscription stream.
Step 4/6: publishing two messages on the same stream.
Step 5/6: receiving events.
Event on demo-topic: hello
Event on demo-topic: world
Demo complete.
More demos:
cargo run --release -p broker --bin cache-demo
cargo run --release -p broker --bin latency-demo
cargo run --release -p broker --bin pubsub-demo-notifications
cargo run --release -p broker --bin pubsub-demo-orders
cargo run --manifest-path demos/rbac-live/Cargo.toml
cargo run --manifest-path demos/cross_tenant_isolation/Cargo.toml
See the Demos Overview for details on what each demo does and what to expect.
Note: the cross-tenant isolation demo uses a Postgres-backed control plane.
Try the Cache¶
Run the cache demonstration:
This benchmarks cache operations (put, get_hit, get_miss) across various payload sizes and measures latency/throughput.
Using the Client SDK¶
Here's a minimal example of using the Felix Rust client:
Publish and Subscribe¶
use felix_client::{Client, ClientConfig};
use felix_wire::AckMode;
use std::net::SocketAddr;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Configure client
let quinn = quinn::ClientConfig::with_platform_verifier();
let config = ClientConfig::optimized_defaults(quinn);
let addr: SocketAddr = "127.0.0.1:5000".parse()?;
// Connect to broker
let client = Client::connect(addr, "localhost", config).await?;
let publisher = client.publisher().await?;
// Subscribe to a stream
let mut subscription = client
.subscribe("my-tenant", "my-namespace", "my-stream")
.await?;
// Spawn a task to receive events
tokio::spawn(async move {
while let Some(event) = subscription.next_event().await.unwrap() {
println!("Received: {:?}", event.payload);
}
});
// Publish messages
for i in 0..10 {
let payload = format!("Message {}", i);
publisher
.publish(
"my-tenant",
"my-namespace",
"my-stream",
payload.into_bytes(),
AckMode::None,
)
.await?;
}
Ok(())
}
Cache Operations¶
use bytes::Bytes;
use felix_client::{Client, ClientConfig};
use std::net::SocketAddr;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let quinn = quinn::ClientConfig::with_platform_verifier();
let config = ClientConfig::optimized_defaults(quinn);
let addr: SocketAddr = "127.0.0.1:5000".parse()?;
let client = Client::connect(addr, "localhost", config).await?;
// Put a value with 60-second TTL
client
.cache_put(
"my-tenant",
"my-namespace",
"users",
"user:123",
Bytes::from_static(b"alice"),
Some(60_000),
)
.await?;
// Get the value
if let Some(value) = client
.cache_get("my-tenant", "my-namespace", "users", "user:123")
.await?
{
println!("Cached value: {:?}", value);
}
Ok(())
}
API Surface
The exact client API is evolving. Check crates/felix-client/src/ for the current implementation. The examples above represent the intended ergonomics.
Performance Testing¶
Latency Benchmark¶
Run the latency demo with various configurations:
# Basic run with defaults
cargo run --release -p broker --bin latency-demo
# Custom configuration
cargo run --release -p broker --bin latency-demo -- \
--binary \
--fanout 10 \
--batch 64 \
--payload 4096 \
--total 10000 \
--warmup 500
Parameters:
--binary: Use binary batch format (higher throughput)--fanout N: Number of concurrent subscribers--batch N: Batch size for publishing--payload N: Payload size in bytes--total N: Total messages to send--warmup N: Warmup messages before measurement
Cache Benchmark¶
Measures cache operations at various payload sizes with configurable concurrency.
Configuration¶
Felix can be configured via environment variables or a YAML config file.
Environment Variables¶
Key performance tuning variables:
# Event delivery (pub/sub)
export FELIX_EVENT_CONN_POOL=8
export FELIX_EVENT_BATCH_MAX_DELAY_US=250
# Cache operations
export FELIX_CACHE_CONN_POOL=8
export FELIX_CACHE_STREAMS_PER_CONN=4
# Publishing
export FELIX_PUBLISH_CHUNK_BYTES=16384
Config File¶
Create /tmp/felix-config.yml:
quic_bind: "0.0.0.0:5000"
metrics_bind: "0.0.0.0:8080"
event_batch_max_events: 64
event_batch_max_delay_us: 250
cache_conn_recv_window: 268435456
Run with custom config:
See Configuration Reference for all options.
Using Task¶
If you have Task installed, you can use convenience commands:
# Build
task build
# Run tests
task test
# Format code
task fmt
# Run linter
task lint
# Run demos
task demo:pubsub
task demo:cache
task demo:latency
task demo:notifications
task demo:orders
task demo:rbac-live
task demo:cross-tenant-isolation
See Taskfile.yml in the repository root for all available tasks.
Next Steps¶
Now that you have Felix running:
- Explore the Architecture: System Design
- Learn the APIs: Broker API
- Tune Performance: Performance Guide
- Deploy Properly: Deployment Guides
- Contribute: Development Guide
Troubleshooting¶
Port Already in Use¶
If port 5000 or 8080 is in use:
# Change broker port
export FELIX_QUIC_BIND="0.0.0.0:5001"
export FELIX_METRICS_BIND="0.0.0.0:8081"
cargo run --release -p broker
Build Errors¶
Ensure you have Rust 1.92.0 or later:
Update if needed:
Connection Refused¶
Make sure the broker is running and listening:
See Troubleshooting Guide for more help.