Skip to main content

A state management system for Python 3.x that unifies your applications business logic, data persistence, and caching into a single, efficient layer.

Project description

Dbzero logo

A state management system for Python 3.x that unifies your application's business logic, data persistence, and caching into a single, efficient layer.

License: LGPL 2.1

"If we had infinite memory in our laptop, we'd have no need for clumsy databases. Instead, we could just use our objects whenever we liked."

— Harry Percival and Bob Gregory, Architecture Patterns with Python

Overview

dbzero lets you code as if you have infinite memory. Inspired by a thought experiment from Architecture Patterns with Python by Harry Percival and Bob Gregory, dbzero handles the complexities of data management in the background while you work with simple Python objects.

dbzero implements the DISTIC memory model:

  • Durable - Data persists across application restarts
  • Infinite - Work with data as if memory constraints don't exist (e.g. create lists, dicts or sets with billions of elements)
  • Shared - Multiple processes can access and share the same data
  • Transactional - Transaction support for data integrity
  • Isolated - Reads performed against a consistent point-in-time snapshot
  • Composable - Plug in multiple prefixes (memory partitions) on demand and access other apps’ data by simply attaching their prefix.

With dbzero, you don’t need separate pieces like a database, ORM, or cache layer. Your app becomes easier to build and it runs faster, because there are no roundtrips to a database, memory is used better, and you can shape your data to fit your problem.

Key Platform Features

dbzero provides the reliability of a traditional database system with modern capabilities and extra features on top.

  • Persistence: Application objects (classes and common structures like list, dict, set, etc.) are automatically persisted (e.g. to a local or network-attached file)
  • Efficient caching: Only the data actually accessed is retrieved and cached. For example, if a list has 1 million elements but only 10 are accessed, only those 10 are loaded.
  • Constrained memory usage: You can define memory limits for the process to control RAM consumption.
  • Serializable consistency: Data changes can be read immediately, maintaining a consistent view.
  • Transactions: Make atomic, exception-safe changes using the with dbzero.atomic(): context manager.
  • Snapshots & Time Travel: Query data as it existed at a specific point in the past. This enables tracking of data changes and simplify auditing.
  • Tags: Tag objects and use tags to filter or retrieve data.
  • Indexing: Define lightweight, imperative indexes that can be dynamically created and updated.
  • Data composability: Combine data from different apps, processes, or servers and access it through a unified interface - i.e. your application’s objects, methods and functions.
  • UUID support: All objects are automatically assigned a universally unique identifier, allowing to always reference them directly.
  • Custom data models - Unlike traditional databases, dbzero allows you to define custom data structures to match your domain's needs.

Requirements

  • Python: 3.9+
  • Operating Systems: Linux, macOS, Windows
  • Storage: Local filesystem or network-attached storage
  • Memory: Varies by workload; active working set should fit in RAM for best performance

Quick Start

Installation

pip install dbzero

Simple Example

The guiding philosophy behind dbzero is invisibility—it stays out of your way as much as possible. In most cases, unless you're using advanced features, you won’t even notice it’s there. No schema definitions, no explicit save calls, no ORM configuration. You just write regular Python code, as you always have. See the complete working example below:

import dbzero as db0

@db0.memo(singleton=True)
class GreeterAppRoot:
    def __init__(self, greeting, persons):
        self.greeting = greeting
        self.persons = persons
        self.counter = 0

    def greet(self):
        print(f"{self.greeting}{''.join(f', {person}' for person in self.persons)}!")
        self.counter += 1

if __name__ == "__main__":
    # Initialize dbzero
    db0.init("./app-data", prefix="main")
    # Initialize the application's root object
    root = GreeterAppRoot("Hello", ["Michael", "Jennifer"])
    root.greet() # Output: Hello, Michael, Jennifer!
    print(f"Greeted {root.counter} times.")

The application state is persisted automatically; the same data will be available the next time the app starts. All objects are automatically managed by dbzero and there's no need for explicit conversions, fetching, or saving — dbzero handles persistence transparently for the entire object graph.

Core Concepts

Memo Classes

Transform any Python class into a persistent, automatically managed object by applying the @db0.memo decorator:

import dbzero as db0

@db0.memo
class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

# Instantiation works just like regular Python
person = Person("Alice", 30)

# Attributes can be changed dynamically
person.age += 1
person.address = "123 Main St"  # Add new attributes on the fly

Collections

