sop

Scalable Objects Persistence


Project maintained by SharedCode Hosted on GitHub Pages — Theme by mattgraham

Scalable Objects Persistence (SOP) Data & Compute Platform

Discussions CI codecov Go Reference Go Report Card

SOP is a comprehensive Data & Compute Platform designed for the modern enterprise and high-performance applications.

At its core, SOP is not just a traditional code library; it is a Distributed Computing Framework that powers Swarm Computing—the efficient, coordinated management of data and compute across clusters and embedded systems. SOP enables applications to effortlessly scale from a single device to a massive, distributed “swarm” of intelligent nodes.

The SOP Ecosystem

Packed inside the library is everything you need to build next-generation distributed systems:

Installation & Distribution

SOP is designed to be accessible regardless of your preferred technology stack. There are two primary ways to get the SOP Platform Suite, which includes both the SOP Code Library and the Platform Tools (Data Manager, Script VDE, AI Copilot).

Option 1: Language Packages

Best for developers who want to integrate SOP directly into their application code. Installing the package for your language automatically includes the Data Manager (sop-httpserver) and CLI tools.

Language Installation Description
Python pip install sop4py Full Python bindings with Data Manager & AI Scripts.
Go go get github.com/sharedcode/sop The core native library for maximum performance.
C# dotnet add package Sop Complete .NET Core integration.
Java Maven/Gradle (Coming Soon) Full JVM support.
Rust cargo add sop (Coming Soon) High-performance Rust bindings.

AI Copilot Configuration

The SOP Data Manager includes an embedded AI Copilot powered by LLMs (like Google Gemini). To use the Copilot features, you must configure your API key.

Setting the API Key

You can provide the API Key via an environment variable or the configuration file. For a detailed guide on using the conversational interface, case sensitivity rules, and query examples, please refer to the AI Copilot User Guide.

Option 1: Environment Variable (Recommended) Set the SOP_LLM_API_KEY variable in your shell or .env file before launching the application.

export SOP_LLM_API_KEY="your-api-key-here"

Option 2: Config File Add the llm_api_key field to your config.json file.

{
  "llm_api_key": "your-api-key-here",
  "port": 8080
}

Note: The Copilot requires an active internet connection to communicate with the LLM provider.

Option 2: Standalone Binary (GitHub Releases)

Best for infrastructure administrators, DevOps, or “Data-First” users who want to set up the management console immediately. You can download the sop-httpserver executable directly from our GitHub Releases Page.


Development Workflows: Code-First vs. Data-First

The SOP Platform empowers you to choose the starting point that fits your style. Both approaches are equally powerful and allow you to manage your databases using the SOP library. It is simply a matter of preference where you begin.

1. Code-First Approach

Start in your IDE.

