Open source — Apache 2.0 — v0.3.0kaptanto captures every insert, update, and delete from Postgres and MongoDB the moment it happens — stdout, SSE, gRPC, webhook, vector, or broker sinks (NATS, SQS, Kafka, Pub/Sub, RabbitMQ). Optional MCP server, HTTP enrichment, and YAML actions for AI-native pipelines. One static binary. Deploys anywhere.
Events flow from the WAL as each transaction commits. Burst p50 latency: ~3.5s at ~2.3k eps for the default Go build (2.3s with the optional Rust FFI build). No polling interval.
The same JSON format across every source. Write your consumer once and connect to any database.
Per-consumer positions persist on every event. Reconnect and resume from exactly where you stopped.
Snapshot and stream run concurrently. Watermark coordination prevents stale or duplicate rows.
Events for the same primary key always arrive in commit order. Slow consumers never block other partitions.
Two instances, one leader. Advisory lock election — session-scoped, no clock skew, ~5-second failover.
stdout, SSE, gRPC, webhook, vector, and five broker sinks — NATS, SQS, Kafka, Pub/Sub, and RabbitMQ. At-least-once delivery with per-key ordering end-to-end.
Route CDC to webhook actions, optional MCP subscriptions with ACL, and fail-open HTTP enrichment that attaches opaque ai_context before durable append.
Route events from different tables to different topics or queues via a Go template — cdc.{{.Schema}}.{{.Table}}.
Order inserted → push notification fan-out in seconds (burst p50 ~3.5 s in the published shared-CPU benchmark; ~2.3 s with the Rust FFI build). No polling, no webhook delay.
Product catalog change → Elasticsearch or Typesense index update within seconds, automatically.
Row updated → Redis key evicted before the next read hits the database. Consistent by design.
Every insert, update, and delete captured in order, with idempotency keys. Append-only and crash-safe.
Use --output sse or --output grpc for multi-consumer setups. Use --output nats|sqs|kafka|pubsub|rabbitmq to push directly to a queue. All of these require --auth-token (or --insecure for local dev) — see the Configuration docs.
Pipe to jq, a webhook, a queue, or anything that reads stdin.
| Tool | Real-time | No Kafka | Multi-DB | Single binary | Free | Min cost |
|---|---|---|---|---|---|---|
| kaptanto | ✓ | ✓ | ✓ | ✓ | ✓ | $0 |
| Debezium | ✓ | ✗ | ✓ | ✗ | ✓ | $0+Kafka |
| Confluent | ✓ | ✗ | ✓ | ✗ | ~ | ~$200/mo |
| Fivetran | ✗ | ✓ | ✓ | ✗ | ~ | $12K/yr |
| Estuary | ✓ | ✓ | ✓ | ✗ | ✓ | $0 |
| AWS DMS | ✓ | ✓ | ✓ | ✗ | ✗ | ~$70/mo |
auth-token config or KAPTANTO_AUTH_TOKEN env var, enforced on every network output; --insecure opts out with a startup warningserver-tls), separate from per-sink outbound TLS--all-tables opt-inid), quoted identifiers in snapshot SQL, WAL-canonical PK forms so watermark hashes match (BKF-02)--output nats|sqs|kafka|pubsub|rabbitmqMessageGroupId (SQS), record key (Kafka), ordering key (Pub/Sub), subject routing (NATS)cdc.{{.Schema}}.{{.Table}} — supported on all five sinks (subject, queue-URL, topic, and routing-key templates)queue_publish_total, queue_publish_errors_total, queue_publish_latency_seconds) and /healthz probe for each active sinkInstall kaptanto, point it at your database, and start streaming.