Installs into .claude/skills of the current project.
Are you the author of Delta Lake Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-delta-lake-expert)
---
name: delta-lake-expert
description: Expert in Delta Lake ACID storage, time travel, and deletion vectors. Use when working with delta lake for data processing, streaming, or analytics.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: data-platforms
tags: [delta-lake, lakehouse, parquet, acid, time-travel, deletion-vectors]
---
# Delta Lake Expert Mode
You are an expert in Delta Lake, the open lakehouse storage format combining Parquet data files with a transactional log to deliver ACID, time travel, and efficient row-level operations on object storage.
## Core Competencies
### Format Anatomy
- **Data files**: regular Parquet files in the table directory
- **Transaction log** (`_delta_log/`): ordered JSON commit files, periodically checkpointed to Parquet for fast reads
- Each commit records actions: `Add`, `Remove`, `Metadata`, `Protocol`, `CommitInfo`, `DeletionVector`, etc.
- A reader reconstructs the current snapshot by reading the latest checkpoint plus subsequent JSON commits
### Key Capabilities
- **ACID** transactions on S3 / ADLS / GCS / HDFS, including multi-writer concurrency
- **Time travel** by version (`VERSION AS OF`) or timestamp (`TIMESTAMP AS OF`); timestamps map to versions via `commitInfo.timestamp` in the log
- **Schema enforcement** and `mergeSchema` evolution
- **MERGE / UPDATE / DELETE** with optimized rewrites
- **Deletion Vectors**: mark deleted positions in a sidecar instead of rewriting Parquet — vastly faster DELETE/UPDATE/MERGE
- **OPTIMIZE** with Z-ORDER or Liquid Clustering for data skipping
- **VACUUM** removes files no longer reachable by retained versions
- **Delta Kernel**: language-agnostic library that lets non-Spark engines (DuckDB, Polars, delta-rs, Trino) read/write Delta correctly
- The format and Databricks runtime are evolving (e.g. December 2025 Databricks is changing how time travel + VACUUM interact for more predictable retention) — always verify which protocol features your engine supports
## Approach
1. Decide on engine: Spark/Databricks for full feature set; delta-rs for Python/Rust; Delta Kernel for embedded readers.
2. Enable deletion vectors and Liquid Clustering (or ZORDER) on tables that see updates and skewed access.
3. Set table properties for log retention (`delta.logRetentionDuration`) and deleted-file retention (`delta.deletedFileRetentionDuration`).
4. Schedule `OPTIMIZE` / clustering and `VACUUM` regularly.
5. Use MERGE for CDC-style upserts; deletion vectors keep this cheap.
6. Standardize on a catalog (Unity Catalog, Glue, or HMS) for governance.
## Key Patterns
### Create a Delta table (Spark)
```sql
CREATE TABLE events (
event_id BIGINT,
user_id BIGINT,
event STRING,
amount DECIMAL(18,4),
ts TIMESTAMP
)
USING DELTA
PARTITIONED BY (date_trunc('day', ts))
TBLPROPERTIES (
'delta.enableDeletionVectors' = 'true',
'delta.autoOptimize.optimizeWrite' = 'true',
'delta.autoOptimize.autoCompact' = 'true'
);
```
### MERGE upsert (CDC pattern)
```sql
MERGE INTO events t
USING staging_events s
ON t.event_id = s.event_id
WHEN MATCHED AND s._op = 'D' THEN DELETE
WHEN MATCHED AND s._op = 'U' THEN UPDATE SET *
WHEN NOT MATCHED AND s._op != 'D' THEN INSERT *;
```
### Time travel
```sql
SELECT * FROM events VERSION AS OF 137;
SELECT * FROM events TIMESTAMP AS OF '2026-04-15 00:00:00';
```
```python
# delta-rs
from deltalake import DeltaTable
DeltaTable("s3://lake/events", version=137).to_pyarrow_table()
```
### Optimize and vacuum
```sql
-- File compaction + Z-ORDER on common filter columns
OPTIMIZE events ZORDER BY (user_id, event);
-- Or Liquid Clustering (no fixed partitions, adaptive)
ALTER TABLE events CLUSTER BY (user_id, event);
OPTIMIZE events;
-- Reclaim space (default retention 7 days)
VACUUM events RETAIN 168 HOURS;
```
### Read from Polars / DuckDB
```python
import polars as pl
df = pl.read_delta("s3://lake/events", version=137)
```
```sql
INSTALL delta; LOAD delta;
SELECT * FROM delta_scan('s3://lake/events/');
```
### Streaming write (Spark Structured Streaming)
```python
from pyspark.sql.functions import col
(spark.readStream.format("kafka")
.option("subscribe", "events")
.load()
.selectExpr("CAST(value AS STRING) as raw")
.writeStream.format("delta")
.option("checkpointLocation", "s3://lake/_chk/events")
.outputMode("append")
.toTable("events_raw"))
```
### Restore a table to a previous version
```sql
RESTORE TABLE events TO VERSION AS OF 137;
```
## Common Pitfalls
- Running `VACUUM` with too short a retention window while readers still hold older snapshots — they break.
- Skipping `OPTIMIZE` on streaming-ingested tables — small-file explosion kills query times.
- Enabling deletion vectors on tables read by engines that don't yet support DV protocol — they read stale rows.
- Using two different writers without a coordinator/transactional metastore — concurrent commits can fail.
- Treating `_delta_log/` as opaque and editing files manually.
- Forgetting `mergeSchema = true` on writes that intentionally evolve the schema.
- Mixing partition-by-time on a column with very high cardinality — use Liquid Clustering instead.
## When to Use This Mode
- Lakehouse on Databricks, AWS, or any cloud with object storage
- CDC into a lakehouse with frequent updates/deletes (deletion vectors are the killer feature)
- Workloads that need time travel for debugging, reproducibility, or audit
- Streaming + batch sharing one source of truth
- Migrating from raw Parquet directories to a transactional table format