In this workflow, you use the SOP Code Library to define your data structures and logic programmatically.

  1. Define & Run: You write code to define B-Tree stores, transaction logic, and data types (Go, Python, C#, etc.). When your app runs, SOP creates the necessary structures on disk.
  2. Manage Later: You can then launch the Data Manager to inspect, query, and visualize the data your application has created. This is perfect for developers who prefer to stay in code and treat the database as an embedded component.

2. Data-First Approach

Start in the Visual Tool.

In this workflow, you start with the Data Manager to define your schema and data beforehand.

  1. Visual Design: Use the Data Manager’s Visual Tools to create Databases, define Stores, and optionally populate initial datasets or manage content.
  2. Consume in Code: Your application code simply “opens” these pre-existing stores. This allows you to define the schema and indices (data/schema first) before a single line of business logic is written.

The Complementary Cycle

These workflows are not mutually exclusive—they represent a full lifecycle.

SOP ensures seamless interoperability regardless of where you begin.

SOP Data Manager & AI Suite

SOP allows you to interact with your data using the SOP Data Manager—a web-based console that features a powerful SQL-like query engine and an AI Copilot.

Data Manager Capabilities

Designing for AI: Relations

SOP is not just a storage engine; it is designed to be the “Long Term Memory” for AI Agents. There are two ways to model relationships so that AI Agents can intuitively navigate your data:

  1. Direct Relations (Metadata): Use this for standard One-to-Many relationships (e.g., Order.user_id -> User.id). By registering this relationship in the StoreOptions, the AI understands the detailed schema and can perform high-performance Joins automatically.
    • Pro Tip: This enables Bi-Directional Querying (Parent $\leftrightarrow$ Child) without the need for redundant “Link Stores” or double-indexing. Query “User’s Orders” or “Order’s User” with equal efficiency.
  2. Link Store Pattern (Advanced): Use this for Many-to-Many relationships or complex graph traversals. Create a dedicated Link Store (e.g., User_Orders) to map IDs effectively without modifying the base tables.

This structure allows AI Agents to navigate data using simple “Chain of Thought” reasoning steps (e.g., “First find the User ID, then look up their Orders”) rather than struggling to generate complex SQL Joins. The SOP Data Manager provides first-class support for visualizing and debugging these relationships.

Storage Distribution & Redundancy

SOP separates the storage responsibilities into two distinct layers, each tunable via the configuration:

  1. Registry / System Data (Stores Folders):
    • Configuration: StoresFolders (List of paths).
    • Mechanism: Active/Passive Redundancy.
    • Behavior: You typically provide 2 paths (on different drives). SOP writes to the Active drive. If it fails, the system automatically fails over to the Passive drive to ensure the Registry & the database remains fully operational.
  2. User Data Files (Erasure Coding):
    • Configuration: ErasureConfigs (Map of Keys to EC settings).
    • Mechanism: Sharding & Parity (Striping).
    • Behavior: Large data files (User B-Trees, Blobs) are split into chunks (Shards) and distributed across multiple drives. This provides both Parallel I/O (High IOPS) and Fault Tolerance (e.g., surviving a drive failure via parity reconstruction).
    • Key-Based Routing: You can assign specific stores to specific storage tiers (e.g., “fast-ssd-pool” vs “archive-hdd-pool”) using the configuration keys.

The System Database (SystemDB)

All SOP environments come with a built-in SystemDB. Far from just a log repository, this is the “brain” of the platform that stores:

AI Copilot & Scripts

The Data Manager includes an integrated AI Copilot that supports Natural Language Programming.

To launch the Data Manager:

# Data Manager is included in your language binding installation
sop-httpserver

Articles & Deep Dives

🚀 Getting Started

Download & Installation Guide: The fastest way to get up and running with SOP.

⚡ Performance

SOP is designed for high throughput and low latency. Below are benchmark results running on a 2015 MacBook Pro (Dual-Core Intel Core i5, 8GB RAM) using the built-in benchmark tool (tools/benchmark).

Optimization Guide: Tuning SlotLength

The SlotLength parameter controls the number of items stored in each B-Tree node. Tuning this value can significantly impact performance depending on your dataset size and workload.

Configuration Used:

10,000 Items Benchmark

For smaller datasets, a SlotLength of 2,000 offers the best balance.

SlotLength Insert (ops/sec) Read (ops/sec) Delete (ops/sec)
1,000 107,652 136,754 40,964
2,000 132,901 142,907 50,093
3,000 135,066 137,035 49,754
4,000 123,190 122,228 48,094
5,000 132,670 126,432 47,150

100,000 Items Benchmark

For larger datasets, increasing SlotLength to 4,000 yields higher throughput.

SlotLength Insert (ops/sec) Read (ops/sec) Delete (ops/sec)
1,000 121,139 145,195 48,346
2,000 132,805 136,684 51,817
3,000 137,296 141,764 50,605
4,000 145,417 143,770 51,988
5,000 137,054 144,565 50,309

Recommendation: Start with a SlotLength of 2,000 for general use, and increase to 4,000+ for write-heavy workloads with large datasets.

Pro Tip for Massive Scale: For datasets reaching into the hundreds of billions or trillions of records, you can increase SlotLength up to 20,000. This maximizes node density, allowing a single B-Tree to manage massive amounts of data (calculated at 68% average load):

Hash Mod Value Segment Size Capacity (Key/Value Pairs)
750,000 (Max) ~3 GB 673,200,000,000 (673.2 Billion)

This enables managing petabytes of data with minimal metadata overhead. See Scalability & Limits for the full breakdown.

Why this matters

These benchmarks are running with Full ACID Transaction protection. Unlike simple Key-Value stores that optimize purely for random writes (often sacrificing order or safety), SOP provides a robust foundation for complex data access:

Competitive Landscape

How does SOP compare to other storage engines in the Go ecosystem?

Database Type Typical Batch Write (Ops/Sec) Key Differences
SOP B-Tree ~145,000 ACID, Ordered, SWARM Scalability
BadgerDB LSM Tree ~150,000 - 300,000 Faster writes (LSM), but requires compaction and lacks native B-Tree ordering features.
SQLite B-Tree (C) ~50,000 - 100,000 Slower due to SQL parsing overhead.
BoltDB B-Tree ~10,000 - 50,000 Slower random writes due to copy-on-write page structure.
Go map Hash Map ~10,000,000+ In-memory only. No persistence, no ACID, no ordering.

Note on SOP’s Unique Value Proposition: While raw speed is comparable to top-tier engines, SOP distinguishes itself by combining features that usually don’t exist together:

  • Full ACID Transactions: Guarantees safety where others might trade it for speed.
  • SWARM Technology: Unlike monolithic engines, SOP scales linearly across the network.
  • SQL-Ready Structure: Data is stored ordered, enabling ORDER BY, range scans, and efficient joins without extra indexing overhead.

Interoperability & Data Management

SOP is designed as a Universal Data Platform. Whether you are writing in Go, Python, Java, C#, or Rust, your data should be accessible, manageable, and interoperable.

1. The Universal Approach (JSONDB)

This is the standard approach used by all language bindings (Python, Java, C#, Rust) and is also available to Go developers via the jsondb package.

2. The Native Go Approach (Structs & Comparers)

Go developers often prefer storing native structs for maximum performance and type safety. SOP supports this fully but requires a bridge to be manageable by the generic Data Manager.

Bridging the Gap: From Code-First to Managed (Safe & Zero-Downtime)

SOP supports a powerful hybrid workflow. You can start with a Code-First approach (using custom Go structs and comparers) and later “upgrade” your store to be fully manageable by the Data Manager—without migration or downtime.

This allows DBAs to take a “black box” store generated by application code and turn it into a transparent, queryable dataset for reporting, debugging, and AI analysis.

General Purpose & Strong Typing

SOP B-Trees are general-purpose storage engines. Similar to a Model Store, they can store “any” value type (e.g., interface{} in Go, Object in Java).

See the API Cookbook for details.

SOP Data Manager

SOP now includes a powerful SOP Data Manager that provides full CRUD capabilities for your B-Tree stores. It goes beyond simple viewing, offering a complete GUI for inspecting, searching, and managing your data at scale.

To launch the SOP Data Manager:

# From the root of the repository
go run ./tools/httpserver

Or use the pre-built binaries if available. See tools/httpserver/README.md for more details.

SOP AI Kit

The SOP AI Kit transforms SOP from a storage engine into a complete AI data platform.

See ai/README.md for a deep dive into the AI capabilities.

Table of contents

Swarm Computing & Concurrent Transactions

SOP supports “Swarm Computing” where multiple distributed processes or threads can concurrently modify the same B-Tree without external locks. The library handles ACID transactions, conflict detection, and merging automatically.

Important Requirement for First Commit: To enable seamless concurrent merging on a newly created B-Tree, you must pre-seed the B-Tree with at least one item in a separate, initial transaction.

Cluster reboot procedure

When rebooting an entire cluster running applications that use SOP, follow this order to avoid stale locks and ensure clean recovery:

1) Gracefully stop all apps that use SOP across the cluster. 2) Stop the Redis service(s) used by these SOP apps. 3) Reboot hosts if needed (or proceed directly if not). 4) Start the Redis service(s) first and verify they are healthy. 5) Start the apps that use SOP.

