Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

I built Kaptanto to turn database writes into events that downstream software can consume without repeatedly polling for changes. Its PostgreSQL path reads logical changes from the write-ahead log (WAL), while the tool’s described design also covers snapshot handoff, local event durability, ordering, and failover. Here is how I described that implementation—and what the reported benchmark does and does not show.

This account reflects Lucas Andrade’s article, published April 22, 2026. Kaptanto’s features and implementation details below are attributed to Andrade; they have not been independently verified here.

Why use change data capture instead of polling?

Polling asks an application to check a database repeatedly for new or changed rows. That creates recurring queries even when nothing has changed, and the consumer’s view of a change can be delayed until the next check. Another option is to make application code publish a notification whenever it writes to the database. That can work, but every writer must reliably send the matching event; a path that writes data but forgets to notify consumers can leave them out of sync.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Change data capture (CDC) moves the capture point closer to the database’s record of changes. Instead of asking repeatedly whether something changed, a consumer reads a stream of changes and turns them into events for other systems. This can reduce the need to modify every application that writes to the source, but it introduces its own engineering questions: how to establish the starting state, resume after interruption, persist events, preserve ordering, and coordinate multiple instances.

How PostgreSQL exposes changes to a CDC consumer

PostgreSQL’s logical decoding extracts persistent table changes from WAL records and presents them in a form applications can interpret. A logical replication slot represents a replayable stream of changes from a database. The slot tracks the consumer’s position so changes can be read from the stream rather than inferred through repeated table queries. See the PostgreSQL documentation on logical decoding concepts.

A slot is a building block, not a complete delivery system. A CDC tool still has to decide how to initialize a consumer with existing rows, how to coordinate that snapshot with changes arriving during the snapshot, and when it is safe to advance the source position. The slot and decoder do not by themselves establish that a particular tool has gap-free delivery, exactly-once processing, or a specific failover guarantee.

How I described Kaptanto’s snapshot-to-stream handoff

A consumer often needs both the database’s existing state and all changes that occur while that state is being read. If it takes a snapshot first and starts listening afterward, a write between those operations may be missed. If it streams first but cannot reconcile those changes with the snapshot, consumers may see duplicate or out-of-order effects.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Andrade says Kaptanto opens a replication slot, takes a consistent snapshot, emits the snapshot rows, and then applies buffered WAL changes relative to a watermark. The intended handoff is to move from the initial state to ongoing changes without a gap or duplicate events. Andrade summarized his design this way: “The slot opens before the snapshot, so nothing is missed.” That is his explanation of Kaptanto’s approach, not an independently established guarantee about the implementation.

The general design requirement is broader than choosing an operation order: the snapshot boundary and stream position need to be coordinated so the consumer can tell which changes are already represented in the initial state and which must be emitted afterward. Teams evaluating any CDC implementation should verify the documented snapshot semantics and test interruption and restart cases, rather than assume that having a replication slot alone solves the handoff.

How Kaptanto handles persistence, ordering, and multiple instances

Persisting events before advancing the source position

Andrade says Kaptanto writes each event to an embedded Badger log before advancing the PostgreSQL checkpoint. The underlying concern is durability: if a source position advances before the event is safely retained, a crash could leave the consumer unable to recover that event from its own log. Persisting first is the sequence Andrade describes; the account does not independently establish its crash guarantees, retention behavior, or delivery semantics.

Durable storage also does not automatically mean consumers receive each event exactly once. A restart can require replay, and downstream systems may receive duplicates unless the producer and consumer agree on acknowledgements, identifiers, or idempotent handling. The important evaluation question is how the tool defines persistence and recovery at each boundary: source stream, local log, and downstream delivery.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Maintaining order

Andrade says Kaptanto uses log sequence number (LSN) positions to preserve per-key ordering. This is a reported implementation detail, not a claim that all events across all keys have a single total order. A team that depends on ordering should establish the precise scope of the guarantee—per key, partition, table, or whole stream—and how it behaves when processing is parallelized or restarted.

Coordinating active and standby instances

