garnet Documentation

Garnet is a remote cache-store from Microsoft Research that offers strong performance (throughput and latency), scalability, storage, recovery, cluster...

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy garnet on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name garnet -p 6379:6379 --restart always ghcr.io/microsoft/garnet
Configured Services & Ports
โš™๏ธ garnet
image: ghcr.io/microsoft/garnet
๐Ÿ”Œ Ports: 6379:6379
docker-compose.yml
yaml (docker-compose.yml)
services:
  garnet:
    image: 'ghcr.io/microsoft/garnet'
    ulimits:
      memlock: -1
    ports:
      - "6379:6379"
    # To avoid docker NAT, consider `host` mode.
    # https://docs.docker.com/compose/compose-file/compose-file-v3/#network_mode
    # network_mode: "host"
    volumes:
      - garnetdata:/data
volumes:
  garnetdata:

1. Project Overview & Quickstart (microsoft/garnet)

File: README.md

Garnet






Garnet is a remote cache-store that offers several unique benefits:

  • Garnet adopts the popular RESP wire protocol as a starting point, which makes it possible to use Garnet from unmodified Redis clients available in
    most programming languages of today, such as StackExchange.Redis in C#.
  • Garnet offers much better throughput and scalability with many client connections and small batches, relative to comparable open-source cache-stores, leading to cost savings for large apps and services.
  • Garnet demonstrates extremely low client latencies (often less than 300 microseconds at the 99.9th percentile) using commodity cloud (Azure) VMs with Accelerated Networking enabled, which is critical to real-world scenarios.
  • Based on the latest .NET technology, Garnet is cross-platform, extensible, and modern. It is designed to be easy to develop for and evolve, without sacrificing performance in the
    common case. We leveraged the rich library ecosystem of .NET for API breadth, with open opportunities for optimization. Thanks to our careful use of .NET, Garnet achieves
    state-of-the-art performance on both Linux and Windows.

This repo contains the code to build and run Garnet. For more information and documentation, check out our website at https://microsoft.github.io/garnet.

Looking for a fully managed service? Azure Cosmos DB Garnet Cache provides Garnet as a fully managed, enterprise-ready caching solution with built-in high availability, performance guarantees and zero infrastructure management.

What's New ๐ŸŽ‰

  • ๐Ÿš€ Vector Sets (Preview) โ€” Approximate nearest-neighbor search backed by the DiskANN algorithm and Garnet's Tsavorite storage engine. In our initial results, Garnet leads on QPS, p99 latency, and recall.
  • ๐Ÿ” Range Index (Preview) โ€” Secondary range and equality indexes over Garnet keys, powered by Bf-Tree.
  • ๐Ÿ“„ The Garnet paper will appear at VLDB 2026! B. Chandramouli, V. Zois, T. Hart, T. Zaccai, L. M. Maas, Y. Rajasekaran, D. Gehring. Garnet: A Next-Generation Cache-Store for Accelerating Applications and Services. PVLDB 2026. [PDF]

Feature Summary

Garnet implements a wide range of APIs including raw strings (e.g., gets, sets, and key expiration), analytical (e.g., HyperLogLog and Bitmap), and object (e.g., sorted sets and lists)
operations. It can handle multi-key transactions in the form of client-side RESP transactions and our own server-side stored procedures and modules in C#. It allows users to define custom
operations on both raw strings and custom object types, all in the convenience and safety of C#, leading to a lower bar for developing custom extensions. Garnet also supports Lua scripts.

Garnet uses a fast and pluggable network layer, enabling future extensions such as leveraging kernel-bypass stacks. It supports secure transport layer security (TLS) communications using
the robust SslStream library of .NET, as well as basic access control. Garnetโ€™s storage layer, called Tsavorite,
is built for high performance and includes strong database features such as thread scalability, tiered storage support (memory, SSD, and cloud storage), fast non-blocking checkpointing,
recovery, operation logging for durability, multi-key transaction support, and better memory management and reuse. Finally, Garnet supports a cluster mode of operation with support for
sharding, replication, and dynamic key migration.

Performance Preview

We illustrate a few key results on our website comparing Garnet to leading open-source cache-stores.

Design Highlights

Garnetโ€™s design re-thinks the entire cache-store stack โ€“ from receiving packets on the network, to parsing and processing database operations, to performing storage interactions. We build on
top of years of our prior research. Below is Garnetโ€™s overall architecture.

Garnetโ€™s network layer is based on a shared memory design, with TLS processing and storage interactions performed on the network IO completion thread, avoiding thread switching overheads in the common
case. This approach allows CPU cache coherence to bring the data to the processing logic, instead of traditional shuffle-based network designs, which require data movement to the appropriate shard on
the server.

Garnetโ€™s storage design consists of two Tsavorite key-value stores whose fates are bound by a unified operation log. The first store, called the โ€œmain store,โ€ is optimized for raw string operations and manages memory carefully to
avoid garbage collection. The second, and optional, โ€œobject storeโ€ is optimized for complex objects and custom data types, including popular types such as Sorted Set, Set, Hash, List, and Geo. Data types in the object store
leverage the .NET library ecosystem for their current implementations. They are stored on the heap in memory (which makes updates very efficient) and in a serialized form on disk. In the future, we plan to investigate using a
unified index and log to ease maintenance.

A distinguishing feature of Garnetโ€™s design is its narrow-waist Tsavorite storage API, which is used to implement the large, rich, and extensible RESP API surface on top. This API consists of read, upsert, delete, and atomic
read-modify-write operations, implemented with asynchronous callbacks for Garnet to interject logic at various points during each operation. Our storage API model allows us to cleanly separate Garnetโ€™s parsing and query
processing concerns from storage details such as concurrency, storage tiering, and checkpointing. Garnet uses two-phase locking for multi-key transactions.

Cluster Mode

In addition to single-node execution, Garnet has a fully-featured cluster mode, which allows users to create and manage a sharded and replicated deployment. Garnet also supports an efficient and dynamic key migration scheme
to rebalance shards. Users can use standard Redis cluster commands to create and manage Garnet clusters, and nodes perform gossip to share and evolve cluster state. Garnet's cluster mode design is currently passive: this means
that it does not implement leader election, and simply responds to cluster commands issued by a user-provided control plane; see this link for details.

Next Steps

Head over to our documentation site, or jump directly to the getting started or
releases section.

License

This project is licensed under the MIT License, see the LICENSE file.

Privacy

Privacy information can be found at https://privacy.microsoft.com/en-us/.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct.
For more information see the Code of Conduct FAQ or
contact [email protected] with any additional questions or comments.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow
Microsoft's Trademark & Brand Guidelines.
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
Any use of third-party trademarks or logos are subject to those third-party's policies.

Redis is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd. Any use by Microsoft is for referential
purposes only and does not indicate any sponsorship, endorsement or affiliation between Redis and Microsoft.


File: benchmark/README.md

Benchmarks

This directory contains projects for benchmarking Garnet.

Resp.benchmark

Garnet project contains a Benchmark tool for running RESP benchmarking using different clients, different workloads and different strategies for measuring throughput, performance and latency.

See Resp.benchmark/README.md for a copy-paste cookbook covering the offline (throughput) and online (latency-histogram) modes, plus a recipe for running an end-to-end disk-bound benchmark that lines up with the lower-layer KV.benchmark and Device.benchmark recipes.

You can also visit the website documentation here: The Resp.benchmark tool.

BDN.benchmark

The BDN.benchmark command-line tool allows contributors to run precise and reproducible micro-benchmarks by utilizing the BenchmarkDotNet.

Usage

You can list all available benchmarks using --list flat or --list tree, e.g.

text
dotnet run -c Release -f net8.0 --list flat

To run specific benchmarks, you can use --filter. For example, to run all RESP-protocol write benchmarks using the default configuration, which will run the benchmarks using all .NET target runtimes (with the dynamic PGO disabled):

text
dotnet run -c Release -f net8.0 --filter *RespIntegerWriteBenchmarks*

See more command-line options at https://benchmarkdotnet.org/articles/guides/console-args.html

Writing microbenchmarks

Please see the Microbenchmark Design Guidelines for the best practices when writing microbenchmarks using BenchmarkDotNet.

Device.benchmark

