Skip to content

valkey commands

if you need to use valkey operations, you can access the client as follows:

>>> from django.core.cache import cache
>>> cache.set("key", "value1", nx=True)
True
>>> cache.set("key", "value2", nx=True)
False
>>> cache.get("key")
"value1"

the list of supported commands is very long, if needed you can check the methods at django_valkey.base.BackendCommands.

Infinite timeout

django-valkey comes with infinite timeouts supported out of the box. And it behaves in the same way as django backend contract specifies:

  • timeout=0 expires the value immediately.
  • timeout=None infinite timeout.
cache.set("key", "value", timeout=None)

Get and Set in bulk

django-valkey has two different kind of method for bulk get/set: atomic and non-atomic.

atomic operations are done with mget() and mset()

>>> from django.core.cache import cache
>>> cache.mset({"a": 1, "b": 2})
>>> cache.mget(["a", "b"])
{"a": 1, "b": 2}

the non-atomic operations are done with get_many() and set_many():

>>> from django.core.cache import cache
>>> cache.set_many({"a": 1, "b": 2})
>>> cache.get_many(["a", "b"])
{"a": 1, "b": 2}

Note: django-redis users should note that in django redis get_many() is an atomic operation, but set_many() is non-atomic, but in django-valkey they are both non-atomic.

Scan and Delete in bulk

when you need to search for keys that have similar patterns, or delete them, you can use the helper methods that come with django-valkey:

>>> from django.core.cache import cache
>>> cache.keys("foo_*")
["foo_1", "foo_2"]

if you are looking for a very large amount of data, this is not suitable; instead use iter_keys. this will return a generator that you can iterate over more efficiently.

>>> from django.core.cache import cache
>>> cache.iter_keys("foo_*")
<generator object algo at 0x7ff432
>>> next(cache.iter_keys("foo_*))
'foo_1'
>>> foos = cache.iter_keys("foo_*")
>>> for i in foos:
...     print(i)
'foo_1'
'foo_2'

to delete keys, you should use delete_pattern which has the same glob pattern syntax as keys and returns the number of deleted keys.

>>> from django.core.cache import cache
>>> cache.delete_pattern("foo_*")
2

To achieve the best performance while deleting many keys, you should set DJANGO_VALKEY_SCAN_ITERSIZE to a relatively high number (e.g., 100_000) by default in Django settings or pass it directly to the delete_pattern.

>>> from django.core.cache import cache
>>> cache.delete_pattern("foo_*", itersize=100_000)

Get ttl (time-to-live) from key

with valkey you can access to ttl of any sorted key, to do so, django-valky exposes the ttl method.

the ttl method returns:

  • 0 if key does not exist (or already expired).
  • None for keys that exist but does not have expiration.
  • the ttl value for any volatile key (any key that has expiration).
>>> from django.core.cache import cache
>>> cache.set("foo", "value", timeout=25)
>>> cache.ttl("foo")
25
>>> cache.ttl("not-exists")
0

you can also access the ttl of any sorted key in milliseconds, use the pttl method to do so:

>>> from django.core.cache import cache
>>> cache.set("foo", "value", timeout=25)
>>> cache.pttl("foo")
25000
>>> cache.pttl("non-existent")
0

Expire & Persist

in addition to the ttl and pttl methods, you can use the persist method so the key would have infinite timeout:

>>> cache.set("foo", "bar", timeout=22)
>>> cache.ttl("foo")
22
>>> cache.persist("foo")
True
>>> cache.ttl("foo")
None

you can also use expire to set a new timeout on the key:

>>> cache.set("foo", "bar", timeout=22)
>>> cache.expire("foo", timeout=5)
True
>>> cache.ttl("foo")
5

The pexpire method can be used to set new timeout in millisecond precision:

>>> cache.set("foo", "bar", timeout=22)
>>> cache.pexpire("foo", timeout=5505)
True
>>> cache.pttl("foo")
5505

The expire_at method can be used to make the key expire at a specific moment in time:

>>> cache.set("foo", "bar", timeout=22)
>>> cache.expire_at("foo", datetime.now() + timedelta(hours=1))
True
>>> cache.ttl("foo")
3600

The pexpire_at method can be used to make the key expire at a specific moment in time, with milliseconds precision:

>>> cache.set("foo", "bar", timeout=22)
>>> cache.pexpire_at("foo", datetime.now() + timedelta(milliseconds=900, hours=1))
True
>>> cache.ttl("foo")
3601
>>> cache.pttl("foo")
3600900

Locks

django-valkey also supports locks. valkey has distributed named locks which are identical to threading.Lock so you can useit as replacement.

with cache.get_lock("somekey"):
    do_something())

this command is also available as cache.lock() but will be removed in the future.

Access Raw client

if the commands provided by django-valkey backend is not enough, or you want to use them in a different way, you can access the underlying client as follows:

>>> from django-valkey import get_valkey_connection
>>> con = get_valkey_connection("default")
>>> con
<valkey.client.Valkey object at 0x2dc4510>

Warning: not all clients support this feature: ShardClient will raise an exception if tried to be used like this.