Self-Healing & Reliability

SOP includes a robust background servicer that ensures database integrity even in the face of infrastructure failures like Redis restarts.

Redis Restart Detection & Lock Resurrection

In Clustered mode (using Redis), SOP employs a minimally intrusive “on Redis restart” detector. This mechanism:

Note: This feature is specific to Clustered mode. In Standalone mode, the application performs a similar cleanup sweep immediately upon startup.

Notes:

Introduction

What is SOP?

Scalable Objects Persistence (SOP) is a bare metal storage engine that bakes together a set of storage related features & algorithms in order to provide the most efficient & reliable (ACID attributes of transactions) technique (known) of storage management and rich search. It brings to the application the raw muscle of “raw storage” via direct I/O communications with disk drives, bypassing the overhead of intermediate database layers.

SOP V2 core is written in Go, but provides first-class bindings for Python, Java, C#, and Rust, making it a truly universal storage solution. It can be used for storage management by applications of many types across different hardware architectures & Operating Systems (OS).

Polyglot Support

SOP is designed as a “Write Once, Run Anywhere” architecture. The core engine is compiled into a shared library (libsop.so/.dylib/.dll) which is then consumed by language-specific bindings. This ensures that all languages benefit from the same high-performance, ACID-compliant core.

For a deep dive into our multi-language architecture, see Polyglot Support.

