Skip to main content
Install the ClickHouse Node.js client:
At a glance, the pipeline looks like this:

Table design

Use CollapsingMergeTree with a sign Int8 DEFAULT 1 column. This engine enables efficient fork rollbacks: to cancel rows, the target re-inserts them with sign = -1 and ClickHouse merges the pair during background processing.
Design notes:
  • Apply DoubleDelta + ZSTD codecs to monotonically increasing columns such as block numbers and timestamps.
  • Use LowCardinality for columns with low cardinality like addresses to reduce storage and speed up filtering.
  • Store 256-bit integers as UInt256; serialize JavaScript BigInt values to strings before insertion.
Create the table in onStart using store.command():

onData

Call store.insert() to queue an insert. The call is non-blocking — inserts fire concurrently and are fully flushed when the target closes:

onRollback

Implement onRollback to handle blockchain forks. It is invoked in two situations:
  • reason: 'recovery' — on every restart with a saved cursor, to discard writes from a previous crashed or partial run
  • reason: 'fork' — when the stream detects a chain reorganisation
Use store.removeAllRows() to remove rows past the safe point. On CollapsingMergeTree-family tables with a sign column this re-inserts matching rows with sign = -1 (the only removal mechanism that propagates through materialized views); on other engines it falls back to a lightweight DELETE with a logged warning (requires ClickHouse ≥ 23.3):

Complete example

Docker setup

docker-compose.yml
See the clickhouseTarget reference for the full API.