A high-performance AMQP 0.9.1 message broker written in Go. Compatible with RabbitMQ clients and tools.
RabbitMQ is the gold standard for AMQP 0.9.1, but it runs on the Erlang VM — a separate runtime with its own scheduling, memory model, and operational overhead. StrangeQ exists for teams that want:
- Embeddable: Run it as a library inside your Go application. No separate process, no Erlang runtime, no Docker image required for tests.
- Go-native observability: Native
net/http/pprofendpoints for CPU, memory, goroutine, and mutex profiling. Usego tool pprofdirectly — no Erlang tooling required. - Single binary deployment: One static binary with no runtime dependencies. Cross-compile for any Go-supported platform with a single command.
- AMQP 0.9.1 wire compatibility: Drop-in replacement for RabbitMQ from any AMQP 0.9.1 client (Go, Python, Node.js, Java, Ruby, C#).
- Transparent internals: The entire broker is readable Go source code. Debug, profile, and extend with standard Go tooling.
- AMQP 0.9.1 protocol compatible with RabbitMQ clients (Go, Python, Node.js, Java, Ruby, C#)
- Exchange types: direct, fanout, topic (with
*and#wildcards), headers (withx-match: all,any,all-with-x,any-with-x) - Exchange-to-exchange bindings with cycle detection
- Three-tier storage architecture (in-memory hot cache → WAL (durable) → segments (cold fallback))
- Persistent and non-persistent messages with crash recovery
- TLS/SSL encryption with mutual TLS support
- SASL authentication (PLAIN, ANONYMOUS)
- Authorization with RabbitMQ-style configure/write/read permissions per vhost
- Publisher confirms (
confirm.select) - Transactions (
tx.select/tx.commit/tx.rollback) with publish and ack buffering basic.getwith synchronous message retrieval and ack trackingbasic.returnfor unroutable mandatory messagesbasic.recoverfor redelivering unacknowledged messagesqueue.purgefor removing all messages from a queuechannel.flow/channel.flow-okfor start/stop of content frames- Message & queue TTL —
x-message-ttl, per-messageexpiration, andx-expiresidle-queue expiry - Dead-letter exchanges —
x-dead-letter-exchange/x-dead-letter-routing-keywith fullx-death/x-first-death-*headers - Queue length limits —
x-max-length/x-max-length-byteswithx-overflow(drop-head,reject-publish) - Resource alarms —
connection.blocked/connection.unblockeddriven by memory (RSS) and free-disk watermarks - Exclusive and auto-delete queues with automatic cleanup (exclusive queues deleted on owning-connection close; auto-delete queues deleted when the last consumer leaves)
- Faster than RabbitMQ 4.4 Classic on every benchmark workload in the default
barriermode — from a tie on 64 KiB 1p/1c to +210% on 1 KiB 32p/32c — with 12-79% less peak memory. See Performance - Prometheus metrics and pprof profiling
- Management control plane — a RabbitMQ-compatible REST API plus an embedded single-binary web UI (go:embed, no CDN), including a Metrics tab over the live Prometheus matrix
- Byte-bounded per-queue hot cache with its own eviction budget
- Batch TCP writes and ACK offloading
Download the latest release for your platform from the releases page. Each platform ships as a tarball (amqp-server-<version>-<os>-<arch>.tar.gz) that contains the amqp-server binary, config.sample.yaml, README.txt, and LICENSE, plus a .sha256 checksum.
# macOS/Linux (replace <version>, <os>, <arch> with your release)
tar -xzf amqp-server-<version>-<os>-<arch>.tar.gz
cd amqp-server-<version>-<os>-<arch>/
sudo mv amqp-server /usr/local/bin/
# Verify installation
amqp-server --versiongit clone https://github.com/maxpert/strangeq.git
cd strangeq/src/amqp-go
go build -o amqp-server ./cmd/amqp-server
sudo mv amqp-server /usr/local/bin/The Go module path (github.com/maxpert/amqp-go) does not match the
repository path (github.com/maxpert/strangeq), so go install ...@latest is
not supported. Build from source as shown above.
# Defaults: persistent storage in ./data, listening on 127.0.0.1:5672,
# authentication off
amqp-server
# Generate example config
amqp-server --generate-config config.yaml
# Run with config file
amqp-server --config config.yaml
# With TLS
amqp-server --tls --tls-cert cert.pem --tls-key key.pem
# With mutual TLS (client cert verification)
amqp-server --tls --tls-cert cert.pem --tls-key key.pem --tls-ca ca.pem
# With telemetry (Prometheus metrics and /health)
amqp-server --config config.yaml --enable-telemetry
# Telemetry also with pprof (heap/goroutine dumps)
amqp-server --config config.yaml --enable-telemetry --enable-pprof
# With the management control plane (REST API + web UI at http://127.0.0.1:15672)
amqp-server --config config.yaml --managementEnvironment variables apply with or without --config. The format is
AMQP_<SECTION>_<KEY>; keys may use underscores. Precedence is
defaults → file → environment → explicitly set flags.
AMQP_NETWORK_PORT=15672 amqp-server --config config.yaml
AMQP_NETWORK_ADDRESS=0.0.0.0:5672 amqp-server
AMQP_STORAGE_PATH=/var/lib/amqp amqp-server
AMQP_SECURITY_AUTHENTICATION_ENABLED=true amqp-server
AMQP_SERVER_LOGLEVEL=debug amqp-serverAMQP_NETWORK_PORT rewrites the port in network.address. List-valued keys
can only be set from the environment as a single element; use the config file
for lists.
amqp-server [options]
--config string Configuration file path (YAML/JSON)
--generate-config string Generate default config file (mode 0600) and exit
--version Show version and exit
--enable-telemetry Enable telemetry HTTP endpoint (/metrics, /health)
--telemetry-port int Telemetry port (default from config: 9419)
--telemetry-address string Telemetry bind address (default from config: 127.0.0.1)
--enable-pprof Enable pprof endpoints (off by default)
--management Enable the management control plane (REST API + web UI)
--management-address string Management API bind address (default from config: 127.0.0.1)
--management-port int Management API port (default from config: 15672)
--healthcheck Probe the local /health endpoint and exit 0/1
--unsafe-recovery Start despite unrecoverable artifacts (DATA LOSS)
--tls Enable TLS (amqps)
--tls-cert string TLS certificate file (PEM)
--tls-key string TLS private key file (PEM)
--tls-ca string TLS CA file for mutual TLS client verification (PEM)
Flags that are not passed keep the value from the file or environment; flag defaults are documentation only.
import pika
connection = pika.BlockingConnection(
pika.ConnectionParameters('localhost')
)
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(
exchange='',
routing_key='hello',
body='Hello World!'
)
print(" [x] Sent 'Hello World!'")
connection.close()const amqp = require('amqplib');
async function main() {
const connection = await amqp.connect('amqp://localhost');
const channel = await connection.createChannel();
await channel.assertQueue('hello');
channel.sendToQueue('hello', Buffer.from('Hello World!'));
console.log(" [x] Sent 'Hello World!'");
await connection.close();
}
main().catch(console.error);package main
import (
"log"
amqp "github.com/rabbitmq/amqp091-go"
)
func main() {
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
ch, err := conn.Channel()
if err != nil {
log.Fatal(err)
}
defer ch.Close()
q, err := ch.QueueDeclare("hello", false, false, false, false, nil)
if err != nil {
log.Fatal(err)
}
err = ch.Publish("", q.Name, false, false, amqp.Publishing{
ContentType: "text/plain",
Body: []byte("Hello World!"),
})
if err != nil {
log.Fatal(err)
}
log.Println(" [x] Sent 'Hello World!'")
}See CLIENT_EXAMPLES.md for complete examples including consumers, exchanges, and advanced patterns.
See src/amqp-go/config.sample.yaml for full configuration with documented defaults.
network:
address: 127.0.0.1:5672
storage:
path: ./data
server:
loglevel: infoThis loads on top of the defaults; omitted keys keep their default values. A minimal file no longer fails validation.
network:
address: "0.0.0.0:5672"
maxconnections: 10000
tcpkeepalive: true
storage:
path: /var/lib/amqp
durability: barrier
security:
tlsenabled: true
tlscertfile: /etc/amqp/cert.pem
tlskeyfile: /etc/amqp/key.pem
authenticationenabled: true
authenticationfilepath: /etc/amqp/auth.json
allowedhosts: ["10.0.0.0/8", "localhost"]
resourcealarms:
enabled: true
memoryhighwatermark: 0.8
telemetry:
enabled: true
address: 127.0.0.1
port: 9419
server:
loglevel: info
engine:
maxqueuebacklog: 209715
walbatchsize: 1000Run it under systemd (see deployment/systemd/) rather than daemonize: true
and a PID file; the unit handles restart, environment, and logging.
Key engine tuning parameters:
maxqueuebacklog— Per-queue publisher backpressure depth high-water mark in messages (default 52428; 0 = default). The hot-cache byte budget usually binds first.walbatchsize— Messages per WAL batch (default 1000)walbatchtimeoutms— Retained for compatibility; WAL sync is drain-then-sync, not timer-gatedwalfilesize— Size of each WAL file (default 512 MB)segmentsize— Cold storage segment file size (code default 64 MB; the shippedconfig.sample.yamlsets 256 MB)walcleanupcheckintervalms— WAL reclaim sweep interval (code default and shipped sample: 1000 ms)consumermaxbatchsize— Max messages to deliver per consumer per poll (default 100)
Three storage keys were removed in 0.15.0 and are now reported as unknown keys
at load: storage.cachemb, storage.maxfiles and storage.retentionms. They
were parsed but read by no engine path, so dropping them changes no behaviour —
a config that still carries them starts normally and logs one warning per key.
Remove them to silence the warning.
Separately, the retired engine depth keys — engine.ringbuffersize,
engine.spillthresholdpercent, engine.depthhighwmoverride and
engine.depthhighwm — are rejected at boot rather than ignored, because
silently dropping them would change the per-queue publisher backpressure depth.
Replace them with engine.maxqueuebacklog; the mapping is
ringbuffersize × spillthresholdpercent / 100. See CHANGELOG.md for the full
0.15.0 breaking-change list.
Benchmarks run on a 16-core Apple Silicon (M4 Max) machine with an APFS data
volume, one broker at a time, driven by the same client — cmd/perftest
(amqp091-go) with identical flags for both brokers. This table is the default
durability mode only (storage.durability: barrier). Per cell: durable queue,
persistent messages, publisher confirms, manual acks, consumer prefetch 100,
outstanding window 1000; 10 s warm-up then a 30 s measured window, with msg/s
taken as the median per-second end-to-end delivered rate (every published
message confirmed, acked and delivered, lost=0) and RSS as peak resident set
size. StrangeQ cells are 3-4 stall-free repetitions from the 2026-11-09 session
(0.15.0); RabbitMQ is 4.4 Classic queues at its best-measured configuration
(reference campaign).
| Workload (message size, producers/consumers) | StrangeQ msg/s | RabbitMQ msg/s | margin | StrangeQ RSS | RabbitMQ RSS | margin |
|---|---|---|---|---|---|---|
| 1 KiB, 1p/1c | 141,392 | 96,318 | +47% | 229 MB | 259 MB | −12% |
| 1 KiB, 10p/10c | 159,259 | 86,262 | +85% | 271 MB | 397 MB | −32% |
| 64 KiB, 1p/1c | 35,504 | 35,463 | tie | 251 MB | 1,195 MB | −79% |
| 64 KiB, 10p/10c | 44,677 | 36,864 | +21% | 655 MB | 2,020 MB | −68% |
| 1 KiB, 32p/32c | 140,455 | 45,339 | +210% | 324 MB | 539 MB | −40% |
- StrangeQ is faster or tied on every workload, with 12-79% less peak memory.
- Durability is a dial, not a switch:
noneconfirms on write-completion and survives a broker crash only; the defaultbarrier(above) additionally survives an OS crash;flushwaits for the drive to flush to media (power-loss safe) and is ~10-30% slower on Apple Silicon. The cells above arebarrieronly. - The 64 KiB rows are bounded by durable write bandwidth; the 1 KiB rows are CPU/dispatch bound, which is where added producers and consumers raise throughput.
cd src/amqp-go
go run ./cmd/perftest -url amqp://guest:guest@localhost:5672/ \
-durable -confirm -producers 10 -consumers 10 -size 65536 \
-duration 30s -outstanding 1000 -prefetch 100Point -url at either broker — both speak AMQP 0.9.1. RabbitMQ 4.4 for
comparison:
docker run -d --name rabbitmq-bench --platform linux/arm64 -p 5672:5672 rabbitmq:4.4-managementRun on the same kind of storage you intend to deploy against: the default
barrier guarantee depends on the platform's device-sync primitive.
| Method | StrangeQ | RabbitMQ |
|---|---|---|
connection.start / start-ok |
Yes | Yes |
connection.tune / tune-ok |
Yes | Yes |
connection.open / open-ok |
Yes | Yes |
connection.close / close-ok |
Yes | Yes |
connection.blocked / unblocked |
Yes (memory/disk alarms) | Yes |
connection.secure / secure-ok (method — multi-step SASL) |
No | Yes |
channel.open / open-ok |
Yes | Yes |
channel.close / close-ok |
Yes | Yes |
channel.flow / flow-ok |
Yes | Yes |
exchange.declare / declare-ok |
Yes | Yes |
exchange.delete / delete-ok |
Yes | Yes |
exchange.bind / bind-ok |
Yes | Yes |
exchange.unbind / unbind-ok |
Yes | Yes |
queue.declare / declare-ok |
Yes | Yes |
queue.delete / delete-ok |
Yes | Yes |
queue.bind / bind-ok |
Yes | Yes |
queue.unbind / unbind-ok |
Yes | Yes |
queue.purge / purge-ok |
Yes | Yes |
basic.qos / qos-ok |
Yes (per-channel; global QoS not enforced) | Yes |
basic.consume / consume-ok |
Yes | Yes |
basic.cancel / cancel-ok |
Yes | Yes |
basic.publish |
Yes | Yes |
basic.ack |
Yes | Yes |
basic.nack |
Yes | Yes |
basic.reject |
Yes | Yes |
basic.get / get-ok / get-empty |
Yes | Yes |
basic.deliver |
Yes | Yes |
basic.return |
Yes | Yes |
basic.recover / recover-ok |
Yes | Yes |
tx.select / commit / rollback |
Yes | Yes |
confirm.select / select-ok |
Yes | Yes |
| Type | StrangeQ | RabbitMQ |
|---|---|---|
direct |
Yes | Yes |
fanout |
Yes | Yes |
topic |
Yes (* single-word, # zero-or-more words) |
Yes |
headers |
Yes (x-match: all, any, all-with-x, any-with-x) |
Yes |
| Feature | StrangeQ | RabbitMQ |
|---|---|---|
| TLS | Yes | Yes |
| Mutual TLS (mTLS) | Yes | Yes |
| SASL PLAIN | Yes | Yes |
| SASL ANONYMOUS | Yes (opt-in; disabled by default) | Yes |
| SASL EXTERNAL | No | Yes |
| File-based authentication | Yes (bcrypt) | Yes |
| Per-vhost authorization | Yes (RabbitMQ-style regex) | Yes |
| Loopback restriction | Yes | Yes |
| Feature | StrangeQ | RabbitMQ |
|---|---|---|
| Durable queues | Yes | Yes |
| Durable exchanges | Yes | Yes |
| Persistent messages (delivery mode 2) | Yes | Yes |
| WAL (write-ahead log) | Yes | Yes |
| Crash recovery | Yes | Yes |
| Bindings persistence | Yes | Yes |
| Extension | StrangeQ | Notes |
|---|---|---|
x-message-ttl (per-queue) |
Yes | Message expires after N ms in the queue |
Per-message expiration |
Yes | Effective TTL = min(per-message, per-queue) |
x-expires (queue TTL) |
Yes | Idle queue auto-deletes after N ms with no consumers/get/redeclare |
x-dead-letter-exchange |
Yes | Rejected / expired / evicted messages re-routed through the normal router |
x-dead-letter-routing-key |
Yes | Overrides the routing key on dead-letter (else the original key is kept) |
x-death / x-first-death-* headers |
Yes | Full array-of-tables with count/reason/queue/time/exchange/routing-keys aggregation |
x-max-length |
Yes | Cap on ready message count |
x-max-length-bytes |
Yes | Cap on ready message bytes |
x-overflow |
Yes | drop-head (evict oldest → DLX) or reject-publish (nack/return/drop the incoming message) |
x-last-death-* headers |
No | Deferred; only x-first-death-* + the x-death array are emitted |
x-max-priority (priority queues) |
No | See Not Yet Supported |
Dead-letter reason values match RabbitMQ: rejected (nack/reject with requeue=false), expired (TTL), maxlen (drop-head eviction). Cycle detection matches RabbitMQ too — a rejected loop is not broken (it cycles), while expired/maxlen are dropped on a queue-name match.
StrangeQ is wire-compatible, but a few observable behaviors intentionally differ. All are verified against RabbitMQ 4.3 by the conformance suite (make conformance-rabbitmq):
mandatory+ fullreject-publishqueue: StrangeQ returns the message viabasic.return(reply code 312); RabbitMQ does not return a routable-but-full message.x-message-ttl: 0/expiration: 0with no ready consumer: the message is dropped. StrangeQ has no publish-time direct hand-off to a waiting consumer, so a zero-TTL message cannot be delivered-before-expiry.- Malformed / non-numeric per-message
expiration: treated as "no TTL" (lenient) rather than a channel error. reject-publishinside a transaction: not enforced (a tx-published message to a full reject-publish queue is accepted);drop-headinside a transaction is enforced.
The following RabbitMQ features are not implemented:
- Clustering and high availability
- Priority queues (
x-max-priority) - Lazy queues (
x-queue-mode) - Consumer priorities (
x-priority) connection.secure/secure-ok(multi-step challenge-response auth; thesecure/sslconnection properties are reported on/api/connections, but the multi-step method itself is not implemented)- SASL EXTERNAL
- Global prefetch (
basic.qoswithglobal=true) — accepted but applied per-consumer, not enforced globally - Prefetch size (
basic.qoswithprefetch_size > 0) — rejected with a540 not implementedchannel error rather than silently ignored - Management CLI tools (the REST API and web UI are available; see docs/MANAGEMENT.md)
- Hot Cache: Byte-bounded per-queue in-memory cache with its own eviction budget
- WAL Spill: Durable messages are written to the write-ahead log with a batched group-commit durability barrier; a transient message the hot cache cannot admit spills to the WAL too.
- Segment Storage: Cold message storage in segment files, read after the WAL on the cold path
- Per-Queue Isolation: Each queue has its own hot cache, WAL cursor, and consumer dispatch — no cross-queue contention
- Reader/Processor Separation: TCP reader and frame processor run in separate goroutines
- ACK Offloading: A dedicated goroutine handles ACK/NACK/reject frames — eliminates head-of-line blocking on the frame processor
- Batched TCP Writes: Deliveries in a batch are serialized into a single buffer and sent with one write — reduces syscalls and lock acquisitions
- Direct-Write Serialization: Frame bytes are written directly into the batch buffer — eliminates intermediate object allocations
- Vectored Delivery: Message bodies of 32 KB or larger are delivered with scatter-gather I/O (
writev) — the body is sent directly from its buffer with no intermediate copy - Object Pooling: Frames, publish methods, pending messages, and content headers are pooled via
sync.Pool - Flow Control:
channel.flowgates delivery forwarding with a single atomic load — zero overhead when flow is active
- Validate storage integrity
- Recover durable exchanges and queues
- Rebuild bindings
- Load persistent messages into the hot cache
- Restore pending acknowledgments
Recovery is incremental (recovery time is not measured in this document).
# Install the unit and the shipped config (see deployment/systemd/README.md
# for the auth file and directory setup)
sudo cp deployment/systemd/amqp-server.service /etc/systemd/system/
sudo install -o root -g amqp -m 0640 deployment/systemd/config.yaml /etc/amqp/config.yaml
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable amqp-server
sudo systemctl start amqp-server
# Check status
sudo systemctl status amqp-servermake docker-build VERSION=0.1.0
docker run --rm -p 5672:5672 -p 9419:9419 -v amqp-data:/var/lib/amqp amqp-go:0.1.0The image binds 0.0.0.0 with authentication off by default (it prints the
startup security warning). To enable authentication, mount an auth file and set
AMQP_SECURITY_AUTHENTICATIONENABLED=true and
AMQP_SECURITY_AUTHENTICATIONFILEPATH=/etc/amqp/auth.json.
The image's HEALTHCHECK uses amqp-server --healthcheck, which probes the
same telemetry address/port from the environment.
For protocol interoperability testing with RabbitMQ, the repository also includes a docker-compose file:
cd src/amqp-go/protocol
docker-compose upTwo optional HTTP surfaces can be enabled independently of the broker listener:
-
Management control plane — a RabbitMQ-4.4-management-subset REST API plus an embedded single-page web UI, served from the same binary (assets are
go:embed-ed; no separate folder, build step, or CDN). Off by default and loopback-only by default.amqp-server --config config.yaml --management # Management API listening on http://127.0.0.1:15672 # open http://127.0.0.1:15672/ in a browser
See docs/MANAGEMENT.md for enabling it, the startup refusal matrix, the auth model (capabilities, sessions + CSRF, loopback/host ACLs, rate limits), the full REST API reference, the UI screens, and the honest divergences from RabbitMQ.
-
Telemetry — Prometheus metrics, readiness, and optional pprof.
amqp-server --config config.yaml --enable-telemetry
See docs/METRICS.md for the serving endpoints, the full emitted
amqp_*metric reference, alerting queries, and what is deliberately not emitted.
The management UI includes a Metrics tab that renders the same Prometheus matrix the
telemetry listener exposes (a 45-tile vital-stats panel, a searchable family browser, and a
raw view) from a same-origin, auth-gated GET /api/metrics.
| Feature | StrangeQ | RabbitMQ |
|---|---|---|
Connection secure/ssl property (/api/connections) |
Yes | Yes |
GET /api/connections also reports auth_mechanism, the SASL mechanism that authenticated
the connection. Both fields describe transport/identity state, not protocol-method support:
secure/ssl are derived from the transport (a *tls.Conn), never from the SASL mechanism.
Enable telemetry to expose Prometheus metrics and readiness:
amqp-server --config config.yaml --enable-telemetryTelemetry binds 127.0.0.1:9419 by default. Use --telemetry-address (or
telemetry.address) to change the bind address. /health is a readiness
probe: it returns 503 until recovery has completed and the AMQP listener is
bound, and 503 during shutdown. During a resource alarm it still returns 200
with OK (resource alarm active: memory,disk) so consumers keep draining.
curl http://localhost:9419/metricsThe endpoint exposes the full amqp_* family set — message throughput and depth,
connections, channels, consumers, queues and exchanges, publish/delivery latency,
back-pressure and parking, WAL/segment durability and recovery, resource alarms, shutdown,
panics, and (when the management surface is enabled) the amqp_management_* families. The
complete reference, with types, labels and meanings, plus ready-to-use alerting queries, is
in docs/METRICS.md.
The management UI's Metrics tab (/metrics) renders the same matrix in the browser
through a same-origin, auth-gated GET /api/metrics, so no separate dashboard is required.
When telemetry is disabled that route answers 501 and the screen shows a truthful notice.
pprof is disabled unless --enable-pprof (or telemetry.pprofenabled: true) is
set. When enabled, heap and goroutine dumps are unauthenticated, so keep
telemetry on loopback or behind a firewall.
# CPU profile (30 seconds)
curl -o cpu.prof http://localhost:9419/debug/pprof/profile?seconds=30
go tool pprof -http=:8080 cpu.prof
# Memory profile
curl -o mem.prof http://localhost:9419/debug/pprof/heap
go tool pprof -http=:8080 mem.prof
# Goroutine profile
curl -o goroutine.prof http://localhost:9419/debug/pprof/goroutine
go tool pprof -http=:8080 goroutine.prof
# Mutex contention
curl -o mutex.prof http://localhost:9419/debug/pprof/mutex
go tool pprof -http=:8080 mutex.profcd src/amqp-go
# Run all tests
go test ./...
# Run with race detector
go test -race ./...
# Run with coverage
go test -cover ./...
# Run benchmarks
go test -bench=. -benchmem -benchtime=5s ./storagecd src/amqp-go
# Build server
go build -o amqp-server ./cmd/amqp-server
# Build with optimizations
go build -ldflags="-s -w" -o amqp-server ./cmd/amqp-server
# Cross-compile for Linux
GOOS=linux GOARCH=amd64 go build -o amqp-server-linux ./cmd/amqp-serversrc/amqp-go/
├── cmd/amqp-server/ # Server entry point
├── config/ # Configuration management
├── protocol/ # AMQP protocol implementation
├── server/ # Server and connection handling
├── storage/ # Storage engine (hot cache, WAL, segments)
├── interfaces/ # Interface definitions
├── broker/ # Message routing and delivery
├── auth/ # Authentication & authorization
├── metrics/ # Prometheus metrics
└── transaction/ # Transaction manager
Compatible with any AMQP 0.9.1 client library:
- Go: github.com/rabbitmq/amqp091-go
- Python: pika,
aio-pika - Node.js: amqplib
- Java: RabbitMQ Java Client, Spring AMQP
- Ruby:
bunny - C#: RabbitMQ .NET Client
- Client Examples — Complete examples for Python, Node.js, and Go
- Management Control Plane — REST API, embedded web UI, auth model, and divergences
- Telemetry & Metrics — Serving telemetry, the full metric reference, and alerting
- Authorization Guide — Permission model and access control
- TLS Configuration — TLS encryption and mutual TLS setup
- Contributing Guidelines — How to contribute
- Security Policy — Security best practices
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
MIT License — see LICENSE for details.
- Report bugs: GitHub Issues
- Security issues: See SECURITY.md