Supported Languages

Scalability & Limits

SOP is architected to handle Petabyte-scale datasets and Trillions of objects.

See the full analysis in Scalability & Limits.

Key Use Cases

SOP is designed to be versatile, powering everything from small embedded tools to massive enterprise clusters.

For detailed architectural patterns, deployment lifecycles, and configuration examples, see Workflows & Scenarios.

1. Standalone App (Embedded DB)

2. Enterprise Cluster App

3. AI Vector Database

4. AI Agent with Local LLM (Ollama)

5. Blob Store (Media & Large Files)

6. AI Model Registry

7. Cassandra Power-Up (Layer 2 Database)

8. Embedded Search Engine

Core Innovations

SOP breaks the mold of traditional database architectures by combining the speed of embedded systems with the scalability of distributed clusters.

1. The Unified Native Core (“Write Once, Run Everywhere”)

Unlike many databases that rely on slow TCP/IP protocols for local drivers, SOP runs inside your application process.

2. Swarm Computing Architecture

SOP is not just a storage engine; it is a coordination framework.

3. Rich Key Structures (Metadata-Carrying Keys)

Standard Key-Value stores treat keys as opaque strings. SOP treats them as First-Class Objects.

4. Hybrid AI Compute & Scripting (Self-Correcting)

SOP introduces a novel paradigm by embedding a Scripting Engine directly into the AI Run-Loop.

5. Granular Durability & RAID

Moving beyond simple replication, SOP brings hardware-level reliability concepts into software.

For a deeper dive into the system’s design and package structure (including the Public vs. Internal split), please see the Architecture Guide.

For configuration options and performance tuning, see the Configuration Guide.

For operational best practices (failover, backups), see the Operational Guide.

For code examples, check out the API Cookbook.

See more details here that describe further, the different qualities & attributes/features of SOP, and why it is a good choice as a storage engine for your applications today: Summary

Before I go, I would like to say, SOP is a green field, totally new. What is being shipped in V2 is just the start of this new product. We are barely scratching the surface of what can be done that will help storage management at super scale. SOP is a super computing enabler. The way its architecture was laid out, independent features and together, they are meant to give us the best/most efficient performance & IO of a group of computers (cluster), network & their storage, that can possibly give us.

High level features/usability articles about SOP

See the entire list & details here: https://github.com/sharedcode/sop/blob/master/README2.md#high-level-features-articles-about-sop

The Database Abstraction

SOP provides a high-level database package that simplifies configuration and management of your storage artifacts.

