System Requirements
Minimum Requirements
Disk Space Estimation
DuckDB stores data in a columnar format which is highly compressed. As a rough guide:- 1 million transactions ≈ 50-100 MB on disk
- 10 million transactions ≈ 500 MB - 1 GB
- 100 million transactions ≈ 5-10 GB
instructions.db (compiled rules) is typically under 1 MB regardless of the number of rules.
Configuration Reference
FinWatch is configured entirely through environment variables. Here is the complete reference:Core Configuration
Git Repository (GitOps)
Data Synchronization
Database Paths
FinWatch creates its databases in theblnk_agent/ directory relative to the working directory:
Memory Management
DuckDB’s performance comes from keeping data in memory. As your transaction volume grows, memory management becomes critical.How Memory Is Used
DuckDB uses memory for:- Buffer pool — Cached table pages for fast reads.
- Query execution — Intermediate results from aggregate queries.
- Write-ahead log — Buffered writes before checkpointing to disk.
Configuring the Memory Limit
TheFINWATCH_MEMORY_LIMIT environment variable controls DuckDB’s maximum memory usage:
512MiB, 1GiB, 2GiB, 4GiB, 8GiB, 16GiB.
DuckDB Pragmas
FinWatch initializes DuckDB with the following settings:threads = 1: Limits DuckDB to a single execution thread. This simplifies the single-writer concurrency model. Go’s runtime handles HTTP concurrency separately.memory_limit: The upper bound on DuckDB’s memory consumption. When exceeded, DuckDB spills intermediate results to theduckdb_temp/directory.checkpoint_threshold = '64MiB': Controls how frequently in-memory data is flushed to disk. Lower values mean more frequent writes (safer but slower).
Memory Sizing Guidelines
Temp Directory
When DuckDB exceeds its memory limit, it spills data toblnk_agent/duckdb_temp/. Ensure this directory:
- Has sufficient disk space (at least 2x the memory limit).
- Is on fast storage (SSD recommended).
- Is not on a tmpfs or RAM-backed filesystem (defeats the purpose of spilling).
Docker Deployment
Production Docker Run
--restart unless-stopped: Auto-restart on crash or server reboot.-v finwatch-data:/app/blnk_agent: Persistent volume for DuckDB data. Without this, data is lost on container restart.--memory 6g: Docker memory limit. Set higher thanFINWATCH_MEMORY_LIMITto leave room for Go runtime overhead.--cpus 2: Limit CPU usage.
Production Docker Compose
Health Check
The Docker health check uses the/instructions endpoint. A 200 OK response confirms:
- The HTTP server is running.
- The DuckDB instruction database is accessible.
- The API can serve requests.
Kubernetes Deployment
Deployment Manifest
Important Kubernetes Notes
- Replicas: 1. FinWatch uses an embedded DuckDB database with a single-writer model. Running multiple replicas against the same data volume will cause write contention. If you need horizontal scaling, see the Scaling Considerations section.
- PVC with SSD. DuckDB performance is heavily dependent on disk I/O for spill-to-disk operations. Use SSD-backed persistent volumes.
- Secrets. Store
BLNK_DSN(which contains database credentials) in a Kubernetes Secret, not in plain-text environment variables. - Liveness vs. Readiness. The liveness probe checks if FinWatch is alive; the readiness probe checks if it’s ready to accept traffic. The readiness probe has a shorter interval for faster traffic routing.
Monitoring and Observability
Log Format
FinWatch uses zerolog for structured JSON logging. In production, logs are formatted as:Key Log Events to Monitor
Metrics to Watch
Integrating with Log Aggregators
FinWatch’s JSON logs can be consumed by any standard log aggregator:- Datadog: Configure the Docker log driver or use the Datadog agent’s log collection.
- ELK Stack: Forward container logs via Filebeat or Fluentd.
- Grafana Loki: Use Promtail to ship container logs.
- CloudWatch: Use the
awslogsDocker log driver.
Backup and Recovery
What to Back Up
DuckDB File Backup
DuckDB database files can be backed up with a simple file copy while FinWatch is running, but for consistency, prefer:Recovery Scenarios
Scenario: DuckDB data is corrupted or lost.- FinWatch restarts and creates a fresh DuckDB database.
- Compiled rules are rebuilt from the
.wsfiles (via Git sync or local directory). - Historical transaction data is rebuilt via the watermark sync from PostgreSQL.
- Recovery is fully automatic — no manual intervention required.
- FinWatch continues to operate with the last-synced rules.
- Git polling logs warnings but does not crash.
- When the repository becomes available again, FinWatch catches up automatically.
- Watermark sync pauses. Logs warnings.
- FinWatch continues to evaluate rules against locally-stored data.
- Aggregate functions use the data available in DuckDB — results may be stale.
- When PostgreSQL recovers, the watermark sync resumes from where it left off.
Scaling Considerations
Single-Instance Model
FinWatch is designed as a single-instance service. This is a deliberate architectural choice driven by DuckDB’s single-writer concurrency model. The benefits:- Simplicity: No distributed coordination, no consensus protocols, no split-brain scenarios.
- Consistency: All rules see the same data. No eventual consistency issues.
- Performance: Local DuckDB queries are faster than any network-based alternative.
When to Scale
A single FinWatch instance can comfortably handle:- 10,000+ transactions per second for simple rules.
- 1,000+ transactions per second with complex aggregate rules.
- 100+ active rules with no performance impact.
- Vertical scaling: Increase memory and CPU. DuckDB benefits significantly from more RAM.
- Rule optimization: Ensure cheap conditions are evaluated before expensive aggregates (the gate-and-probe pattern).
- Time window reduction: Smaller aggregate time windows mean less data to scan.
- Data retention: Purge old transaction data that is no longer needed for rule evaluation.
Multi-Instance Patterns
If you truly need horizontal scaling (e.g., processing 100K+ TPS), consider:- Sharding by source account: Route transactions to different FinWatch instances based on the source account. This ensures aggregate functions for a given account are always evaluated by the same instance.
- Read replicas: Run multiple instances in read-only mode for serving API queries, with a single write instance for ingestion.
Pre-Production Checklist
- Environment variables are set — Verify all required vars are configured.
- Persistent volume is attached — DuckDB data survives container restarts.
- Memory limits are appropriate — Docker/K8s limit > DuckDB
memory_limit+ 1-2 GB headroom. - Git repository is accessible — FinWatch can clone and pull the rules repo.
- PostgreSQL is reachable — If using
BLNK_DSN, verify connectivity. - Health checks are configured — Liveness and readiness probes are active.
- Logging is aggregated — Logs are shipped to your monitoring platform.
- Backup strategy is in place — Rules are in Git; data can be rebuilt.
- Alerts are configured — Monitor for compilation errors, high latency, and sync failures.
- Test transactions have been validated — Run a full test suite before going live.
Next Steps
- Integration Guide — Connect your application to FinWatch.
- GitOps Rule Management — Set up Git-based rule deployment for production.
- Troubleshooting — Diagnose and fix common production issues.
- Understanding the Architecture — Deep dive into how FinWatch works.
.png?fit=max&auto=format&n=0JF6z69u57hmqsWm&q=85&s=531373acedba0eb783b669f6d558dfd8)