Skip to main content

deltalite

Streaming, partition-level upsert for Delta Lake tables that replaces delta-rs's SQL MERGE with a bounded-memory merge engine. Memory is bounded by the size of the incoming batch and a few concurrency knobs — never by the size of the target table.

delta-rs stays the storage and protocol layer (transaction log, checkpoints, Parquet writing, Add-action statistics, S3 conditional-put commits, conflict resolution). deltalite replaces only the merge execution.

import deltalite

table = deltalite.DeltaLiteTable.open("s3://bucket/my_table")
stats = table.upsert(record_batch, primary_keys=["id"], partition_key="day")
print(f"v{stats.version}: +{stats.rows_inserted} / ~{stats.rows_updated}")

Why

delta-rs MERGE executes a DataFusion hash join whose memory scales with the scanned target, and it can deadlock under a bounded memory pool (delta-io/delta-rs#4614). For a large, slowly-changing table merged against a comparatively small batch — the typical incremental-sync shape — that means either OOM risk or a hang.

deltalite takes a different route:

  1. Build a primary-key hash set over the (small) source batch.
  2. Stream the (large) target one Parquet row group at a time, dropping rows whose key is in the source set.
  3. Write survivors plus the source rows into new files.
  4. Commit every touched partition in one atomic Delta commit.

Peak memory is bounded by the source batch and the concurrency knobs, not by the table. In validation, resident memory stayed flat from 62k- to 1M-row partitions (~4× below MERGE) at matching write volume, via exact content-based file selection.

Installation

pip install deltalite
# or
uv add deltalite

Prebuilt cp312-abi3 wheels are published for manylinux (2_28) and musllinux on x86_64/aarch64, and macOS on arm64/x86_64. A single wheel works on any CPython 3.12 or newer. No Rust toolchain is needed to install.

Usage

upsert accepts anything with the pyarrow C-stream interface — a pyarrow.Table, a RecordBatch, or a RecordBatchReader:

import pyarrow as pa
import deltalite

table = deltalite.DeltaLiteTable.open(
    "s3://bucket/events",
    storage_options={
        "AWS_REGION": "us-east-1",
        "AWS_ACCESS_KEY_ID": "...",
        "AWS_SECRET_ACCESS_KEY": "...",
    },
)

batch = pa.table({
    "id":  [1, 2, 3],
    "day": ["2026-01-01", "2026-01-01", "2026-01-02"],
    "val": ["a", "b", "c"],
})

stats = table.upsert(
    batch,
    primary_keys=["id"],
    partition_key="day",          # omit for an unpartitioned table
    commit_metadata={"source": "my-sync"},
)

print(stats)
# UpsertStats(version=42, partitions_touched=2, files_added=2, files_removed=1, ...)

Rows in the batch whose primary key already exists are replaced; new keys are inserted. Deletes are not expressed through upsert — it is an insert-or-replace by key. Duplicate primary keys within a single batch are rejected (raising DeltaLiteError) rather than silently double-inserted.

API

DeltaLiteTable

Method Description
DeltaLiteTable.open(uri, storage_options=None) Open an existing Delta table. storage_options is the usual object-store dict (S3/GCS/Azure/local).
DeltaLiteTable.is_deltatable(uri, storage_options=None) True if a Delta table exists at uri.
.upsert(data, primary_keys, partition_key=None, **opts) Insert-or-replace data by key. Returns UpsertStats. See knobs below.
.version() Current table version (int).
.reload() Reload the table state from the log.
.schema_arrow() Table schema as a pyarrow Schema.
.partition_columns() Partition column names (list[str]).
.file_uris() URIs of the table's active data files.
.history(limit) Recent commit history entries.

UpsertStats

Returned by upsert. Counts: version, partitions_touched, files_added, files_removed, files_carried_over, files_probed, rows_updated, rows_inserted, rows_copied, source_rows, null_pk_rows. Per-phase wall-clock timings (milliseconds): plan_ms (listing + pruning files), rewrite_ms (reading + rewriting the touched partitions), commit_ms (committing to the Delta log).

Exceptions

All inherit from DeltaLiteError, so you can catch the base or branch on kind:

Exception Raised when
DeltaLiteError Base class / generic failure.
DeltaLiteCommitConflictError Concurrent commit won the conditional-put race (retry-exhausted).
DeltaLiteSchemaMismatchError Batch schema is incompatible with the table.
DeltaLiteTableNotFoundError No Delta table at the URI.
DeltaLiteUnsupportedTableError Table uses a feature deltalite can't handle (e.g. deletion vectors, column mapping).
DeltaLiteSourceTooLargeError Batch exceeds max_source_bytes (see below).

Operational knobs

Per-call — keyword arguments to upsert (defaults in parentheses):

Argument Default Purpose
max_parallel_partitions 2 Partitions merged concurrently.
max_parallel_files 4 Files read concurrently within a partition.
max_buffered_bytes 64 MiB Output buffered in memory before flushing.
prune_strategy "probe" "probe" skips files that can't contain a source key; "none" scans all.
skip_unmatched_files True Convenience toggle: Falseprune_strategy="none".
probe_concurrency 8 Concurrent statistics/probe reads.
read_batch_size 8192 Row-group read batch size.
target_file_size table setting, else 100 MiB Output file size target.
max_source_bytes 2 GiB Oversized-batch guard (0 disables).
multipart_threshold / multipart_part_size 64 MiB / 16 MiB Multipart upload thresholds (0 threshold disables).
commit_max_retries 15 Conditional-put commit retry budget.
commit_metadata None Extra key/values recorded in the Delta commit.

Process-global — environment variables, enforced on top of the per-call knobs so that many concurrent upsert threads in one process cannot multiply the budgets:

DELTALITE_PROCESS_MAX_PARALLEL_PARTITIONS (8), DELTALITE_PROCESS_MAX_PARALLEL_FILES (16), DELTALITE_PROCESS_MAX_BUFFERED_BYTES (256 MiB), DELTALITE_MAX_SOURCE_BYTES, DELTALITE_MULTIPART_THRESHOLD_BYTES, DELTALITE_MULTIPART_PART_SIZE_BYTES.

Metrics

deltalite emits via the Rust metrics facade (static labels only): deltalite_upserts_total (outcome, prune_strategy, error_kind), deltalite_upsert_duration_seconds, deltalite_files_{added,removed,carried_over,probed}_total, and deltalite_rows_{updated,inserted,copied}_total.

Compatibility & status

  • Built against deltalake (delta-rs) 0.32.x as the storage/protocol layer. Correctness is guaranteed by a differential parity suite that runs the same batch sequences through real delta-rs MERGE and through deltalite.upsert and asserts identical logical content — not by version equality.
  • Not supported: tables with deletion vectors or column mapping (detected and raised as DeltaLiteUnsupportedTableError), and SCD2 merges.
  • deltalite rejects duplicate source primary keys that MERGE silently double-inserts — check pre-existing data if you migrate an existing pipeline.

This package is developed in the PostHog monorepo under rust/deltalite/. Issues and source live there.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deltalite-0.1.7.tar.gz (179.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

deltalite-0.1.7-cp312-abi3-musllinux_1_2_x86_64.whl (64.2 MB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ x86-64

deltalite-0.1.7-cp312-abi3-musllinux_1_2_aarch64.whl (63.1 MB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ ARM64

deltalite-0.1.7-cp312-abi3-manylinux_2_28_x86_64.whl (65.8 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ x86-64

deltalite-0.1.7-cp312-abi3-manylinux_2_28_aarch64.whl (63.5 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

deltalite-0.1.7-cp312-abi3-macosx_11_0_arm64.whl (18.0 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

deltalite-0.1.7-cp312-abi3-macosx_10_12_x86_64.whl (18.1 MB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

Details for the file deltalite-0.1.7.tar.gz.

File metadata

  • Download URL: deltalite-0.1.7.tar.gz
  • Upload date:
  • Size: 179.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for deltalite-0.1.7.tar.gz
Algorithm Hash digest
SHA256 3239569df220821765ab9d7dc7a0e58cfbe6256670c29bbdc7df25a07eef7ce7
MD5 7ac3dfa2fdbb9d077c9b714c814c876b
BLAKE2b-256 eebae08c970ed75b05cc3fe406f404eff1f68e82d399283e6937d8ebb8699401

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7.tar.gz:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ceb20644b87642e8265de01f4b89286891e75ddba226914e4100db561cfde1c7
MD5 3555d20797d5f9a54ce33223a3054935
BLAKE2b-256 f67789f31c64f7ce7d05e48b638652b284e8a8ce356c06c4124002d853bae22b

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-musllinux_1_2_x86_64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 8d432f322bc9546453ed895f6c68e5fe2be8b43143642329bb7c828f958ee4f4
MD5 dd18472c05cdbb7f9d2739829022330c
BLAKE2b-256 2e7f405fd089c8e3f56c51d6aec13586d729cd991f0b9e8aace5e3a2e30a180f

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-musllinux_1_2_aarch64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 854f3657dccbc48cce11d5c1cd90dd92f3c4c897ef1c274a3ebae06aea5fcb65
MD5 e9342bfe4e7ce0ca8db09959ef8dbd3b
BLAKE2b-256 81efa6b7ea3d6367875c6fb9138ca08d70df1c5f4b6200d9649a7773fd1cbb77

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-manylinux_2_28_x86_64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e6e5bf4e90e7459d4538f4270e5c70e5b41750fd91c41e84aba311b5ad93d810
MD5 700a1b27ff42cb1d712c84aeb5ec0ba8
BLAKE2b-256 1e53c69bf668d442e514f7ab2443c14831e6241fd0151cec2acfd429e6298ad8

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-manylinux_2_28_aarch64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 211f6d4ca4c0168d5a43c7acdcf0feb5cc53f80ce9febaab3341cdbbece8b501
MD5 9516174b7c54168c2b69a2dd77137616
BLAKE2b-256 d4e1f4d68be53a8a0786d06cd87aeb06f6bf91f3c8af87a5d382e9ff8200fb27

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-macosx_11_0_arm64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deltalite-0.1.7-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.7-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a9617a7a13b3e2dad34345130846b4bae67e940b5c7a82982024d9aad116a193
MD5 5e442d7cea1d1e50c08730750978ca79
BLAKE2b-256 ce19339cef01f049c2baa873266788be9bd9083b20025adfc82cf82cd680b030

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.7-cp312-abi3-macosx_10_12_x86_64.whl:

Publisher: build-deltalite.yml on PostHog/posthog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.7 This release

7 files

0.1.6

7 files

0.1.5

7 files

0.1.4

7 files

0.1.3

7 files

0.1.2

7 files

0.1.1

7 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page