Quick start

SOP is a NoSQL-like key/value storage engine with built-in indexing and transactions. You only need Go to start (Redis is optional for distributed setups).

1) Plan your environment

2) Prerequisites

3) Install and run Redis (Optional)

4) Add SOP to your Go app

5) Initialize and start coding

6) Deploy

7) Permissions

Tip: Using Python? See “SOP for Python” below.

Lifecycle: failures, failover, reinstate, EC auto-repair

SOP is designed to keep your app online through common storage failures.

See the detailed lifecycle guide (failures, observability, reinstate/fast‑forward, and drive replacement) in README2.md: https://github.com/SharedCode/sop/blob/master/README2.md#lifecycle-failures-failover-reinstate-and-ec-auto-repair

Also see Operational caveats: https://github.com/SharedCode/sop/blob/master/README2.md#operational-caveats

For planned maintenance, see Cluster reboot procedure: Cluster reboot procedure.

Transaction idle maintenance (onIdle) & priority rollback sweeps

Each write or read transaction opportunistically invokes an internal onIdle() path at the start (Begin()). This lightweight pass performs two independent maintenance tasks:

  1. Priority rollback sweeps (Lock Resurrection): Resurrects lost locks for interrupted higher-priority transactions by consulting per‑transaction priority log (.plg) files. This allows transactions to “self-heal” by enabling stale detection and rollback as necessary.
    • Cluster-wide coordination: This task is coordinated across the entire cluster (or all threads in standalone mode). Only one worker “wins” and performs the sweep at any given time, ensuring no redundant processing. This prevents unnecessary “swarm overload” on these onIdle services.
    • Restart fast path: On application start (in embedded mode), SOP triggers a one‑time sweep of all priority logs immediately, ignoring age. This accelerates recovery of any half‑committed writes that were waiting for the periodic window. In Clustered mode, a global coordinator ensures that only one process in the entire cluster pings the Redis ‘notrestarted’ flag and performs the actual lock resurrection service if needed.
    • Periodic path: Absent a restart, one worker periodically processes aged logs. Base interval is 5 minutes. If the previous sweep found work, a shorter 2 minute backoff is used to drain backlog faster. Intervals are governed by two atomically updated globals: lastPriorityOnIdleTime (Unix ms) and priorityLogFound (0/1 flag).
    • Rule: Priority logs older than 5 minutes are considered “abandoned” and are rolled back by this servicer.
    • Concurrency: A mutex plus atomic timestamp prevents overlapping sweeps; only one goroutine performs a rollback batch at a time even under high Begin() concurrency.
    • Rationale: Using onIdle piggybacks maintenance on natural transaction flow without a dedicated background goroutine, simplifying embedding into host applications that manage their own scheduling.
  2. Expired transaction log cleanup: Removes obsolete commit/rollback artifacts (B-Tree node pages and data value pages).
    • Cluster-wide coordination: Like priority sweeps, this task is coordinated cluster-wide. Only one worker wins the right to perform the cleanup for a given interval (regular or accelerated).
    • Intervals:
      • 4 Hours (Default): B-Tree nodes and data pages modified in a transaction are temporary until the commit updates the Registry. Since the Registry is the source of truth for ACID transactions, cleaning up these temporary artifacts can be done at a “luxury of time” pace (4 hours) without affecting data integrity.
      • 5 Minutes (Accelerated): If recent activity suggests potential pending cleanup (e.g., known rollbacks), the interval accelerates to 5 minutes to reclaim space faster.
    • Timing uses an atomic lastOnIdleRunTime.

Thread safety: Earlier versions used unsynchronized globals; these now use atomic loads/stores (sync/atomic) to eliminate race detector warnings when tests force timer rewinds. Tests that manipulate timing (to speed up sweep scenarios) reset the atomic counters instead of writing plain globals.

Operational impact: You generally do not need to call anything explicitly—just ensure transactions continue to flow. If you embed SOP in a service that may become read‑only idle for long stretches but you still want prompt rollback of higher‑priority interruptions, periodically issue a lightweight read transaction to trigger onIdle.

