Library / SDK
aio-libs/aiocache avatar
aio-libs/aiocache

aiocache is a thin contract layer, and the plugins are where it earns its keep

Asyncio cache manager for redis, memcached and memory

1,435 stars181 forksPythonBSD-3-Clause

At a glance

What is it?
The asyncio cache library holds the same ten-method interface across memory, Redis, memcached and a newer Valkey backend, and the interesting design is not the caching but the separation into backends, serializers and plugins. It also has a release history that stops in 2024 while the repository keeps receiving commits.
Who is it for?
Adopt aiocache if you want one async cache interface across several backends and you will actually use the plugin hooks, because the same ten methods across memory, Redis, memcached and Valkey is what lets you move a cache in tests and keep it in production without touching call sites.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 93 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Ten methods, stated up front, which is the entire contract

The readme opens by saying the library aims for simplicity over specialisation, then lists the minimum interface every cache implements. Installing it is a single package install, with backends added as extras:

bash
pip install aiocache
bash
pip install aiocache[redis,memcached]

Add puts a value only if the key does not exist. Get retrieves by key. Set writes. Multi-get and multi-set handle batches. Exists returns a boolean. Increment adds to the stored value. Delete removes a key and returns the number deleted. Clear empties the store. Raw executes a command on the underlying client. That is ten methods and it is the whole promise. The design decision is that the same set exists on every backend, so a memory cache and a Redis cache are interchangeable from the caller's point of view. Two of the entries carry more weight than the rest and are worth reading carefully. Add is the one you reach for when populating a cache from a source of truth, because it is the operation that will not overwrite something another process wrote first, and a cache built from get-then-set has a race that add does not. Raw is the escape hatch that makes the abstraction honest rather than a wall: you can reach the underlying client when you need a command the interface does not name, and the cost is that the code using it is no longer portable across backends.

Backends, serializers and plugins are the three moving parts

The architecture section names three entities and says they combine during cache operations. Backends decide which store is used. Serializers transform data between your objects and the store, which is what allows arbitrary Python objects to be cached, with four named implementations: string, pickle, JSON and msgpack, and the readme notes you can write your own. Plugins implement a hook system that runs extra behaviour before and after each command. The separation is the design, and the reason it holds up is that each axis is independently replaceable. You can change serializer without touching backend code, add a backend without reimplementing serialization, and attach observability by writing a plugin rather than by wrapping every call site. The readme also points at two flow diagrams in the documentation, one for the overall architecture and one tracing a single set operation through the three stages, and says they are there to help you see what happens. That is the right level of ambition for a caching library: the code is small, and the diagrams carry the explanation. The one consequence to be aware of is that the three-way combination means a single set call can fail in the serializer, in the plugin, or in the backend, and a hook that throws will do so around a cache operation that would otherwise have succeeded.

The decorator is the feature most teams will actually use

Beyond direct calls, the readme shows a cached decorator, and the example is more informative than it first appears. It builds a Redis client, wraps it in a Redis cache with a namespace, then decorates an async function with a key, a pickle serializer, a port and a namespace, and calls the function three times in a row. The second and third calls are served from the cache. The function body sleeps for three seconds, so the difference is measurable. Three details in that example deserve attention. First, the decorator is async-aware, which is the whole reason this library exists rather than a thread-off synchronous cache. Second, the return value is a named tuple, not a plain string, which demonstrates the point of the pickle serializer: you can cache structured Python objects in a store that only holds bytes. Third, the readme notes that the same approach lets you store Python objects in backends like Redis, which is the same point stated as a capability. The context management in the example closes both the client and the cache together in an async with block, so the connection is not left dangling. If you take one idea from this readme it is that the decorator plus a serializer is a cleaner shape than a hand-written get, compute, set with a key you built by hand.

Valkey is in the extras and the compose file, which is the current-generation signal

Look at the packaging and the era becomes clear. The manifest declares install_requires as None, so the base install pulls no client library at all, and everything network-facing sits in extras: a Valkey client library, a memcached client, and msgpack. That is a well-behaved package design, since a memory-cache user should not install a database driver, but it does mean a plain install gives you the in-memory backend and nothing more, and a mistake there shows up as a missing import rather than a failed connection. The Valkey entry is the interesting one. Valkey is the community continuation of Redis, and its presence as a first-class extra, alongside a development compose file that starts a Valkey service on the Redis port and a memcached service on its own port, says this project has tracked that shift. The readme's own installation list, however, still names only the redis, memcached and msgpack extras and does not mention Valkey, which is a small documentation gap between the manifest and the prose. A second compose-based example file for Valkey exists in the examples directory, so the support is real and demonstrable. If you are on Valkey or Redis today, the extras are where you will find it, and the compose file is the fastest way to have both stores locally for development.

