liner
liner is a lightweight, serverless, peer-to-peer message broker written in Rust. It provides a decentralized messaging mesh backed by Redis, SQLite, or PostgreSQL, with pure TCP between peers.
- Decentralized architecture — peer-to-peer mesh, no central broker process.
- Flexible storage — Redis, SQLite, or PostgreSQL (backends).
- At-least-once delivery — store-backed persistence and offline queues (per backend).
- Cross-language — Rust, Python, and C++ (C API).
- High message bandwidth — raw TCP; see benchmark.
- Messaging patterns — one-to-one, one-to-many, many-to-many, topic subscription.
- Unlimited payload size — not fixed by the wire format.
- Cross-platform — Linux and Windows.
Supported backends
| Backend | Mode | Best for |
|---|---|---|
| SQLite | Embedded single-file | Local dev, edge/IoT, zero extra services |
| Redis | In-memory key-value | Low latency, ephemeral catalog |
| PostgreSQL | Shared relational DB | Production persistence, ops familiarity |
- Redis — shared URL, default build. See using-redis.md.
- SQLite — per-process files;
receivers_jsonseeds peers on isolated DBs. See using-sqlite.md. - PostgreSQL — one shared database URL (Cargo feature
postgres). See using-postgres.md.
Quick example (Redis)
Rust:
use Liner;
Python:
=
=
SQLite / PostgreSQL constructors: Liner::new_sqlite, Client.new_sqlite, Liner::new_postgres, Client.new_postgres — see docs below.
Build
Install Rust and Cargo, then:
PostgreSQL backend:
Architecture

Examples of use
One to one: Python / CPP / Rust
One to one for many: Python / CPP / Rust
One to many: Python / CPP / Rust
Many to many: Python / CPP / Rust
Producer-consumer: Python / CPP / Rust
Benchmark
Three binaries run the same workload: two clients, send_to loop (10k messages × 100 cycles). Only the store differs (benchmark/).
| Binary | Store | Notes |
|---|---|---|
bench_pair_sendto_redis |
Redis | redis://localhost/, default build |
bench_pair_sendto_sqlite |
SQLite | Two temp .sqlite files; fixed ports; each side seeds the peer via receivers_json |
bench_pair_sendto_postgres |
PostgreSQL | One shared URL; cargo build --release --features postgres |
Sample output (liner + Redis, 10k messages per cycle):
$ ./bench_pair_sendto_redis
send_to 8 ms
receive_from 8 ms
send_to 5 ms
receive_from 5 ms
send_to 7 ms
receive_from 3 ms
send_to 11 ms
receive_from 3 ms
send_to 6 ms
receive_from 3 ms
About 10 ms on average for 10k messages.
Comparison with ZeroMQ on the same machine (make && ./compare_with_zmq):
$ make
g++ -Wall -O2 -std=c++17 -g -Wno-write-strings -o compare_with_zmq compare_with_zmq.cpp -lzmq
$ ./compare_with_zmq
Connecting to tcp://127.0.0.1:34079
send_to 20.198 ms
send_to 16.504 ms
send_to 11.5 ms
send_to 13.153 ms
send_to 10.964 ms
send_to 10.788 ms
send_to 10.785 ms
send_to 11.119 ms
send_to 11.348 ms
send_to 10.826 ms
For ZeroMQ it is similar (on the order of ~10 ms per 10k messages).
Tests
Rust unit tests:
# PostgreSQL store tests (optional):
LINER_TEST_POSTGRES_URL='postgresql://user:pass@127.0.0.1/liner_test' \
Python integration suites (build release library first):
PostgreSQL (requires postgres feature and a running database):
Redis tests under test/redis/ auto-start Redis via Docker when needed. Optional env:
LINER_TEST_REDIS_PORT=16379 LINER_TEST_REDIS_CONTAINER=liner-test-redis \
Docs
- Using Redis —
new_redis, shared URL,test/redis/ - Using SQLite —
new_sqlite,receivers_json, isolated DB limits - Using PostgreSQL —
--features postgres, shared database - Crate API on docs.rs
- Developer notes — errors, backends, C API, lifecycle
- C API compatibility and build
License
Licensed under the MIT License.