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.5.tar.gz (175.9 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.5-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.5-cp312-abi3-musllinux_1_2_aarch64.whl (62.8 MB view details)

Uploaded CPython 3.12+musllinux: musl 1.2+ ARM64

deltalite-0.1.5-cp312-abi3-manylinux_2_28_x86_64.whl (65.5 MB view details)

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

deltalite-0.1.5-cp312-abi3-manylinux_2_28_aarch64.whl (63.2 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

deltalite-0.1.5-cp312-abi3-macosx_11_0_arm64.whl (17.9 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

deltalite-0.1.5-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.5.tar.gz.

File metadata

  • Download URL: deltalite-0.1.5.tar.gz
  • Upload date:
  • Size: 175.9 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.5.tar.gz
Algorithm Hash digest
SHA256 f32bfdc3694eaf50c9ebdaaecbc5c2569f7bbb25e654c4993e1be38c0d20551b
MD5 8c9b414e947c71032651ed0fb381e020
BLAKE2b-256 d6489bcfde29c0995ea05e2c19461a3dc0c6be0a50fece497c288682cb1596d3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ed7eabd20a48516204e152cd571417257b83d37dd960d75c83d498a4b04e68e7
MD5 3e50ce767459868f92b47bde897acef2
BLAKE2b-256 f109580aafe9ed5a82379986d654739455b3c0eb8ac3faf9b232c192d60e82fc

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 a64e87c31d11127062ecddeed0ca19ae4ace89cea8fae4ab188fa2fa627764ea
MD5 cd9d6d2dae880c2ac4238718697fc0be
BLAKE2b-256 bc44963c25fe15702cda11f48c45c20a584196b51bb9b4d0f94f1532437c9d13

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c21e7dde62aef0feb63fb214466c384c918c13b2ae1abadefb3c412df9aab06b
MD5 01c0b047daef46f468249d012b68a530
BLAKE2b-256 be5f495a00f9bd369585fee0f8f4d777239a4f0502da795b540b5589452744e3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 16e98ea37abda4f24743c816d8e31277c77523fbe92e0add0a0429b41cd442e3
MD5 e408cae8ae78ff8fbb45baa4e5a55f53
BLAKE2b-256 a4e3fdc5efd9c05bf96e52f2928f1cd83b9f1ad844d84feafc31d66fe68061aa

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e2d7579bd39551c28af81969d7d6710f7ee45e2ccd09eef5c067152171b1be93
MD5 61193a5e6e029965b0ed99c9d75107dd
BLAKE2b-256 dae39dab3f1694528a3f745933d8d83e686f4d3bd1fdec544ae490faf3ab81f6

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for deltalite-0.1.5-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2af20ea42d2a5f658870a18b628f1a6ad1e36c9f68677ff392aa7b59d43f6605
MD5 1e7bc1a1a0f489bcd13d7e5bcc4df94b
BLAKE2b-256 fd4393519f0b3ca35ea2d8ce261d49eebc5b702e5ebefb4f2f8e783ef6a25f2d

See more details on using hashes here.

Provenance

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

This release

0.1.5 This release

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