A low-overhead random-read IOPS benchmark for Tsavorite's IDevice implementations
(Native libaio / io_uring on Linux, IOCP on Windows; FileStream; RandomAccess; and
the in-RAM LocalMemory device). It is a Tsavorite-engine benchmark and lives
alongside KV/YCSB under libs/storage/Tsavorite/cs/benchmark/. See
Device.benchmark/README.md
for usage and recipes to saturate ~750K IOPS on a Dell P5600-class NVMe or measure
the ~78M ops/sec LocalMemory ceiling.

The three layers โ€” Device (raw IDevice), KV
(Tsavorite engine), and Resp (full RESP server) โ€” stack as Resp โ‰ค KV โ‰ค Device โ‰ค fio,
and each has a matching disk and LocalMemory (memory) scenario for comparison.

Privacy

Microsoft Privacy Statement


File: charts/garnet/README.md

garnet

A Helm chart for Microsoft Garnet

Homepage: https://github.com/microsoft/garnet

Source Code

Usage

Helm must be installed to use the charts. Please refer to
Helm's documentation to get started.

To install the Garnet chart (using an OCI-based registry):

sh
helm upgrade --install garnet oci://ghcr.io/microsoft/helm-charts/garnet

To uninstall the chart:

sh
helm delete garnet

Values

Key Type Default Description
affinity object {} Affinity
config.existingSecret string "" Garnet secret (if you want to use an existing secret). This secret must contains a key called 'garnet.conf'.
config.garnetConf string "" The garnet.conf data content.
containers.args list [] Containers args
containers.livenessProbe object {} Containers livenessProbe
containers.port int 6379 Containers port
containers.readinessProbe object {} Containers livenessProbe
dnsConfig object {} DNS config
dnsPolicy string "ClusterFirst" DNS policy
extraVolumeMounts list [] Extra Volume Mounts
extraVolumes list [] Extra Volumes
fullnameOverride string "" Chart full name override
image.pullPolicy string "IfNotPresent" Image pull policy
image.registry string "ghcr.io" Image registry
image.repository string "microsoft/garnet" Image repository
image.tag string "" Overrides the image tag whose default is the chart appVersion.
imagePullSecrets list [] Image pull secrets
initContainers list [] Init containers
nameOverride string "" Chart name override
nodeSelector object {} Node Selector labels
persistence.enabled bool false persistence enabled
persistence.storageDir string "" The Storage directory for tiered records (hybrid log), if storage tiering (--storage-tier) is enabled. Default: "/data"
podAnnotations object {} Pod annotations
podSecurityContext object {} Pod Security Context
resources object {} Resources
securityContext object {} Security Context
service.annotations object {} Service annotations
service.port int 6379 Service port
service.type string "ClusterIP" Service type
serviceAccount.annotations object {} Annotations to add to the service account
serviceAccount.create bool false Specifies whether a service account should be created
serviceAccount.name string "" The name of the service account to use. If not set and create is true, a name is generated using the fullname template
serviceAccount.token bool false Creates the token object
statefulSet.annotations object {} StatefulSet annotations
statefulSet.replicas int 1 StatefulSet replicas
statefulSet.revisionHistoryLimit int 1 StatefulSet revisionHistoryLimit
statefulSet.updateStrategy.type string "RollingUpdate" StatefulSet updateStrategy type
tolerations list [] Tolerations
volumeClaimTemplates.requestsStorage string "1Gi" Volume Claim Templates Requests Storage
volumeClaimTemplates.storageClassName string "local-storage" Volume Claim Templates Storage Class Name

Autogenerated from chart metadata using helm-docs v1.14.2


File: libs/storage/Tsavorite/cc/README.md

Tsavorite Native Device (C++)

We use CMake to build the native device (optionally used on Linux and Windows).
To build, create one or more build directories and use CMake to set up build
scripts for your target OS. Once CMake has generated the build scripts, it will
try to update them, as needed, during ordinary build.

The resulting library is named native_device.dll on Windows and
libnative_device.so on Linux. Both expose the same C ABI; selection of the
underlying IO backend at runtime is done via the C# IoBackend enum, which
Garnet surfaces as --device-io-backend default|libaio|uring.

