An independent, community-maintained client library for Valkey on Arduino-ecosystem boards. Valkey's client list has no embedded/microcontroller entry today - this library exists to fill that gap.
Works over any Arduino Client-compatible network transport (WiFiClient,
EthernetClient, WiFiClientSecure, WiFiNINA's WiFiClient, ...), so the same
ValkeyClient class runs on ESP32, ESP8266, RP2040/Pico W, WiFiNINA boards,
AVR+Ethernet, STM32, and Teensy 4.1 - board differences live in your sketch (which
Client subclass you construct), not inside the library.
This project is not affiliated with, endorsed by, or maintained by the Valkey project. See LICENSE.
- Full RESP2 command coverage: strings, hashes, lists, sets, sorted sets,
TTL, cursor-basedSCAN(neverKEYS). - Non-blocking pub/sub:
poll()fromloop()instead of blocking onSUBSCRIBE. - Pipelining: batch commands, then read all replies in one pass.
- Reconnect with configurable exponential backoff.
- Two memory tiers so AVR-class boards aren't asked to pay for what they can't use (see below).
- TLS examples for AWS ElastiCache for Valkey and Google Cloud Memorystore for Valkey.
- Optional vector-search extension (
ValkeySearch) for valkey-search: push an embedding, query nearest neighbors, filter by metadata - useful for edge-AI similarity search (anomaly detection, RAG, semantic lookup) with the heavy lifting done server-side.
#include <WiFi.h>
#include <ValkeyClient.h>
WiFiClient net;
ValkeyClient valkey;
void setup() {
WiFi.begin("ssid", "password");
while (WiFi.status() != WL_CONNECTED) delay(500);
valkey.begin(net, "192.168.1.100", 6379);
valkey.connect();
valkey.set("greeting", "hello from arduino");
Serial.println(valkey.get("greeting"));
}
void loop() {
valkey.ensureConnected(); // reconnects with backoff if the link drops
}See examples/ for a full scenario per board family and feature.
| Board / family | Transport | Tier | TLS | Notes |
|---|---|---|---|---|
| ESP32 (incl. S2/S3/C3) | WiFi.h + WiFiClientSecure |
Full | Yes | BasicSetGet |
| ESP8266 | ESP8266WiFi.h + WiFiClientSecure |
Full | Yes | Same API as ESP32; swap the WiFi header |
| Raspberry Pi Pico W / RP2040 (Arduino-Pico core) | WiFi.h + WiFiClientSecure |
Full | Yes | PicoW_WiFi |
| Nano 33 IoT / Nano RP2040 Connect / MKR WiFi 1010 | WiFiNINA.h |
Full | Yes (WiFiSSLClient) |
Nano33IoT_WiFiNINA |
| Arduino Uno / Nano / Mega (AVR) | Ethernet.h (W5100/W5500 shield) |
Tiny | No (not enough RAM for a TLS session) | EthernetAVR |
| STM32 (STM32duino) | Ethernet or WiFi shield (community-dependent) | Full | Depends on shield | Use the same pattern as EthernetAVR/BasicSetGet with your shield's Client |
| Teensy 4.1 | NativeEthernet.h or WiFi shield |
Full | Depends on transport | Same pattern as EthernetAVR with NativeEthernetClient |
The library never branches on board name internally - it only branches on the
memory tier (VALKEY_TINY_TIER), which is auto-detected from __AVR__ and can be
overridden. STM32/Teensy examples follow the same Client-based pattern as the
boards above; open an issue (or see CONTRIBUTING.md) if your
specific board/shield combination needs a dedicated example.
Set automatically from the target architecture; override with -DVALKEY_TINY_TIER=0|1
(PlatformIO build_flags) if auto-detection picks the wrong one for an unusual board.
Tiny tier (VALKEY_TINY_TIER=1) |
Full tier (VALKEY_TINY_TIER=0) |
|
|---|---|---|
| Auto-selected on | AVR (__AVR__) |
Everything else |
| API style | char* buffers you size yourself |
char* buffers and String convenience overloads |
| Protocol | RESP2 only | RESP2 (parser also handles RESP3 reply types) |
| TLS | Not available (#error if forced on) |
Available (VALKEY_ENABLE_TLS, on by default) |
| Vector search | Not available (#error if forced on) |
Available opt-in (VALKEY_ENABLE_SEARCH=1) |
| Pub/sub | Off by default (VALKEY_ENABLE_PUBSUB=0) |
On by default |
| Measured footprint | 21,014 bytes flash (65%) / 684 bytes RAM (33%) for EthernetAVR on an Uno (32KB flash / 2KB RAM part) | 913,828 bytes flash (69%) / 46,912 bytes RAM (14%) for BasicSetGet on an ESP32 (1.3MB flash / 320KB RAM partition used by arduino-cli's default esp32:esp32:esp32 build) |
Those numbers come from actual arduino-cli compile runs against arduino:avr:uno
and esp32:esp32:esp32 in this repo's CI, not estimates - see
.github/workflows/ci.yml. The ESP32 flash figure is
dominated by the WiFi/TLS stack itself, not this library.
All the size knobs (VALKEY_CMD_TIMEOUT_MS, VALKEY_DEFAULT_SCRATCH_SIZE,
VALKEY_MAX_SUBSCRIPTIONS, ...) live in src/ValkeyConfig.h and
can be overridden with -D build flags before you #include <ValkeyClient.h>.
| Example | Tier | Needs | Board(s) |
|---|---|---|---|
| BasicSetGet | Full | WiFi | ESP32 (any WiFi board) |
| PubSubPolling | Full | WiFi, VALKEY_ENABLE_PUBSUB (default on) |
ESP32 (any WiFi board) |
| Pipelining | Full | WiFi | ESP32 (any WiFi board) |
| EthernetAVR | Tiny | Ethernet shield | Uno/Nano/Mega |
| PicoW_WiFi | Full | WiFi | Raspberry Pi Pico W |
| Nano33IoT_WiFiNINA | Full | WiFiNINA module | Nano 33 IoT / MKR WiFi 1010 |
| TLS_ElastiCache | Full | WiFi, VALKEY_ENABLE_TLS (default on), AWS ElastiCache for Valkey cluster |
ESP32 (any TLS-capable board) |
| TLS_Memorystore | Full | WiFi, VALKEY_ENABLE_TLS, VPN/proxy path into the VPC, GCP Memorystore for Valkey instance |
ESP32 (any TLS-capable board) |
| VectorSearch_EdgeAnomaly | Full | WiFi, VALKEY_ENABLE_SEARCH=1 (opt-in, see the example's header comment), a Valkey server running valkey-search |
ESP32 (any WiFi board) |
See docs/CloudSetup.md for TLS/AUTH/reconnect details specific to managed Valkey endpoints.
Once you call subscribe(), avoid issuing other data commands (SET/GET/...) on
that same ValkeyClient/connection - open a second ValkeyClient (a second TCP
connection) if you need both pub/sub and regular commands at once. This mirrors the
standard advice for Redis/Valkey clients in general, not something specific to this
library.
Anything not wrapped by a typed method is reachable via ValkeyClient::command():
ValkeyArg args[3] = { ValkeyArg("EXPIREAT"), ValkeyArg("mykey"), ValkeyArg("1700000000") };
char scratch[16];
ValkeyReply reply;
valkey.command(reply, args, 3, scratch, sizeof(scratch));# RESP2/RESP3 parser unit tests (no Arduino toolchain needed):
g++ -std=c++14 -o test/native/test_resp.exe src/ValkeyResp.cpp test/native/test_resp.cpp
./test/native/test_resp.exe
# Compile an example against a real board target with arduino-cli:
arduino-cli compile --fqbn esp32:esp32:esp32 --library . examples/BasicSetGet
arduino-cli compile --fqbn arduino:avr:uno --library . examples/EthernetAVRCI runs both on every PR - see .github/workflows/ci.yml.
See CONTRIBUTING.md for the current list of gaps and good-first-issue-sized work.
MIT.