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.3.tar.gz (173.5 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.3-cp312-abi3-musllinux_1_2_x86_64.whl (63.8 MB view details)

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

deltalite-0.1.3-cp312-abi3-musllinux_1_2_aarch64.whl (62.7 MB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ ARM64

deltalite-0.1.3-cp312-abi3-manylinux_2_28_x86_64.whl (65.4 MB view details)

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

deltalite-0.1.3-cp312-abi3-manylinux_2_28_aarch64.whl (63.1 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

deltalite-0.1.3-cp312-abi3-macosx_11_0_arm64.whl (17.8 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

deltalite-0.1.3-cp312-abi3-macosx_10_12_x86_64.whl (18.0 MB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: deltalite-0.1.3.tar.gz
  • Upload date:
  • Size: 173.5 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.3.tar.gz
Algorithm Hash digest
SHA256 5daafab4ed9d6f54cdcfea1cb7bfd900b906b6ab9402759c5a176b06fd943815
MD5 1f474877595f7f68f0ffcaf0daf50501
BLAKE2b-256 f9180ebcff958c74ea79f1e8dfbb261f5474bb06033da21ced1bde4d3e1cc2e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3.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.3-cp312-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 5f4a13be6ff584cb18b2162877fcb9f017f5d7a650039c271679c33d89914b95
MD5 81dab50d1acf7009185a36c49d338fed
BLAKE2b-256 2c08f0ddae42c7aef923a2b4b43b797b6a7ab781f05e05bfeee3916a3106a969

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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.3-cp312-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 206e41394a61182327120351e19df16932481a67a4edb14b3e77cbd6afd8e07e
MD5 3bdf7d222aa801835331838b6190ec95
BLAKE2b-256 296b2a5ea282e1ded2dfdc97f2dccc9fce88ec419a15f366db229a5e106160df

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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.3-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ed2d864ab2b63ffd83589f4fc24b23b69ccfc0165e593f04121e7da89b2c4e37
MD5 5e2858a91ceb3226503ea2feebf2a435
BLAKE2b-256 d6115aea109ae137d97e19f786e6e78114b326e8f334a71c534193815b69b006

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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.3-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4e7cc11b98f4211027f9ab387fc01b6592430b4d699422bac6f5f1a8774e8210
MD5 c55bdb0353522f4ffba8bd1f621019b2
BLAKE2b-256 31f8e10658fdb57819b473c824618928b659ad65f541143e9c7a9653a93e9084

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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.3-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 91a5b5f72e37701ac1d4541681be99a78dd14456fadcbd685026c8d91be1aa41
MD5 c276eafa5cf37932da239e03ff2ef8b2
BLAKE2b-256 683a1f9fd47e3df3fc534abb43e97898c03c7e813f566ba484b5e3f3df43fc35

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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.3-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for deltalite-0.1.3-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f43539e33e90d9d2d4f6010a38a69ac1ebc943b7ddb34cb07682734b7d284594
MD5 88f8126c44c784ca6d8fff2084f08dc5
BLAKE2b-256 69b842fed73269c9b93aace404b1c33dfa5886cb9d03cd377982d3b70b4808b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for deltalite-0.1.3-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

0.1.7

7 files

0.1.6

7 files

0.1.5

7 files

0.1.4

7 files

This release

0.1.3 This release

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