Note on the prebuilt artifacts. Prebuilt binaries are checked in under
libs/storage/Tsavorite/cs/src/core/Device/runtimes/<rid>/native/ (one folder per
runtime identifier โ€” linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64,
win-x64, and win-arm64) and copied into bin/ at build time. The C#
NativeStorageDevice loader resolves the folder for the current OS/architecture/libc at
load time. If you change C++ sources you must rebuild and re-check in the matching
prebuilt for every platform you changed. The easiest way to regenerate all of them
canonically is the Build Native Device GitHub workflow
(.github/workflows/native-build.yml): dispatch it on your branch with
update_repo = true and it builds each RID and commits the refreshed binaries onto your
branch. See "Updating the shipped prebuilt binaries" below for details and the manual path.

Runtime dependencies (end users)

We ship two Linux prebuilt native libraries next to each other under
runtimes/linux-x64/native/:

  1. libnative_device.so โ€” built with USE_URING=ON, links libaio
    AND liburing. Exposes both IoBackend.Libaio and IoBackend.Uring
    to the C# caller. Loaded when liburing2 is present on the host.
  2. libnative_device_libaio.so โ€” built with USE_URING=OFF, links
    libaio only. Exposes IoBackend.Libaio. Loaded automatically as a
    fallback when liburing2 is not present on the host so the libaio
    backend (the default) still works without any extra setup.

The C# NativeStorageDevice loader tries libnative_device.so first and
silently falls back to libnative_device_libaio.so if the dynamic linker
reports liburing.so.2: cannot open shared object file. The libaio backend
always works out of the box on any Linux distribution that ships libaio
(essentially all of them).

If a caller explicitly selects IoBackend.Uring on a host without
liburing installed, construction throws a TsavoriteException with the
install command for the user's distribution (apt-get install -y liburing2, dnf install -y liburing, apk add liburing). We never
silently downgrade Uring to Libaio.

sh
# libaio (always required โ€” both shipped binaries link it):
#   Debian / Ubuntu 24.04+: libaio1t64
#   Older Debian / Ubuntu:  libaio1
#   Fedora / RHEL / AzureLinux: libaio
#   Alpine: libaio

# liburing (optional โ€” only needed if you want IoBackend.Uring):
#   Debian / Ubuntu: liburing2
#   Fedora / RHEL / AzureLinux: liburing
#   Alpine: liburing

Windows users do not need any of this; the shipped native_device.dll
uses the Windows ThreadPool API and has no native runtime dependencies
beyond the standard CRT.

Building on Windows

The native device builds with MSVC (Visual Studio 2022, Visual Studio 2026
Insiders, or the standalone Build Tools). You need the Desktop development
with C++
workload installed, plus the Spectre-mitigated CRT libraries
(see prerequisites below).

1. Confirm CMake and Visual Studio are installed

CMake 3.21 or newer is required for the Visual Studio 2022 generator;
3.31 or newer is recommended for Visual Studio 2026 Insiders. Check with:

powershell
cmake --version

To list what Visual Studio installs CMake will discover:

powershell
& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -prerelease -products * -format json |
    Select-String -Pattern '"displayName"|"installationPath"|"installationVersion"'

Pre-release / Insiders editions only show up with the -prerelease flag โ€”
omitting it is the most common reason for a missing-VS error.

2. Install the Spectre-mitigated CRT libraries

Our CMakeLists.txt builds with /Qspectre /guard:cf /sdl (source-level
Spectre v1 mitigation, Control Flow Guard, and Security Development
Lifecycle checks) and the project requires the matching Spectre-mitigated
CRT runtime libraries at link time. They are an optional component in
the VS Installer:

  1. Open the Visual Studio Installer, click Modify on your VS
    2022 or VS 2026 Insiders install.
  2. Switch to the Individual components tab.
  3. Search for Spectre and check the entry that matches your toolset and
    architecture โ€” e.g. MSVC v143 - VS 2022 C++ x64/x86 Spectre-mitigated
    libs (Latest)
    for VS 2022, or the equivalent v144 / v18 entry
    for VS 2026 Insiders.
  4. Click Modify to install (about 200 MB).

Skipping this step will surface as error MSB8040: Spectre-mitigated libraries are required for this project during cmake --build.

3. Pick a generator

