Contributing
How to contribute — development workflow, implementing Redis commands, and PR expectations.
Thanks for your interest in contributing.
Reporting issues
Search existing issues before opening a new one. Include:
- What you expected vs what happened
- Gateway / Redis client versions and OS
- Minimal reproduction (RESP bytes or
redis-clicommands)
Code contributions
- Fork and create a feature branch
- Keep changes focused; match existing Rust style
- Add or update tests under
pg_redis_gw//compat/as appropriate - For new Redis commands, follow Implementing a Redis command
Development
Preferred local runtime is the in-process gateway:
mise install
make postgres-up # embedded RESP gateway (preferred)
make test
make compat # Valkey TCL against :6379 (embedded)
make bench # redis-benchmark vs Valkey baseline
make run # optional standalone gateway
make run starts the optional standalone gateway against the same Postgres.
End-user run instructions live in the docs Quickstart.
Implementing a Redis command
Ship semantics in SQL (redis.*), protocol binding in the gateway. Both the
in-process BGWorker and the standalone binary share redis_gateway_core — fix
behavior there once.
Semantics checklist
- Match Redis/Valkey arity and error text closely (
ERR wrong number of arguments for '…' command). - Command names are case-insensitive; keys/values are binary-safe (
bytea/ bulk strings). - Missing keys: Redis null bulk (
$-1\r\n) where Redis returns null (e.g.GET). - Empty string values are valid (not null). Cover them explicitly.
- Reject unsupported options explicitly rather than silently ignoring them.
- Prefer
redis.*functions/tables for behavior; keep the gateway free of business rules beyond param binding and RESP encoding.
Protocol surfaces (easy to miss)
Do not stop at redis-cli + allowlisted Valkey TCL. Those speak RESP arrays
and miss several real clients — see Commands › Protocol surfaces.
When adding a simple command that humans or benchmarks might send inline, add
at least one raw-bytes test for the inline form. Inline PING (PING\r\n) is
supported.
Test surfaces
| Check | Target | Covers | Does not cover |
|---|---|---|---|
cargo test in pg_redis_gw |
Core + standalone | Unit decode/dispatch; some TCP tests | Full Valkey suite; durability matrix |
make postgres-up + make test |
Embedded gateway + Postgres | Live SET/GET against in-process RESP | Inline-only clients unless tests send raw bytes |
make compat |
Embedded :6379 via Valkey --host/--port |
Allowlisted TCL cases (RESP client) | Spawning valkey-server; inline wire form |
make bench |
Embedded :6379 vs Valkey :6380 |
Throughput; default ping,set,get |
Full semantic correctness |
Manual redis-cli |
Either runtime | Smoke / exploration | Automated CI signal |
Suggested workflow
- Implement
redis.*SQL (migration / extension) and session helpers. - Wire dispatch in
redis_gateway_corewith arity + reply encoding. - Unit-test decode/dispatch (wrong arity, empty value, happy path).
- Integration-test against a live gateway where Postgres is required.
- Enable matching Valkey test names in
compat/allowlist.txt; runmake compat. - If the command appears in default benchmarks, run
make benchor a focusedredis-benchmarkand confirm inline and mbulk forms if applicable. - Update
compat/STATUS.mdand README / docs command surface notes.
PR expectations
- Green
make test(with Postgres up when integration tests need it). - Green
make compatfor any newly allowlisted names. - Note any intentional Redis incompatibilities (unsupported options, singledb).
- Do not treat “compat passed” as proof that inline protocol or benchmark defaults work — call out which surfaces you exercised.
Docs site
This documentation is a Blume site. Content lives in
docs/; config in blume.config.ts. Node and bun are mise-managed:
mise install
bun install
bun run docs:dev # hot-reload preview
bun run docs:build # static site → dist/
Or via Make: make docs-dev / make docs-build.
AI-assisted contributions
If AI tools were used substantially, say so in the PR description (tool + how). You remain responsible for understanding and testing every change.