Andrade reports that Kaptanto uses a PostgreSQL advisory lock to elect an active instance. In the described design, that lock is the coordination mechanism for active/standby operation. The article does not independently verify how quickly a standby takes over, what happens to in-flight events during failover, or whether concurrent delivery is impossible in every failure scenario. Those are important operational behaviors to test under the deployment’s actual failure and recovery conditions.

What Kaptanto supports, according to its author

Andrade describes Kaptanto as supporting PostgreSQL and MongoDB sources and normalizing their changes into a shared event structure. He says it can emit events through standard output in NDJSON format, server-sent events (SSE), and gRPC. These are claims about Kaptanto in his April 22, 2026 article, not independently tested capabilities. The description does not establish details such as version compatibility, connector-specific privileges, schema-change behavior, or delivery guarantees for each output.

Normalizing different databases into a common event shape can make downstream integration simpler, but it can also obscure source-specific differences. Before relying on a shared structure, a team should check how it represents inserts, updates, deletes, transaction boundaries, types, and schema changes for each supported source.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How this compares with Debezium’s documented PostgreSQL approach

Debezium’s official PostgreSQL connector documentation describes an initial consistent snapshot followed by streaming committed row-level inserts, updates, and deletes into Kafka topics. It documents logical decoding and replication slots as part of the connector’s PostgreSQL capture approach. See the Debezium PostgreSQL connector documentation.

This is a useful comparison of broad patterns: initialize from a consistent snapshot, then stream committed changes using PostgreSQL’s logical change stream. It does not demonstrate that Kaptanto and Debezium have equivalent delivery, recovery, ordering, operational, or performance characteristics. Their documented outputs differ in the descriptions available here: Kaptanto’s author lists stdout/NDJSON, SSE, and gRPC; Debezium’s connector documentation describes Kafka topics.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What the reported benchmark says—and what it cannot establish

Andrade reports testing against PostgreSQL 16 on an Apple M-series machine using Docker Desktop. The figures below are his 2026 results for that stated setup; they were not independently reproduced here. They should not be generalized to production hardware or treated as a neutral industry-wide comparison.

Implementation tested by Andrade Steady rate Large-batch rate
Kaptanto 4,805 events/sec 36,267 events/sec
kaptanto-rust 3,559 events/sec 31,883 events/sec
Debezium 128 events/sec 150 events/sec
Sequin 220 events/sec 324 events/sec

These are author-reported measurements, not a broadly controlled comparison. The available account specifies the database version and broad machine and container setup, but the figures should be read within that stated environment and methodology. Workload shape, configuration, output path, durability settings, and other conditions can materially affect CDC throughput; the listed rates alone do not predict performance in another deployment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Andrade also reports that the Rust FFI version had lower throughput than Kaptanto in this benchmark, while showing lower p50 latency and recovery time. Those are his reported outcomes as well; without independently reproduced measurements and fuller workload details, they should not be used to conclude that one implementation will be faster or recover better in another environment.

What to verify before choosing or deploying a CDC tool

Benchmark numbers are only one part of a CDC decision. Evaluate the behaviors that determine whether consumers can recover correctly and whether the operational dependencies fit your environment.

  • Source support and permissions: Confirm supported database versions, required privileges, logical decoding configuration, and any source-specific limitations.
  • Snapshot consistency: Establish how the tool coordinates initial rows with changes made during the snapshot, and how it resumes if the snapshot is interrupted.
  • Restart and retention behavior: Determine what position is persisted, how long the source can retain changes for a disconnected consumer, and what happens if the consumer falls too far behind.
  • Durability and duplicates: Find out when the source checkpoint advances relative to local persistence and downstream acknowledgement. Plan for duplicate handling unless the tool’s end-to-end semantics are clearly documented and suitable for your use.
  • Ordering scope: Check whether ordering is guaranteed per key, transaction, partition, or across the full stream, and whether parallel processing changes that guarantee.
  • Failover: Test takeover, in-flight work, and recovery with the actual database and deployment configuration, rather than assuming an active/standby mechanism prevents every duplicate or interruption.
  • Outputs and dependencies: Match supported outputs and required infrastructure to the consumers you need to serve, and confirm which behaviors are available for each source and output combination.
  • Reproducible performance: Benchmark a representative workload with documented database, hardware, deployment, configuration, event size, batch pattern, durability settings, and measurement method.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.