pickleDB Logo PyPI Downloads GitHub Stars

pickleDB

pickleDB is a lightweight, JSON-backed key-value store for Python, designed for simple APIs, fast in-memory operations, and a unified sync/async interface. BSD 3-Clause License · © Harrison Erd.

Quick Start

Install

pip install pickledb

Sync Example

from pickledb import PickleDB

# Bind to a JSON file; no I/O yet
db = PickleDB("data.json").load()  # load from disk into memory (if file exists)

db.set("username", "alice")
db.set("theme", {"color": "blue", "font": "sans-serif"})

print(db.get("username"))  # → "alice"

db.save()  # atomically write in-memory DB back to data.json

Async Example

import asyncio
from pickledb import PickleDB

async def main():
    db = await PickleDB("data.json").load()

    await db.set("score", 42)
    value = await db.get("score")
    print(value)  # → 42

    await db.save()

asyncio.run(main())
Explicit I/O: the constructor PickleDB("data.json") never touches disk. load() and save() are explicit (or handled by context managers).

Design & Behavior

Context Managers

Synchronous

from pickledb import PickleDB

with PickleDB("data.json") as db:
    # On enter: db.load()
    db.set("foo", "bar")
    db.set("hello", "world")
    # On successful exit: db.save()

Asynchronous

import asyncio
from pickledb import PickleDB

async def main():
    async with PickleDB("data.json") as db:
        # On enter: await db.load()
        await db.set("foo", "bar")
        await db.set("hello", "world")
        # On successful exit: await db.save()

asyncio.run(main())

Core Methods

These are the only methods you really need to know. Every method works the same in sync and async code; just add await when you’re in an async function. All of these methods are part of the PickleDB class.

Method Sync usage Async usage Description
load() db.load() await db.load() Load (or reload) the JSON file into memory. Returns the same PickleDB instance for chaining.
save() db.save() await db.save() Atomically save the in-memory database back to disk.
set(key, value) db.set(k, v) await db.set(k, v) Store a value under key. Keys are coerced to str; values must be JSON-serializable.
get(key, default=None) db.get(k, d) await db.get(k, d) Retrieve the stored value, or default if the key doesn’t exist.
remove(key) db.remove(k) await db.remove(k) Delete a key. Returns True if it existed and was removed.
all() db.all() await db.all() Return a list of all keys in the in-memory database.
purge() db.purge() await db.purge() Clear the in-memory database. Returns True.

pickleDB is intentionally method-based only. Dict-style access like db["key"] or db["key"] = value is not supported.

Common Patterns

Storing Complex Data

# Store a dictionary
db.set("user", {"name": "Alice", "age": 30})

# Update it
user = db.get("user")
user["age"] += 1
db.set("user", user)

print(db.get("user"))
# {'name': 'Alice', 'age': 31}

Lists / Simple Queues

db.set("tasks", ["write", "test", "deploy"])

tasks = db.get("tasks", [])
tasks.append("celebrate")
db.set("tasks", tasks)

print(db.get("tasks"))
# ['write', 'test', 'deploy', 'celebrate']

Namespace Keys

db.set("user:1", {"name": "Alice"})
db.set("user:2", {"name": "Bob"})

def keys_with_prefix(db, prefix):
    return [k for k in db.all() if k.startswith(prefix)]

print(keys_with_prefix(db, "user:"))
# ['user:1', 'user:2']

Basic TTL Pattern (App-Level)

import time

def set_with_ttl(db, key, value, ttl_seconds):
    db.set(key, {
        "value": value,
        "expires_at": time.time() + ttl_seconds,
    })

def get_if_fresh(db, key):
    data = db.get(key)
    if not data:
        return None
    if time.time() < data.get("expires_at", 0):
        return data["value"]
    db.remove(key)
    return None

set_with_ttl(db, "session", "active", ttl_seconds=5)
time.sleep(3)
print(get_if_fresh(db, "session"))  # 'active'
time.sleep(3)
print(get_if_fresh(db, "session"))  # None

Performance Snapshot

Example timings loading, reading, and saving large JSON payloads using async mode on a Dell XPS 9350, Ubuntu 24.04:

Entries Load (into memory) Bulk read Save (to disk)
1M 0.68 s 0.64 s 0.03 s
10M 7.48 s 7.27 s 0.22 s
50M 43.36 s 36.53 s 1.09 s

Full benchmark script: available here.

When Not to Use pickleDB

In those cases, consider Redis or MongoDB instead.

Issues, questions, or ideas? Open an issue on GitHub.

Fork me on GitHub