Visual Studio CMake generator string
Visual Studio 2026 Insiders "Visual Studio 18 2026"
Visual Studio 2022 (any edition) "Visual Studio 17 2022"
Build Tools 2022 (no IDE) "Visual Studio 17 2022"
Anything else / unsure Ninja (see below)

If cmake --help does not list your generator, your CMake is too old โ€”
upgrade with winget install Kitware.CMake or download a fresh build from
https://cmake.org/download/.

4. Configure and build

Create a build directory under Tsavorite\cc and configure from there:

powershell
cd libs\storage\Tsavorite\cc
mkdir build
cd build

# Pick the line matching your VS edition:
cmake -G "Visual Studio 18 2026" -A x64 ..    # VS 2026 Insiders (current dev tooling)
cmake -G "Visual Studio 17 2022" -A x64 ..    # VS 2022 (any edition) / Build Tools 2022

cmake --build . --config Release

If configure/link fails to find the toolset or the Spectre-mitigated CRT (e.g.
the generator defaults to a newer toolset than the one whose Spectre libs you
installed โ€” common with VS 2026 Insiders), select the MSVC toolset explicitly
with -T. For example, to use the v143 (VS 2022) toolset:

powershell
cmake -G "Visual Studio 18 2026" -A x64 -T v143 ..   # force the v143 toolset

Use the toolset that matches your installed Spectre-mitigated libs (v143 for
VS 2022, v144/v145 for VS 2026 Insiders).

That produces build\src\Release\native_device.dll (and a matching
native_device.pdb). The CMake configuration also creates a Tsavorite.sln
that you can open in Visual Studio for interactive development; both Debug
and Release profiles are added for x64.

USE_URING is a no-op on Windows; the Windows DLL only exposes the
Default (IOCP) backend.

Generator-agnostic fallback (Ninja)

If you have Build Tools without an IDE, an unsupported / preview VS
version, or you just want a faster command-line build, use Ninja. Open
the x64 Native Tools Command Prompt for VS <version> (the start-menu
shortcut that ships with every VS install) and run:

cmd
cd libs\storage\Tsavorite\cc
mkdir build && cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

Ninja picks up cl.exe from the developer prompt automatically, so it
bypasses the generator-string lookup entirely.

Building on Linux

1. Install the required packages

The native device links against aio (libaio) and, when USE_URING=ON
(the default), uring (liburing). Plus the usual build toolchain.

On Debian / Ubuntu (including Ubuntu 24.04 with the t64 ABI transition):

sh
sudo apt-get install build-essential cmake libaio-dev liburing-dev uuid-dev

On Fedora / RHEL / Azure Linux:

sh
sudo dnf install gcc-c++ cmake libaio-devel liburing-devel libuuid-devel

On Alpine (musl):

sh
sudo apk add build-base cmake linux-headers libaio-dev liburing-dev util-linux-dev

Alpine is supported: a musl prebuilt is shipped under
runtimes/linux-musl-x64/native/ (its binaries link libaio.so.1/liburing.so.2
and the musl C runtime, unlike the glibc linux-x64 build which needs
libaio.so.1t64). The C# loader selects it automatically on musl hosts.

CMake 3.21 or newer is required.

2. Configure and build

CMake on Linux generates scripts for either Debug or Release per build
directory โ€” run CMake twice, in two different directories, if you want
both.

sh
cd libs/storage/Tsavorite/cc
mkdir -p build/Release && cd build/Release
cmake -DCMAKE_BUILD_TYPE=Release ../..
make -j"$(nproc)"

Or, for a Debug build:

sh
mkdir -p build/Debug && cd build/Debug
cmake -DCMAKE_BUILD_TYPE=Debug ../..
make -j"$(nproc)"

The output is build/<config>/libnative_device.so. The build links libaio
(always) and, when USE_URING=ON (the default), also links liburing โ€” the
resulting binary exposes the Libaio and (if USE_URING=ON) Uring
backends to the C# caller via the IoBackend enum (--device-io-backend libaio|uring). The Linux default is libaio; Uring must be explicitly
selected.

