Skip to content

About

Independent client library for Valkey on Arduino-ecosystem boards (ESP32, ESP8266, RP2040/Pico W, WiFiNINA, AVR+Ethernet, STM32, Teensy).

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

valkey-arduino

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.

Features

  • Full RESP2 command coverage: strings, hashes, lists, sets, sorted sets, TTL, cursor-based SCAN (never KEYS).
  • Non-blocking pub/sub: poll() from loop() instead of blocking on SUBSCRIBE.
  • 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.

Quick start

#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 compatibility

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.

Memory tiers

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>.

Feature matrix (which example needs what)

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.

Pub/sub caveat

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.

Raw command escape hatch

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));

Building / testing this library

# 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/EthernetAVR

CI runs both on every PR - see .github/workflows/ci.yml.

Contributing

See CONTRIBUTING.md for the current list of gaps and good-first-issue-sized work.

License

MIT.

About

Independent client library for Valkey on Arduino-ecosystem boards (ESP32, ESP8266, RP2040/Pico W, WiFiNINA, AVR+Ethernet, STM32, Teensy).

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages