Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Database Schema

xrat uses relational databases (SQLite or PostgreSQL) with the same schema across both backends.

Schema Overview

TableVersionDescription
subscriptions0001Import source tracking
configs0001, 0003, 0015Stored proxy nodes
connection_tests0001, 0002, 0008, 0009, 0010Test results per config
connection_test_runs0007Groups test results into runs
runtime_sessions0001, 0004, 0005, 0006, 0012, 0013, 0014Proxy process lifecycle
cf_scan_results0011IP scan results

Tables

subscriptions

Tracks import sources (URLs, files, raw text).

CREATE TABLE subscriptions (
    id INTEGER PRIMARY KEY,
    source_url TEXT,
    source_kind TEXT NOT NULL CHECK(source_kind IN ('url', 'file', 'raw_text')),
    name TEXT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
source_urlTEXTOriginal URL, file path, or β€œraw_text”
source_kindTEXTurl, file, or raw_text
nameTEXTOptional subscription name
created_atTIMESTAMPFirst import timestamp
updated_atTIMESTAMPLatest import timestamp

configs

Stores normalized proxy nodes.

CREATE TABLE configs (
    id INTEGER PRIMARY KEY,
    subscription_id INTEGER REFERENCES subscriptions(id),
    dedup_key TEXT NOT NULL UNIQUE,
    protocol TEXT NOT NULL,
    address TEXT NOT NULL,
    port INTEGER NOT NULL,
    username TEXT,
    uuid TEXT,
    password TEXT,
    method TEXT,
    network TEXT NOT NULL,
    tls TEXT,
    sni TEXT,
    host TEXT,
    path TEXT,
    name TEXT,
    raw_config TEXT NOT NULL,
    is_active INTEGER NOT NULL DEFAULT 0,
    is_enabled INTEGER NOT NULL DEFAULT 1,
    is_deleted INTEGER NOT NULL DEFAULT 0,
    imported_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
subscription_idINTEGERFK to subscriptions
dedup_keyTEXTUnique deduplication key
protocolTEXTvless, vmess, ss, trojan, http, socks5, hy2
addressTEXTServer address
portINTEGERServer port
usernameTEXTUsername (HTTP/SOCKS5)
uuidTEXTUUID (VLESS/VMess)
passwordTEXTPassword (Trojan/SS)
methodTEXTEncryption method (Shadowsocks)
networkTEXTtcp, ws, grpc, udp
tlsTEXTtls or NULL
sniTEXTSNI hostname
hostTEXTHost header (WebSocket)
pathTEXTPath (WebSocket/gRPC/TCP)
nameTEXTDisplay name
raw_configTEXTOriginal raw config line
is_activeBOOLEANCurrently active runtime config
is_enabledBOOLEANIncluded in bulk operations
imported_atTIMESTAMPImport timestamp
is_deletedBOOLEANSoft-deleted flag
deleted_atTIMESTAMPDeletion timestamp
created_atTIMESTAMPInsertion timestamp
updated_atTIMESTAMPLast update timestamp

Indexes:

  • dedup_key β€” UNIQUE
  • subscription_id β€” FK index
  • is_enabled, is_active β€” filter queries
  • is_deleted β€” soft-delete queries

connection_tests

Stores individual test results per config.

CREATE TABLE connection_tests (
    id INTEGER PRIMARY KEY,
    run_id INTEGER REFERENCES connection_test_runs(id),
    config_id INTEGER NOT NULL REFERENCES configs(id),
    icmp_ok INTEGER,
    icmp_ms INTEGER,
    tcp_ok INTEGER,
    tcp_ms INTEGER,
    real_delay_ok INTEGER,
    real_delay_ms INTEGER,
    connect_ms INTEGER,
    ttfb_ms INTEGER,
    http_status INTEGER,
    download_mbps REAL,
    upload_mbps REAL,
    failure_kind TEXT,
    failure_reason TEXT,
    endpoint_ip TEXT,
    endpoint_location TEXT,
    endpoint_country TEXT,
    endpoint_asn TEXT,
    tested_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
run_idINTEGERFK to connection_test_runs
config_idINTEGERFK to configs
icmp_okBOOLEANICMP ping success
icmp_msINTEGERICMP latency
tcp_okBOOLEANTCP connect success
tcp_msINTEGERTCP latency
real_delay_okBOOLEANHTTP round-trip success
real_delay_msINTEGERHTTP round-trip latency
connect_msINTEGERTCP connect time
ttfb_msINTEGERTime to first byte
http_statusINTEGERHTTP response status
download_mbpsREALDownload throughput
upload_mbpsREALUpload throughput
failure_kindTEXTFailure classification
failure_reasonTEXTHuman-readable error
endpoint_ipTEXTResolved IP address
endpoint_locationTEXTGeoIP location
endpoint_countryTEXTCountry ISO code
endpoint_asnTEXTASN identifier
tested_atTIMESTAMPTest timestamp

Indexes:

  • config_id β€” per-config queries
  • run_id β€” per-run queries
  • (config_id, tested_at) β€” latest test per config

connection_test_runs

Groups test results into batches.

CREATE TABLE connection_test_runs (
    id INTEGER PRIMARY KEY,
    kind TEXT NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
kindTEXTRun description (e.g., β€œbulk”, β€œping”)
created_atTIMESTAMPRun timestamp

runtime_sessions

Tracks proxy process lifecycle.

CREATE TABLE runtime_sessions (
    id INTEGER PRIMARY KEY,
    config_id INTEGER REFERENCES configs(id),
    status TEXT NOT NULL
        CHECK(status IN ('starting', 'running', 'stopping', 'stopped', 'failed')),
    socks_host TEXT,
    socks_port INTEGER,
    http_host TEXT,
    http_port INTEGER,
    shadowsocks_host TEXT,
    shadowsocks_port INTEGER,
    process_id INTEGER,
    failure_reason TEXT,
    owner_kind TEXT,
    owner_instance_id TEXT,
    last_transition_reason_code TEXT,
    last_transition_reason_detail TEXT,
    last_transition_origin TEXT,
    cooldown_until TEXT,
    last_failed_at TEXT,
    last_failed_reason_code TEXT,
    started_at TIMESTAMP,
    stopped_at TIMESTAMP,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
config_idINTEGERFK to configs
statusTEXTstarting, running, stopping, stopped, failed
socks_hostTEXTSOCKS inbound host
socks_portINTEGERSOCKS inbound port
http_hostTEXTHTTP inbound host (if enabled)
http_portINTEGERHTTP inbound port
shadowsocks_hostTEXTShadowsocks inbound host (if enabled)
shadowsocks_portINTEGERShadowsocks inbound port
process_idINTEGEROS process ID
failure_reasonTEXTError message (if failed)
owner_kindTEXTcli or daemon
owner_instance_idTEXTDaemon instance UUID
last_transition_reason_codeTEXTMachine-readable transition reason code
last_transition_reason_detailTEXTHuman-readable transition details
last_transition_originTEXTTransition source such as CLI, daemon, health, or rotation
cooldown_untilTEXTRotation cooldown expiry as epoch seconds
last_failed_atTEXTLast runtime/health failure time as epoch seconds
last_failed_reason_codeTEXTMachine-readable last failure reason code
started_atTIMESTAMPSession start timestamp
stopped_atTIMESTAMPSession stop timestamp
created_atTIMESTAMPRecord creation timestamp
updated_atTIMESTAMPLast update timestamp

Indexes:

  • config_id β€” per-config queries
  • status β€” running session lookup
  • (owner_kind, owner_instance_id) β€” daemon reattach queries

cf_scan_results

Stores IP scan results.

CREATE TABLE cf_scan_results (
    id INTEGER PRIMARY KEY,
    ip TEXT NOT NULL UNIQUE,
    latency_ms INTEGER,
    download_mbps REAL,
    upload_mbps REAL,
    error TEXT,
    last_scanned_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
ColumnTypeDescription
idINTEGERPrimary key
ipTEXTIP address (unique)
latency_msINTEGERConnection latency
download_mbpsREALDownload throughput (if measured)
upload_mbpsREALUpload throughput (if measured)
errorTEXTError message (if failed)
last_scanned_atTIMESTAMPLast scan timestamp

Migrations

Migrations are run automatically on startup using SQLx.

Migration List

#FileDescription
0001init.sqlInitial schema: subscriptions, configs, connection_tests, runtime_sessions
0002add_connection_test_download_mbps.sqlAdd download_mbps to connection_tests
0003canonical_config_dedup_key.sqlAdd dedup_key to configs
0004add_runtime_session_inbound_ports.sqlAdd inbound port columns to runtime_sessions
0005drop_runtime_session_mixed_port.sqlClean up mixed port column
0006add_runtime_session_failure_reason.sqlAdd failure tracking to runtime_sessions
0007add_connection_test_runs.sqlAdd connection_test_runs table
0008add_connection_test_http_fields.sqlAdd HTTP fields (connect_ms, ttfb_ms, http_status)
0009add_connection_test_country_asn.sqlAdd GeoIP fields (country, ASN)
0010add_connection_test_upload_mbps.sqlAdd upload_mbps to connection_tests
0011add_cf_scan_results.sqlAdd cf_scan_results table
0012add_runtime_session_owner_transition_fields.sqlAdd owner tracking to runtime_sessions
0013add_runtime_session_transition_origin.sqlAdd transition origin tracking
0014add_runtime_session_cooldown_failure_fields.sqlAdd cooldown and failure tracking
0015add_config_soft_delete.sqlAdd soft-delete fields to configs

Migration Location

migrations/sqlite/0001_init.sql
migrations/sqlite/0002_add_connection_test_download_mbps.sql
...
migrations/sqlite/0015_add_config_soft_delete.sql

PostgreSQL migrations have equivalent files in migrations/postgres/.

Schema Diagram

subscriptions
    β”‚
    β”œβ”€β”€ configs (1:N via subscription_id)
    β”‚       β”‚
    β”‚       β”œβ”€β”€ connection_tests (1:N via config_id)
    β”‚       β”‚       β”‚
    β”‚       β”‚       └── connection_test_runs (1:N via run_id)
    β”‚       β”‚
    β”‚       └── runtime_sessions (1:N via config_id)
    β”‚
    └── (none)

cf_scan_results (standalone, not linked to configs)