Tidefall 🌊

DATA RISES. THEN IT FALLS.

CICodecovHex.pmDocumentation

ETS-backed buffer for Elixir β€” accumulate writes, drain in periodic batches.

Tidefall is a generic, reusable buffering system inspired by the OpenTelemetry Batch Processor. It efficiently buffers arbitrary data and periodically processes it using a configurable processor function at regular intervals.

It ships with two concrete buffer implementations:

Both use partitioning to reduce lock contention and double-buffering for zero-downtime processing.

πŸ“¦ Installation

Add :tidefall to your list of dependencies in mix.exs:

def deps do
[
{:tidefall, "~> 1.0.0-rc.0"}
]
end

πŸš€ Usage

The recommended pattern is to define a dedicated buffer module and add it to your supervision tree. The module name becomes the default instance name:

defmodule MyApp.EventQueue do
use Tidefall.Queue, otp_app: :my_app
end
defmodule MyApp.StateMap do
use Tidefall.HashMap, otp_app: :my_app
end
# Supervision tree
children = [
{MyApp.EventQueue, processor: &MyApp.Sink.export/1, processing_interval: 1_000},
{MyApp.StateMap, processor: &MyApp.Sink.export/1}
]
Supervisor.start_link(children, strategy: :one_for_one)
# Queue β€” every item is buffered in insertion order and drained to the processor
:ok = MyApp.EventQueue.push(event)
# HashMap β€” same-key writes coalesce; only the latest value per key survives,
# and put_newer/4 resolves conflicts by version (newer version wins)
:ok = MyApp.StateMap.put(:user_1, %{name: "Alice"})
:ok = MyApp.StateMap.put_newer(:user_1, %{name: "Alice"}, version: 2)

The processor receives the accumulated batch on each tick and runs for its side effects (its return value is discarded):

def export(batch) do
# Queue: batch is [value, ...]
# HashMap: batch is [%Tidefall.HashMap.Entry{key: k, value: v}, ...]
Enum.each(batch, &MyApp.Sink.write/1)
end

For quick experiments or fully dynamic instances, a buffer can also be started directly with a runtime :name, e.g. Tidefall.Queue.start_link(name: :my_queue, processor: &MyApp.Sink.export/1).

See the full documentation on HexDocs for the module-based and direct-usage guides, configuration (config file and supervision tree), choosing between Queue and HashMap, telemetry events, and the complete start/runtime option reference.

🀝 Contributing

Contributions are welcome and appreciated! To report a bug, request a feature, or open a pull request, see CONTRIBUTING.md for the workflow, validation steps (mix test.ci), and commit conventions.

πŸ™ Acknowledgements

Tidefall began as a fork of partitioned_buffer, originally developed at Appcues. partitioned_buffer is still maintained by Appcues; Tidefall is an independent fork that has since taken a different direction. Many thanks to the Appcues team for releasing the original implementation under the MIT license.

Copyright 2026 Carlos BolaΓ±os (Tidefall)
Copyright 2025 Appcues, Inc. (PartitionedBuffer)

Tidefall source code is licensed under the MIT License.