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.6.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.6-cp314-cp314-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.14macOS 15.0+ ARM64

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

Uploaded CPython 3.13Windows x86-64

dbzero-0.3.6-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.8 MB view details)

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

dbzero-0.3.6-cp313-cp313-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.13macOS 15.0+ ARM64

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

Uploaded CPython 3.12Windows x86-64

dbzero-0.3.6-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.8 MB view details)

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

dbzero-0.3.6-cp312-cp312-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.12macOS 15.0+ ARM64

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

Uploaded CPython 3.11Windows x86-64

dbzero-0.3.6-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.8 MB view details)

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

dbzero-0.3.6-cp311-cp311-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

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

Uploaded CPython 3.10Windows x86-64

dbzero-0.3.6-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.8 MB view details)

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

dbzero-0.3.6-cp310-cp310-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.10macOS 15.0+ ARM64

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

Uploaded CPython 3.9Windows x86-64

dbzero-0.3.6-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (9.8 MB view details)

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

dbzero-0.3.6-cp39-cp39-macosx_15_0_arm64.whl (7.8 MB view details)

Uploaded CPython 3.9macOS 15.0+ ARM64

File details

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

File metadata

  • Download URL: dbzero-0.3.6.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.6.tar.gz
Algorithm Hash digest
SHA256 bf1d491cb576e248c35e74cc72d5db2ba42cd167b03e82f9a31dbe83eee6575e
MD5 c1f6438b4e228f2ed0e60520def786e7
BLAKE2b-256 00546a08cd766cb1f23807c2007638fab3ce3fcd4414ea12e781448ee92c538b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp314-cp314-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 07a8fb0788f8400a3b0c5337052674b1ff1e3c49c7f27c5c4c2c3515c85ce921
MD5 e69aa8ba743418ac81f744beb27b18f2
BLAKE2b-256 9715352c36e8d29cb0949f8a5305263fb839851d6c8535980e3d71442060749b

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dbzero-0.3.6-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.6-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 2e1802998c0d38ecfa09b96aa1c20f6dacc090074945497e44202afb00b90074
MD5 b88e71857d82f78a0e2483987db36f01
BLAKE2b-256 f1d8612cb2fdf605d27599e7f7311ac81de3a6a7dde8f68c0a4b02a3582d2a0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d5cc23e4cb716991ca6e345d2f836d0dff84533ec6b48727743b8a6e68436ceb
MD5 c322f3d771e7986ae6709efb6787917e
BLAKE2b-256 a5e002aabe8e7ee231252905385e2ddf9145db740610862f251f1c4c717c5c0c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp313-cp313-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 47d7554287674a025724c032ad11f44b57bf5dc529f436198da7fd1406aa666f
MD5 7af871ca5c2430a6a412a10114a058c8
BLAKE2b-256 a799d4ee4f6234b6d04a95ef7ff5b868a75cbe3a3db2a2b971ffd020be9af975

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dbzero-0.3.6-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.6-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 4d52518d944b189f6951e95bcf1c585a0aaf1c1ec0407e695c6902dc705e6d40
MD5 9797b305525a00e68741a3dbde3e36f7
BLAKE2b-256 bfe7d8913d2888975deff30f34248f04918984aef235aa07204325b17ea71e30

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1f2edee02276341840147b262dcbbd45ae9198b802056690eb65f253745d0b71
MD5 dd01740866b0c2559939a3b18811a9b7
BLAKE2b-256 049a6be12a72aca18beb10e7949bf6a7b24fb2565beeb95767f3fda207217941

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp312-cp312-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 4032694357b4f05ae5d6fa9a88336d6573ff7cfd2cbfa7291ab86f854120ffad
MD5 ddc9f19b6b273904ad365639413f33db
BLAKE2b-256 cd0af79daf549c99fd0d6108262ebfbe39a50499e37086c1101a1ba2a97ce773

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dbzero-0.3.6-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.6-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 7d1ccacebf7c14d3d127cb16da04027373ae3b0a309140cb3cbab64553d9ccf2
MD5 5d140e4d31c0fb1511bf74672efa687a
BLAKE2b-256 b6e20bcdaf17ab9935695ef0b422e385e08e69d37be543d2979dcb078835e76c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 889af75c341fd159157991773ce8e0fe16ef51243de2486a593a49d761ca30aa
MD5 d67e16763e74c1ce26336af12ceb4acc
BLAKE2b-256 1c7d57df5bd4958c990e66b1e1f363b0d06e6cc7396bc4c83118741ede5fcc28

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 1c58cbdf506eb78e767c4de1cf4abf99e85556972ccd318d3c0f20761f7a5212
MD5 bf94017ffc87ada0daadb477fead3f1c
BLAKE2b-256 884ec7f8d0bff9c40a8a37345c6dfec4d2482eec9a440a1d35570e06f826fb2d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dbzero-0.3.6-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.6-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c9e7f2ca31d34a0fa83985ac9ff26548ab3faeb871195bd7248652b5cb428044
MD5 5062db920fcee99eecd98d48165f3268
BLAKE2b-256 4ab4a7930a561441ff2f710e979733fb3957e7c24a50ff295eee03b954e6b5d5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1b583fc195f35d9457cda14843fbee00cf4a7f96cdc7dcc4b3dc00c5d18544d5
MD5 95a3ab5f6a642498d7430046c0655ebe
BLAKE2b-256 12bc8546f643fb0af992e1058d84b5ed8ddd83d74735cf5c1a83d53803532cf5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp310-cp310-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 79c41a2a74c34051cb9d75e658453d396ee52530ae336469bc88b5d2bc2070c9
MD5 024a1306709d247d467ef89d47d4a6f9
BLAKE2b-256 6116b360b377ff8421b11f59cb28aa8c5bd4e29fc1fe6098acfceb7a236c77c9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: dbzero-0.3.6-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.6-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 8b7b67fa16b7889270eecb0228329fa1f13f4377bcd2f5925b08be9272c377cb
MD5 be006895449537276c8976621e8a167b
BLAKE2b-256 aca75b0c12b8928fe100e817f3e7982c7d64c5b684a4856fb663157970eb435b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 850995240c73fd480ebceb8a4bcf6367bdf76e1a457a3626791e2a3fda1b580e
MD5 1973f9c30f0b0485abcfd7c1f867a16e
BLAKE2b-256 5616314e414a40e76a32417038d9a2387d433ce9cd4df020a021d0975cf46911

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for dbzero-0.3.6-cp39-cp39-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 c830db18e4f9f8455a4e62a3c873324fe9cfe8a7e418cae01ea74f87f7440399
MD5 90b86e180813430a2217422607d9c298
BLAKE2b-256 5401a04c9813f4b9f8b1673bf7a40bd3ee47beb4ad62c78d832ba760a650ad63

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