NAUTILUS / RUST source 3eb18933
Pages

Rust edition: this page follows the live DeepWiki structure but treats the current Rust crates as implementation authority. Non-Rust surfaces are identified at their boundary and are not presented as Rust APIs.

State Persistence and Recovery

Relevant Rust source files

  • crates/infrastructure/src/redis/cache.rs
  • crates/common/src/cache/mod.rs
  • crates/common/src/cache/database.rs
  • crates/infrastructure/src/redis/msgbus.rs
  • crates/infrastructure/src/sql/queries.rs

State persistence and recovery enables a live trading system to survive crashes, restarts, and upgrades by saving critical trading state to durable storage and restoring it on startup. This page documents the mechanisms for persisting orders, positions, accounts, instruments, and other stateful entities, as well as the infrastructure layer for Redis and PostgreSQL.

Overview

The NautilusTrader system maintains critical state in memory within the Cache component during operation. In live trading environments, this state must be persisted to survive process restarts. The system provides two primary persistence mechanisms:

  1. Cache State Persistence: Long-lived entities like orders, positions, accounts, and instruments stored via the CacheDatabaseAdapter interface
  2. Event Store (Authoritative Log): An append-only event store capturing commands, events, and venue reports flowing across the message bus (documented in section 2.11).

The infrastructure layer is implemented primarily in Rust for performance, providing adapters for Redis and PostgreSQL

Cache Database Architecture

Infrastructure Layer (Rust)

The core persistence logic resides in the nautilus-infrastructure crate. It utilizes a multi-connection architecture to prevent I/O blocking of the main trading loop.

Redis Cache Implementation

The RedisCacheDatabase uses two distinct Redis connections with specific roles to ensure high performance and thread safety:

  • READ (self.con): Handles synchronous queries such as keys, read, and load_all
  • WRITE: Managed by a background task (CACHE_WRITE) on the Nautilus runtime. It receives DatabaseCommand objects (Insert, Update, Delete, Flush, Close) via an unbounded tokio::sync::mpsc channel

Nautilus persistence ownership showing cache snapshots through CacheDatabaseAdapter, event-store capture and replay, market-history catalog projection, and non-authoritative Redis message egress.

The infrastructure implementation may use background tasks and separate read/write connections, but the semantic boundary remains CacheDatabaseAdapter. Redis transport behind the message bus is a different lane and must not be treated as the cache or event-store durability authority.

PostgreSQL Cache Implementation

The PostgresCacheDatabase utilizes sqlx and a PgPool to persist state to a relational schema Similar to the Redis implementation, it offloads I/O to a CACHE_PROCESS task using an unbounded MPSC channel for DatabaseQuery variants

Supported Entities and Indexing

The system persists specific collections and maintains secondary indexes to allow fast recovery of specific subsets.

Collection Key Entities Stored Code Reference
instruments InstrumentAny
accounts AccountAny
orders OrderAny
positions Position
snapshots OrderSnapshot, PositionSnapshot
custom CustomData

The DatabaseQueries class in the Redis module provides utility functions for scanning keys and bulk reading data using MGET or batched MGET to avoid exceeding request size limits

MessageBus External Streaming

The infrastructure layer allows the internal MessageBus to bridge to external Redis Streams. This enables external monitoring tools or other trading nodes to subscribe to the event flow.

Background Tasks

The RedisMessageBusDatabase (documented in crates/infrastructure/src/redis/msgbus.rs) spawns specialized tasks on the Rust runtime to manage high-throughput streaming without impacting the latency of the core trading logic. This includes handling the XADD operations for outgoing messages and XREAD for incoming external events.

PostgreSQL Schema and Models

The PostgreSQL implementation uses a structured schema to represent trading entities. Mapping between Rust types and SQL rows is handled via sqlx in crates/infrastructure/src/sql/queries.rs.

  • General Storage: The general table stores raw key-value pairs for miscellaneous data
  • Currencies: Persisted in the currency table with fields for precision and ISO codes
  • Instruments: The instrument table uses an ON CONFLICT (id) DO UPDATE pattern to handle updates to existing instrument definitions
  • Orders and Events: Order state and events are stored in dedicated tables, including indexes for fast lookups by client_order_id or venue_order_id.

The DatabaseQueries::truncate function provides a way to reset the database by calling the truncate_all_tables() SQL function