The repo ships two prebuilt Linux binaries. To support hosts that
may or may not have liburing2 installed, the repo ships both:
libnative_device.so (built with USE_URING=ON, links libaio +
liburing) and libnative_device_libaio.so (built with USE_URING=OFF,
links libaio only). The C# loader tries the uring-enabled binary first
and falls back to the libaio-only binary on liburing.so.2: cannot open.
If you rebuild the prebuilts, rebuild both โ€” once with -DUSE_URING=ON,
once with -DUSE_URING=OFF โ€” and copy each over the corresponding file
in runtimes/linux-x64/native/ (see the "Updating the shipped prebuilt
binaries" section below for the rebuild script).

Ubuntu 24.04 (t64 ABI) note. Since the t64 transition the system
ships libaio.so.1t64 instead of libaio.so.1. CMake's -laio will
find /usr/lib/x86_64-linux-gnu/libaio.so which is a symlink to the
.1t64.0.2 file, so the build itself succeeds โ€” but the resulting
binary records libaio.so.1t64 in its NEEDED list. To restore the
portable name, run patchelf --replace-needed libaio.so.1t64 libaio.so.1 libnative_device.so after the build (see the prebuilt
update section below).

Disabling io_uring at build time (optional)

If you want a build that does not have a runtime dependency on liburing
at all (e.g., for a constrained image where liburing is unavailable),
pass -DUSE_URING=OFF to cmake:

sh
cmake -DCMAKE_BUILD_TYPE=Release -DUSE_URING=OFF ../..

The resulting binary links only libaio. Requesting the Uring backend at
runtime against this build is rejected at construction with the same clear
exception (pointing the user at the install command for liburing2). This is
the build flavour that ships as libnative_device_libaio.so.

Updating the shipped prebuilt binaries

The C# project copies the prebuilt native libraries from
libs/storage/Tsavorite/cs/src/core/Device/runtimes/<rid>/native/ into the
output directory at build time. After rebuilding, copy the new artifact over
the corresponding file in that directory and check it in.

Preferred: regenerate all platforms via CI. The Build Native Device
workflow (.github/workflows/native-build.yml) builds every RID
(linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64, win-x64,
win-arm64) and verifies the exported C ABI. It runs automatically in
build-only mode on any change under libs/storage/Tsavorite/cc/** (docs like
this README are excluded) to confirm every platform still compiles.

When you are working on a PR branch that changes the native device and want the
refreshed binaries in your branch, dispatch it on your branch with
update_repo = true:

sh
gh workflow run native-build.yml --ref <your-branch> -f update_repo=true

It rebuilds every RID from your branch's C++ and commits the updated
runtimes/<rid>/native/ binaries straight onto <your-branch>, so the open
PR updates in place โ€” the C# CI (ci.yml) then tests against your new native
code. (Dispatching on main/dev opens a review PR instead of pushing
directly.) Note: a push made with the default GITHUB_TOKEN does not start new
workflow runs, so ci.yml picks up the new binaries on your next push or a
manual re-run unless a maintainer has configured a NATIVE_BINARIES_PAT secret.
This is the canonical way to refresh the binaries.

Linux, by hand. The build-native.sh helper next to this README builds
both flavours (libnative_device.so with USE_URING=ON and
libnative_device_libaio.so with USE_URING=OFF), normalizes the libaio
SONAME, and verifies the exported entrypoints. Point it at the RID folder you
want to refresh (install the build dependencies listed at the top of the script
first):

sh
# from libs/storage/Tsavorite/cc:
./build-native.sh ../cs/src/core/Device/runtimes/linux-x64/native

For musl (linux-musl-x64) run the same script inside an Alpine container so it
links against musl and the plain libaio.so.1 SONAME:

sh
docker run --rm -v "$PWD/../../../../..:/w" -w /w alpine:3.20 sh -c \
  'apk add --no-cache build-base cmake linux-headers libaio-dev liburing-dev util-linux-dev && \
   libs/storage/Tsavorite/cc/build-native.sh libs/storage/Tsavorite/cs/src/core/Device/runtimes/linux-musl-x64/native'

Linux (linux-x64), the individual cmake steps:

sh
# from libs/storage/Tsavorite/cc, after a Release build with USE_URING=ON:
cp build/Release/libnative_device.so \
   ../cs/src/core/Device/runtimes/linux-x64/native/libnative_device.so

The shipped Linux binary records libaio.so.1 and liburing.so.2 as its
NEEDED entries. On Ubuntu 24.04 and later (post-t64 ABI transition) the linker
records libaio.so.1t64 instead; the Dockerfiles in this repo install
libaio1t64 and create a libaio.so.1 -> libaio.so.1t64 compat symlink, but
we keep the checked-in NEEDED name portable by patching it:

sh
patchelf --replace-needed libaio.so.1t64 libaio.so.1 \
   ../cs/src/core/Device/runtimes/linux-x64/native/libnative_device.so

Windows (win-x64):

A VS generator places the binary under src\Release\ (or src\Debug\); a
Ninja build places it under src\ directly. Adjust the source path
accordingly:

cmd
:: from libs\storage\Tsavorite\cc, after a Release build with the VS generator:
copy /Y build\src\Release\native_device.dll ^
   ..\cs\src\core\Device\runtimes\win-x64\native\
copy /Y build\src\Release\native_device.pdb ^
   ..\cs\src\core\Device\runtimes\win-x64\native\

To verify that the new entrypoints are present in the rebuilt binary:

sh
# Linux
nm -D --defined-only libnative_device.so | grep NativeDevice_
cmd
:: Windows
dumpbin /exports native_device.dll | findstr NativeDevice_

You should see NativeDevice_CreateWithBackend and
NativeDevice_AvailableBackends in addition to the legacy entrypoints.

Other options

You can try other generators (compilers) supported by CMake. The main CMake
build script is the CMakeLists.txt located in the root directory (Tsavorite/cc).


File: libs/storage/Tsavorite/cs/README.md

Tsavorite

Tsavorite is a fork of the FASTER C# library (https://github.com/microsoft/FASTER) that we have significantly extended and optimized to support Garnet's requirements.

Privacy

Microsoft Privacy Statement


File: libs/storage/Tsavorite/README.md



Introduction

Managing large application state easily, resiliently, and with high performance is one of the hardest
problems in the cloud today. The FASTER project offers two artifacts to help tackle this problem.

  • FASTER Log is a high-performance concurrent persistent recoverable log, iterator, and random
    reader library in C#. It supports very frequent commit operations at low latency, and can quickly saturate
    disk bandwidth. It supports both sync and async interfaces, handles disk errors, and supports checksums.

  • FASTER KV is a concurrent key-value store + cache (available in C# and C++) that is designed for point
    lookups and heavy updates. FASTER supports data larger than memory, by leveraging fast external
    storage (local or cloud). It also supports consistent recovery using a fast non-blocking checkpointing technique
    that lets applications trade-off performance for commit latency.

Both FASTER KV and FASTER Log offer orders-of-magnitude higher performance than comparable solutions, on standard
workloads. Start learning about FASTER, its unique capabilities, and how to get started at our official website:

aka.ms/FASTER

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct.
For more information see the Code of Conduct FAQ or
contact [email protected] with any additional questions or comments.

Privacy

Microsoft Privacy Statement


File: main/GarnetServer/README.md

garnet-server

garnet-server is a .NET global tool that provides the Microsoft.Garnet RESP server.

The garnet-server by itself will create a Garnet server using the default port; for full options, see garnet-server --help.


File: website/docs/welcome/about-us.md


id: about-us sidebar_label: About Us title: About Us

About Us

Check out our blog post here for more details on our history and evolution.

Contributors

Core Team:

  • Badrish Chandramouli, Vasileios Zois, Ted Hart, Kevin Montrose, Tiago Napoli.
  • Email: garnetteam AT microsoft.com

Project Partners:

  • Hamdaan Khalid, Alan Yang, Pradeep Yadav, Alex Dubinkov, Venugopal Latchupatulla.
  • Matt Tremblay, Kevin Bowersox, Simon Nattress, Ankith Kandala, Justine Cocchi, Kavya Kotacherry, Sergiy Kuryata.
  • Open-source contributors, including @PaulusParssinen, @Vijay-Nirmal, @babykart, @nightroman, @prvyk, @hexonal, and @unsafePtr.

File: website/docs/welcome/compatibility.md


id: compatibility sidebar_label: Compatibility title: API Compatibility

Garnet is a cache-store with a new thread-scalable system architecture. The network, processing, and storage (memory
and disk/cloud) layers of Garnet are all designed from the ground up. We chose the RESP API as a matter of
convenience given its broad adoption in the community. Garnet is not intended to be a 100% perfect drop-in
replacement for Redis, rather it should be regarded as a close-enough starting point for you to ensure compatibility
for features that matter to you. Garnet does work unmodified with many Redis clients (we have in particular tested
Garnet with StackExchange.Redis very well), so getting started is very easy.

A list of API calls supported today by Garnet is maintained here. Below we highlight
specific non-API-related choices that may not be compatible. This list is not exhaustive, rather it is meant as a broad
guideline on what differences you can expect when using Garnet.

  1. Garnet being multi-threaded, MSET is not atomic. For an atomic version of MSET, you would need to express
    it as a transaction (stored procedure). This is easily fixable, similar to MSETNX here, let us know in issues if you
    prefer the atomic semantics of MSET by default.
  2. Garnet does not support Redis modules. Instead, it has its own C# based extensibility mechanisms
    that are optimized for very high performance, thread scalability, safety, and ease of use.
  3. Garnet has full-fledged and efficient support for Lua scripting. You can enable Lua with the --lua switch.
  4. Garnet respects the FIFO ordering of request-responses. However, when used with larger-than-memory data, and with
    the scatter-gather version of IO (the EnableScatterGatherGet [--sg-get] option, enabled by default) for increased disk performance,
    even though results are still returned in FIFO order, the read operations may be executed out-of-order to earlier
    write operations in the same input operation sequence.
  5. When Garnet is used with the append-only-file (AOF) turned on, by default the server does not wait for commit before
    returning success to the user. This can be adjusted using the WaitForCommit [--aof-commit-wait] option, while the frequency of
    commit can be tuned using the CommitFrequencyMs [--aof-commit-freq] option.
  6. You can disable support for data-structure objects if your workload only consists of raw string operations, using the option DisableObjects [--no-obj]. The
    storage tier is disabled by default, and you can enable it using EnableStorageTier [--storage-tier]. You can disable the pub-sub feature
    using the option DisablePubSub [--no-pubsub].

File: website/docs/welcome/faq.md


id: faq sidebar_label: FAQ title: Frequently Asked Questions (FAQ)

How can I contribute to this documentation website?

This website is built using Docusaurus 2, a modern static website generator. The sources are
on GitHub, linked here. The markdown files for the documentation
are in the docs folder. You can contribute by making a
normal GitHub pull request.

Do Garnet checkpoints and other storage artifacts work across release versions?

As of 2.1.0, the storage format of Garnet has stabilized and we plan to ensure backwards compatibility for any future format changes. Specifically, a newer 2.x version of Garnet will interoperate with checkpoint and AOF logs generated by any earlier 2.x version, as far back as 2.1.0. Note that an older version of Garnet is not able to read checkpoint or AOF logs generated by a newer version. This compatibility excludes features marked as preview.

Is Garnet associated with Redis?

No. Like KeyDB and Dragonfly, we were inspired by the popularity and elegance of the RESP API and decided to adopt this
common standard. Redis is a registered trademark of Redis Ltd. Any rights therein are reserved to Redis Ltd. Any use by
Microsoft is for referential purposes only and does not indicate any sponsorship, endorsement or affiliation between
Redis and Microsoft.

2. Official Technical Reference & Guides (microsoft/microsoft.github.io)

[microsoft.github.io](https://microsoft.github.io)

Many open source projects released by Microsoft products, services and teams also have
deployments powered by GitHub Pages on this domain.

To discover Microsoft-released open source projects, learn about Microsoft's open source
approach and other information, check us out online at opensource.microsoft.com.

If we can help answer questions about the open source program at Microsoft, you can
contact opensource at microsoft com - although we are not able to provide support
for projects through this mechanism.

Microsoft GitHub resources

Microsoft open source resources

Resources for Microsoft employees

How to identify an official Microsoft organization on GitHub

  • Official Microsoft GitHub orgs have a professional avatar and include a web address at Microsoft.com or an associated official domain
  • Official Microsoft orgs are Verified on GitHub - look for the domain verification indicator on GitHub