dbzero provides persistent versions of Python's built-in collections:

from datetime import date

person = Person("John", 25)

# Assign persistent collections to memo object
person.appointment_dates = {date(2026, 1, 12), date(2026, 1, 13), date(2026, 1, 14)}

person.skills = ["Python", "C++", "Docker"]

person.contact_info = {
    "email": "john@example.com",
    "phone": "+1-555-0100",
    "linkedin": "linkedin.com/in/john"
}

# Use them as usual
date(2026, 1, 13) in person.appointment_dates # True

person.skills.append("Kubernetes") 
print(person.skills) # Output: ['Python', 'C++', 'Docker', 'Kubernetes']

person.contact_info["github"] = "github.com/john"
person.contact_info["email"] # "john@example.com"

All standard operations are supported, and changes are automatically persisted.

Queries and Tags

Find objects using tag-based queries and flexible logic operators:

# Create and tag objects
person = Person("Susan", 31)
db0.tags(person).add("employee", "manager")

person = Person("Michael", 29)
db0.tags(person).add("employee", "developer")

# Find every Person by type
result = db0.find(Person)

# Combine type and tags (AND logic) to find employees
employees = db0.find(Person, "employee")

# OR logic using a list to find managers and developers
staff = db0.find(["manager", "developer"])

# NOT logic using db0.no() to find employees wich aren't managers
non_managers = db0.find("employee", db0.no("manager"))

Snapshots and Time Travel

Create isolated views of your data at any point in time:

person = Person("John", 25)
person.balance = 1500
# Keep the current state 
state = db0.get_state_num()
# Commit changes explicitely to advance the state immediately
db0.commit()

# Change the balance
person.balance -= 300
db0.commit()

print(f"{person.name} balance: {person.balance}") # John balance: 1200
# Open snapshot view with past state number
with db0.snapshot(state) as snap:
    past_person = db0.fetch(db0.uuid(person))
    print(f"{past_person.name} balance: {past_person.balance}") # John balance: 1500

Prefixes (Data Partitioning)

Organize data into independent, isolated partitions:

@db0.memo(singleton=True, prefix="/my-org/my-app/settings")
class AppSettings:
    def __init__(self, theme: str):
        self.theme = theme

@db0.memo(prefix="/my-org/my-app/data")
class Note:
    def __init__(self, content: str):
        self.content = content

settings = AppSettings(theme="dark") # Data goes to "settings.db0"
note = Note("Hello dbzero!")         # Data goes to "data.db0"

Indexes

Index your data for fast range queries and sorting:

from datetime import datetime

@db0.memo()
class Event:
    def __init__(self, event_id: int, occured: datetime):
        self.event_id = event_id
        self.occured = occured

events = [
    Event(100, datetime(2026, 1, 28)),
    Event(101, datetime(2026, 1, 30)),
    Event(102, datetime(2026, 1, 29)),
    Event(103, datetime(2026, 2, 1)),
]

# Create an index
event_index = db0.index()
# Populate with objects
for event in events:
    event_index.add(event.occured, event)

# Query events from January 2026
query = event_index.select(datetime(2026, 1, 1), datetime(2026, 1, 31))
# Sort ascending by date of occurance
query_sorted = event_index.sort(query)
print([event.event_id for event in query_sorted]) # Output: [100, 102, 101]

Scalability

dbzero provides tools to build scalable applications:

  • Data Partitioning - Split data across independent partitions (prefixes) to distribute workload
  • Distributed Transactions - Coordinate transactions across multiple partitions for data consistency
  • Multi-Process Support - Multiple processes can work with shared or separate data simultaneously, enabling horizontal scaling

These features give you the flexibility to design distributed architectures that fit your needs.

Use Cases

Our experience has proven that dbzero fits many real-life use cases, which include:

  • Web Applications - Unified state management for backend services
  • Data Processing Pipelines - Efficient and simple data preparation
  • Event-Driven Systems - Capturing data changes and time travel for auditing
  • AI Applications - Simplified state management for AI agents and workflows
  • Something Else? - Built something cool with dbzero? We'd love to see what you're working on—share it on our Discord server!

Why dbzero?

The short answer is illustrated by diagram below:

Traditional Stack

Application Code
    ↓
ORM Layer
    ↓
Caching Layer
    ↓
Database Layer
    ↓
Storage

With dbzero

Application Code + dbzero
    ↓
Storage