The example set shows the library is aimed at real coordination problems

The examples directory is more revealing about the project's maturity than the readme is, because the filenames describe problems rather than features. There is an optimistic locking example, which is a distributed lock built on cache primitives, and a redlock example, which is the well-known distributed lock algorithm, so the library is used as a foundation for coordination rather than only for memoising function results. There is an alternative key builder example, which matters because how you build a cache key from function arguments is where cache correctness usually breaks. There is a custom serializer class and a serializer function, plus a marshmallow-based serializer, which means you can validate and shape your cached data as it goes in rather than storing whatever object the function happened to return. There is a plugin demo for timing and one for hit-miss ratio, which is the observability layer. There is a testing example, and the documentation index has a page for testing. And there are framework examples for Sanic, aiohttp and Tornado. Taken together, these are the questions a caching library gets asked once it is in production: what is my hit rate, is my key safe, can two processes coordinate, and can I assert on cache behaviour in a test.

Release history stops in 2024, commits do not

Here is the maintenance picture, and it needs stating precisely rather than optimistically. The published releases are 0.12.3 from 2024-09-25, 0.12.2 from 2023-08-06 and 0.12.1 from 2023-04-23. The last push to the master branch was on 2026-06-28. Those two facts together mean work is happening on the repository while new versions are not being cut, which is the profile of a project whose users run it from a branch or who are waiting for a batch of accumulated changes to be released. The version is still below 1.0, and the readme does not claim otherwise. For an adopter, the practical consequence is that pip gives you 0.12.3, and anything you read in the repository's recent history is not in your installation unless you install from source. The repository layout suggests active maintenance rather than abandonment: there is a GitHub directory, a pre-commit configuration, separate development and runtime requirement files, a makefile, a changelog configuration that generates releases from commit history, a release notes template, a mypy configuration, a flake8 configuration, a coverage configuration for both the coverage service and the local tool, and a codacy configuration. That is a fully equipped project that is simply not cutting versions at the moment.

Editorial conclusion

Adopt aiocache if you want one async cache interface across several backends and you will actually use the plugin hooks, because the same ten methods across memory, Redis, memcached and Valkey is what lets you move a cache in tests and keep it in production without touching call sites. Do not adopt it expecting an actively released project, because the newest published version is 0.12.3 from 2024-09-25 while the last push was on 2026-06-28, so read the recent commits before you depend on anything newer than that release. Four things to verify. That the backend you want is actually an extra, because the manifest declares install_requires as None and puts the Valkey client, the memcached client and the msgpack library behind extras, so a plain install gives you the in-memory cache and nothing else. That your Python version is inside the declared range of 3.9 and later. That the serializer you choose is safe for the data you store, since the readme's own decorator example uses pickle, which is a decision about what an untrusted reader could do to your process rather than only about format. And how you configure key building, since a namespace on the cache instance and a namespace on the decorator are both shown and the interaction is not documented here. The licence is BSD-3-Clause.

Frequently asked questions

How do I install aiocache with a backend?

The readme lists pip install aiocache for the base install and extras for redis, memcached and msgpack, installable separately or together. The manifest declares no required dependencies at all and puts the Valkey client, the memcached client and msgpack behind extras, so a plain install gives you the in-memory cache only.

What interface does every aiocache backend implement?

The readme lists add, get, set, multi_get, multi_set, exists, increment, delete, clear, and raw, which executes a command on the underlying client. The stated aim of the library is simplicity over specialisation.

How do I cache a Python object rather than a string in aiocache?

Use a serializer. The readme names string, pickle, JSON and msgpack implementations and says you can write custom ones, and its decorator example uses a pickle serializer to cache a named tuple in Redis.

What is the latest release of aiocache?

The published releases list 0.12.3 from 2024-09-25, preceded by 0.12.2 in 2023 and 0.12.1 in 2023. The last push to the master branch was on 2026-06-28, so repository work and published versions have diverged.

Can I use aiocache for distributed locking?

The examples directory includes an optimistic locking example and a redlock example, both built on cache primitives, along with a timing plugin and a hit-miss ratio plugin. The readme links to those examples rather than documenting the pattern itself.

Official sources

  1. aio-libs/aiocache on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aio-libs-aiocache.svg)](https://hysenlabs.com/projects/aio-libs-aiocache)