BYOS Architecture
How Local Agents (BYOS) split data, identity, and control across your infrastructure and dbtrail
This page is the reference for how Bring-Your-Own-Server (BYOS, also called Local Agents) actually splits work between your network and dbtrail. If you're new to BYOS, start with the Local Agents guide for install and operations; come back here when you want to understand why the architecture has the shape it does, troubleshoot identity / event-routing edge cases, or follow a runbook that mentions internal terms.
The two index stores
A BYOS deployment maintains two indexes for every server you track. They serve different purposes and live in different places:
| Store | Location | Written by | Read by |
|---|---|---|---|
Local index (bintrail_index DB) | Customer's MySQL host (127.0.0.1:3306) | bintrail stream (your side) | bintrail shim (your side) — used by ProxySQL time-travel queries |
Remote index (bt_<server_uuid> DB) | dbtrail-managed metadata EC2 | bintrail agent ships metadata → dbtrail FastAPI proxies to the metadata EC2 agent | Dashboard Explorer, MCP tools, forensics, recovery, retention worker |
Both are populated continuously. They are not redundant copies — each enables a different feature:
- The local index stays close to your MySQL so ProxySQL time-travel queries (
SELECT … FROM t__time_travel('2026-05-23 12:00')) and_diff()windows resolve without a round-trip to dbtrail's cloud. - The remote index is what the dashboard, MCP server, and Claude integrations read against. It also backs schema-aware forensics + the recovery dry-run flow.
If you ever notice an EC2 in your dbtrail-managed inventory that "doesn't look used" by a BYOS server, that's the remote index for that server. It is not dead allocation — see Troubleshooting → "Duplicate byos-<N> records" if you're looking at the wrong record.
How a metadata batch flows
┌────────────────────────────────────────────────────────────────────┐
│ Your network │
│ │
│ MySQL ───► bintrail stream ───► bintrail_index (local) │
│ │ │ │
│ │ │ read events │
│ │ ▼ │
│ │ bintrail agent ─────┐ │
│ │ │ │
│ │ bintrail shim ◄───┐ │ │
│ │ │ │ │
│ ▼ │ │ │
│ ProxySQL ──► time-travel SQL ────────► bintrail_index │
│ │
└────────────────────────────────────────────────────────────────────┘
│
│ HTTPS
│ POST /v1/events
│ + WS /v1/agent
▼
┌────────────────────────────────────────────────────────────────────┐
│ dbtrail cloud │
│ │
│ FastAPI (control plane) ─────┐ │
│ │ │ │
│ │ resolve server │ ingest_metadata │
│ ▼ ▼ │
│ Postgres (tenant schemas) Metadata EC2 (per-tenant) │
│ ├─ registered_servers └─ bt_<server_uuid> DBs │
│ ├─ onboarding_steps │
│ └─ server_stats_history │
│ │
│ Dashboard, MCP tools, Claude integrations ◄─── read bt_* │
│ │
└────────────────────────────────────────────────────────────────────┘bintrail agent opens a persistent outbound WebSocket to wss://api.dbtrail.com/v1/agent and posts metadata batches to https://api.dbtrail.com/v1/events. Both are outbound-only — no inbound ports needed on your side.
Server identity
Every BYOS server has two identifiers that you may need to know about:
--server-id (uint, required)
A small numeric identifier scoped to the customer's host. The agent emits it in every event payload as bintrail_id. By convention each demo or production install picks a stable value (e.g. 202, 302, 402) and never changes it — the local bintrail_index keys events by this number.
--server-uuid (UUID, optional but recommended)
The UUID of a server you pre-registered via the dashboard or POST /api/v1/servers. The agent sends this in the X-Bintrail-Server-Uuid header on the WebSocket handshake. dbtrail uses it to bind the WS session to your pre-registered server record so the dashboard shows the right name, onboarding completes cleanly, and --server-uuid mismatches are surfaced as server-side warnings.
Without --server-uuid, the agent's first event batch triggers _auto_register_server, which creates a new byos-<server-id> record in the SaaS — useful as a back-compat path for older CLIs but it bypasses your pre-registered records entirely. See the cleanup runbook if this happened to you.
Putting them together
A correctly-configured systemd unit looks like:
[Service]
ExecStart=/usr/local/bin/bintrail agent \
--api-key bt_live_… \
--endpoint wss://api.dbtrail.com/v1/agent \
--server-id 202 \
--server-uuid 183819c0-5742-400a-b1ae-cfb4f63dbdd4 \
--source-dsn bintrail:…@tcp(127.0.0.1:3306)/ \
--schemas shopcart \
--s3-bucket your-archive-bucket \
--s3-region us-east-1 \
--s3-prefix demo/host-AThe --server-id value is whatever your local install picked (and what the local bintrail stream will keep using for its index). The --server-uuid comes from the pre-registered server's UUID — find it in the dashboard at /app/servers/<UUID> or via GET /api/v1/servers.
The metadata EC2 (FAQ for operators)
"I see a dbtrail-managed EC2 allocated for my BYOS tenant. Is it doing anything?"
Yes. That EC2 hosts the remote index — one bt_<server_uuid> MySQL database per server you've registered. The dashboard's Explorer, the MCP query/status tools, the Claude recover dry-run, and the retention worker all read against those DBs. If you decommission that EC2, BYOS time-travel queries via the dashboard and MCP integrations stop working.
"But the agent writes the index locally — what's it for?"
The local index is for the customer-side query path (ProxySQL _time_travel() + _diff()). The remote index is for the dbtrail-side query path (Explorer + MCP + Claude). The agent ships metadata to both.
"How do I know my agent is talking to the right remote DB?"
Check the dashboard — the server card shows the event count, which should match SELECT COUNT(*) FROM binlog_events in the local bintrail_index. If the dashboard says 0 and your local count is high, you're hitting the auto-create-duplicate symptom; see Troubleshooting → "Duplicate byos-<N> records".
Related
- Local Agents — install and operations
- Capacity Planning — rotation, retention, and disk sizing
- Troubleshooting — common issues including duplicate records