By eliminating intermediate layers, dbzero reduces complexity, improves performance, and accelerates development—all while providing the reliability and features you expect from a regular database system.

Documentation

Check our docs to learn more: docs.dbzero.io

There you can find:

  • Guides
  • Tutorials
  • Performance tips
  • API Reference

License

This project is licensed under the GNU Lesser General Public License v2.1 (LGPL 2.1). See LICENSE for the full text.

  • This library can be linked with proprietary software.
  • Modifications to the library itself must be released under LGPL 2.1.
  • Redistributions must preserve copyright and license notices and provide source.

For attribution details, see NOTICE.

Support

Feedback

We'd love to hear how you're using dbzero and what features you'd like to see! Your input helps us make dbzero better for everyone.

The best way to share your thoughts is through our Discord server: Join us on Discord

Commercial Support

Need help building large-scale solutions with dbzero?

We offer:

  • Tools for data export and manipulation
  • Tools for hosting rich UI applications on top of your existing dbzero codebase
  • System integrations
  • Expert consulting and architectural reviews
  • Performance tuning

Contact us at: info@dbzero.io


Start coding as if you have infinite memory. Let dbzero handle the rest.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dbzero-0.3.4.tar.gz (16.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

dbzero-0.3.4-cp314-cp314-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.14macOS 15.0+ ARM64

dbzero-0.3.4-cp313-cp313-win_amd64.whl (27.0 MB view details)

Uploaded CPython 3.13Windows x86-64

dbzero-0.3.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.7 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

dbzero-0.3.4-cp313-cp313-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

dbzero-0.3.4-cp312-cp312-win_amd64.whl (27.0 MB view details)

Uploaded CPython 3.12Windows x86-64

dbzero-0.3.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.7 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

dbzero-0.3.4-cp312-cp312-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.12macOS 15.0+ ARM64

dbzero-0.3.4-cp311-cp311-win_amd64.whl (27.0 MB view details)

Uploaded CPython 3.11Windows x86-64

dbzero-0.3.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.7 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

dbzero-0.3.4-cp311-cp311-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

dbzero-0.3.4-cp310-cp310-win_amd64.whl (27.0 MB view details)

Uploaded CPython 3.10Windows x86-64

dbzero-0.3.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.7 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

dbzero-0.3.4-cp310-cp310-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.10macOS 15.0+ ARM64

dbzero-0.3.4-cp39-cp39-win_amd64.whl (27.0 MB view details)

Uploaded CPython 3.9Windows x86-64

dbzero-0.3.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.7 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

dbzero-0.3.4-cp39-cp39-macosx_15_0_arm64.whl (7.6 MB view details)

Uploaded CPython 3.9macOS 15.0+ ARM64

File details

Details for the file dbzero-0.3.4.tar.gz.

File metadata

  • Download URL: dbzero-0.3.4.tar.gz
  • Upload date:
  • Size: 16.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4.tar.gz
Algorithm Hash digest
SHA256 c8c3bf5de340292bf2f663ed5b0dad5668ec0ebcf6fc99fa2b6bacc26242dd01
MD5 d6e19cd50f2e4b92023328090349aa33
BLAKE2b-256 8781a9526af29e2533ec249f7d1a6f2af894ad0d3b1b17cdf6b5d0bba6fe5f95

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp314-cp314-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp314-cp314-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 27105eadfe65913ebc234dc2e3eaf34e2151c59b2072598536cf198d588f053d
MD5 fa59d4a22d657b1c09a69e72b9ba0774
BLAKE2b-256 ccdee66697a710d12dfa35e9711b44a2227165daa6e5fd6435532ce6c7be8035

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: dbzero-0.3.4-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 27.0 MB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 54b8bbd9a80c609b8501d2a4282474f49a7c27742e536b39558e1d1316dcba11
MD5 5db3b5bc3eed477d1c47dab25e7e146b
BLAKE2b-256 8fdc9a8e27940ad7c530e0e0e5d919811d3ba4766c7a30dbac03104df28d1eef

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e4caaea27b5d42a9931244fa00263ec19e09bc0139f9f392ece5af1bfcb36e8d
MD5 b26664de5be37b0caa664242a4785d30
BLAKE2b-256 119d39820ea73529bab8f4f4882da1e54dddbde9055d33456214aa19c486c1fb

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp313-cp313-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 288ecdebaf175b385e926851fc4bceec5e9712a538d67551e8f0b5ea02e7d9d5
MD5 5e1309652f506a06816307eda5a951f3
BLAKE2b-256 ad055b30c04611655260a8929c3cbc43eb0c4d7cd808241fa110fd9602875e9d

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: dbzero-0.3.4-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 27.0 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 da485b81f3fde7390e6225293ce571659e617854e0332f04ee00fc4530eeece4
MD5 2e08bee3cdf24ab76ab96dd71fd80c7a
BLAKE2b-256 ff168d3c3b5b2a3d16277306a39677ceec0ad5089123eb6cf4bf55678182ed41

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8b064cdfe8dae57bd869fc69f77ecdf4fcd1a7b8eeeaecbda59c84f1787cb889
MD5 a8516b2012a071af9d64a995e33ee229
BLAKE2b-256 00666ef687fc3a96bc04f8ae87ff5710ee59ca1ca3c199dbc1fe07dc298476e2

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp312-cp312-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp312-cp312-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 53c173ff7a88e0a9469893298893b14494334de69c510304858f5f37d2e50e40
MD5 2f9a205724f9918f609b78657abcb2b9
BLAKE2b-256 2e9585fbf5a2035bac143a2ff5964b3bece1e3b92b97a07a2b248053ef26a6d9

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: dbzero-0.3.4-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 27.0 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 d7276580740de4041cf41f9a976d75960552855bb3a720332858bf2d93848f93
MD5 2508b6f09edddd3c58a4cdf2860887c9
BLAKE2b-256 200894c423baeef82d301d5a123337aacb72fcbcd724a73889eae11cd03359b8

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6b9026d1c09987e8d080e3482e32eb576e074ab4e81d0129cff505176ffe51db
MD5 22a1ace44d6ef7643187bb6d73680a83
BLAKE2b-256 bb52f2fd9fd6b64298a8aea4740f973ae5e7a736fdc56ba51b7919bfb124fe98

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp311-cp311-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 b99c40f7dd4384c56677096f4c5d93550b09504b698de423a406e7a571ab0af8
MD5 ea3706979188a0118b5348563ee5876f
BLAKE2b-256 6b7667f24d2b0a922ccdc37fdb7e577617a4136333a291ea812f3c39373b9c7b

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: dbzero-0.3.4-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 27.0 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 a759bc40bcfea503bcbded1215fdd9e49e1d7c96f15ab899ff5917c031e76814
MD5 8a6370e44df62f4547601d0955ec40e6
BLAKE2b-256 71eaed7c3e95c4ce4f98b8e96bec91fdeeadf03e249621f468d4b4ef7530415d

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 66f2345bf6ba3c84cf46e710dece0d9b3ae5bb5c3de79fe3a3f1d925a4889649
MD5 3c282a8622c46ac37ab21d1966cfdac8
BLAKE2b-256 a0263e4fba55d05056a8e27426acd1cda65016406b73a7327dbf0c8507758f94

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp310-cp310-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp310-cp310-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 a6b44d5da2882d6acc9b1e76cdedea9c1c5c35f56219d901700f6f1c9d28c694
MD5 bfc19e4d1c60f3a7eefa1e8073fc8e2b
BLAKE2b-256 eb4d69b1d347bfab9bd9eb131958a308b84115173a1f9ec2fa942336334d6e7c

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: dbzero-0.3.4-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 27.0 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for dbzero-0.3.4-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 48bf94e977c5192e6226cf6a0b154a8120ed601b9f4670c06550c3c10243cb71
MD5 5422b4a4146bea462f6936394c0d13ea
BLAKE2b-256 e9644db6ce505f198592017ee130674e812151c351dcddee19f13ce4fa2e8a06

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 63e7f838279c1914a57ae1c151fc2b1eeeb1dc870a691f888ab41d22f56ad71e
MD5 a1531e1420b23f1fc5ee1b90ff029c8b
BLAKE2b-256 0face0b74bb0b5b49cb7d288f61fadd72728d0a8df5c4ad3c4b1d2c2ff78a4b3

See more details on using hashes here.

File details

Details for the file dbzero-0.3.4-cp39-cp39-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for dbzero-0.3.4-cp39-cp39-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 ee41f59e06e303ec8173e76ead56d6caecff29455c32a4df469114928ef68aaf
MD5 173acff2041c2455ec090281a85d1c63
BLAKE2b-256 29b700e81f2e6a3df4b9bf1a6ca9829ad35ce7904595d0c5336e52759e7bb195

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page