Testing notes: Unit tests rewind lastPriorityOnIdleTime and priorityLogFound (atomically) to force immediate sweep execution; this pattern is acceptable only in test code. Production code should never reset these values manually.

Prerequisites

Running Integration Tests

You can run the SOP’s integration tests from “infs” package using the following docker commands: NOTE: you need docker desktop running in your host machine for this to work. Go to the sop root folder, e.g. cd ~/sop, where sop is the folder where you cloned from github.

  1. Build the docker image: docker build -t mydi .
  2. Run the docker image in a container: docker run mydi
    • Where “mydi” is the name of the docker image, you can use another name of your choice.

The docker image will be built with alpine (linux) and Redis server in it. Copy the SOP source codes to it. Setup target data folder and environment variable that tells the unit tests of the data folder path. On docker run, the shell script ensures that the Redis server is up & running then run the (“infs” package’s integration) test files.

You can pattern how the test sets the (datapath) env’t variable so you can run the same integration tests in your host machine, if needed, and yes, you need Redis running locally for this to work. See https://github.com/SharedCode/sop/blob/master/Dockerfile and https://github.com/SharedCode/sop/blob/master/docker-entrypoint.sh for more details.

If you’re using VS Code, there are ready-made tasks:

Testing (unit, integration, stress)

Run tests locally without Docker using build tags:

VS Code tasks provided:

CI note: GitHub Actions runs unit tests on pushes/PRs; a nightly/manual job runs the stress suite with -tags=stress.

Usability

See details here: https://github.com/sharedcode/sop/blob/master/README2.md#usability

SOP API Discussions

See details here: https://github.com/sharedcode/sop/blob/master/README2.md#simple-usage

SOP for Python (sop4py)

See details here: https://github.com/sharedcode/sop/tree/master/jsondb/python#readme Check out the Python Cookbook for code recipes.

SOP for AI Kit

SOP includes a comprehensive AI toolkit for building local, privacy-first expert systems.

Timeouts and deadlines

SOP commits are governed by two bounds:

The commit ends when the earlier of these two is reached. Internal lock TTLs use maxTime to ensure locks are bounded even if the caller cancels early.

Recommendation: If you want replication/log cleanup to complete under the same budget, set your context deadline to at least maxTime plus a small grace period.

Reliability & Integrity

SOP implements a “Rock Solid” storage strategy ensuring data integrity and consistency across failures.

Checksums (CRC32)

Every data block written to disk is protected by a CRC32 checksum.

Rollbacks (COW & Priority Logs)

SOP uses a robust rollback mechanism to recover from crashes or power failures during a transaction.

Unified Locking (Cross-Platform)

SOP employs a “Redis-assisted, Storage-anchored” locking model that works consistently across operating systems (Linux, Windows, macOS).

Coordination model (OOA) and safety

Coordination model: Redis-assisted, storage-anchored

SOP uses Redis for fast, ephemeral coordination and the filesystem for durable sector claims. Redis locks provide low-latency contention detection; per-sector claim markers on storage enforce exclusive access for CUD operations. This hybrid keeps coordination responsive without coupling correctness to Redis durability.

Why this is safe (despite Redis tail loss/failover)

Operational properties

When Redis is unavailable

Comparison to Paxos-style consensus

TL;DR

SOP builds a fast, decentralized coordination layer using Redis only for ephemeral locks and relies on storage-anchored sector claims for correctness. It scales out naturally and avoids consensus overhead while remaining safe under failover.

Clustered Mode Compatibility

In Clustered Mode, SOP uses Redis to coordinate transactions across multiple nodes. This allows many machines to participate in data management for the same Database/B-Tree files on disk while maintaining ACID guarantees.

Note: The database files generated in Standalone and Clustered modes are fully compatible. You can switch between modes as needed but make sure if switching to Standalone mode, that there is only one process that writes to the database files.

Community & support

Contributing & license