Skip to main content

DuckLess

PyPI Docs License

Documentation · Quickstart · Benchmarks · Releases · Contributing

Serverless DuckDB on GCP. Submit SQL or your own code; DuckLess runs it in your project on a right-sized machine (Cloud Batch VM with local SSD for spill, or Cloud Run Jobs for small jobs), reads and writes GCS with the job's own credentials (no HMAC keys), then tears it down. Nothing runs between jobs. Optional DuckLake tables on a Cloud SQL catalog, and Agent Skills for coding agents.

Status: v0.3, young and tested on real projects. Changes are listed in the GitHub Releases; the benchmarks have the measurements behind the design.

Quick start

uv tool install duckless                     # or: pip install duckless

duckless init --project my-project --region europe-west1
# prints the lines to put in .envrc (DUCKLESS_PROJECT, DUCKLESS_BUCKET, DUCKLESS_SA, DUCKLESS_IMAGE)

duckless preflight --machine n2-highmem-32 --spot
duckless run job.sql --machine n2-highmem-32 --spot
duckless exec --image <your-image> --machine n2-highmem-16 -- dbt build
duckless status <job-id>
duckless logs <job-id> --follow
duckless result <job-id>
duckless destroy --project my-project       # removes what init created

init applies the Terraform module shipped with the CLI (duckless/terraform) through Infrastructure Manager: no local Terraform, state kept in your project, re-run it to upgrade. Teams managing infra as code can use the same module directly instead.

Full guide: tosun-si.github.io/duckless, from the quickstart to the CLI reference.

Writing jobs

  • SQL (.sql): ${VAR} placeholders come from the job env (DUCKLESS_BUCKET, --env K=V).
  • Python (.py): from duckless_runtime import connect gives a DuckDB connection with GCS auth, spill on local SSD, memory and threads sized to the VM.
  • Write to GCS in parallel: COPY … TO 'gs://…' (FORMAT parquet, PER_THREAD_OUTPUT, FILE_SIZE_BYTES '256MB') is 7-8x faster than the single-writer default (~900 MB/s vs ~110 MB/s on 32 vCPU).
  • Vectorize Python logic: a row-wise Python UDF runs at ~8k rows/s on one thread; use an Arrow UDF over numpy (type="arrow") or SQL.

More in Writing jobs and Machines, Spot and spill.

Agent Skills

DuckLess ships a Claude Code plugin with five skills: setup, writing-jobs, sizing, troubleshooting and ducklake. They carry what the docs and the CLI cannot decide for you (which machine, why a job failed) and the rules measured while building DuckLess.

duckless skills install          # into this project: .claude/skills + .agents/skills (--user: your home)

Or as a Claude Code plugin, kept up to date from this repository:

/plugin marketplace add tosun-si/duckless
/plugin install duckless@duckless

Layout

Hexagonal, kept light: a pure core, ports, adapters, and one wiring point.

Path What
duckless/core/ Pure rules, no I/O: machine types and local SSD counts, job spec and planning, quotas, preflight
duckless/ports.py What the service needs from outside: Executor, ArtifactStore, LogReader, QuotaReader, InfraBootstrap, InfraDeployer (Protocols)
duckless/service.py Operations shared by the CLI, the SDK and later the SaaS control plane: functions taking ports as arguments
duckless/adapters/ GCP implementations: Cloud Batch, Cloud Run Jobs, GCS, Cloud Logging, Compute quotas, Infrastructure Manager
duckless/wiring.py Binds the service functions to the adapters (lazily)
duckless/cli.py duckless command, a driving adapter
runtime/ Runner image (duckless_runtime), published as ghcr.io/tosun-si/duckless-runner: DuckDB + gcs community extension, DuckLake + Cloud SQL Auth Proxy, tuned for the machine
duckless/terraform/ APIs, work bucket, least-privilege runner service account, Artifact Registry remote repository proxying the runner image, optional DuckLake catalog
duckless/plugin/ Claude Code plugin: the Agent Skills (duckless/plugin/skills/), listed by .claude-plugin/marketplace.json
spike/ The spike that validated the approach, kept as a record

Dependency rule: core imports nothing else from DuckLess, service only core and ports, and only wiring imports adapters.

Contributing

Issues and pull requests are welcome: bug reports, real use cases, docs, code. See CONTRIBUTING.md for the setup, the conventions and how changes are tested.

uv sync
uv run pytest
uv run ruff check . && uv run ruff format --check .

License

DuckLess is open source under the Apache License 2.0. You can use it, modify it and ship it, commercially or not; keep the license and the notices.

Metadata

Release files for duckless 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for duckless 0.3.1
File Size Uploaded
duckless-0.3.1.tar.gz 42.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for duckless 0.3.1
File Interpreter ABI Platform
duckless-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 102.5 kB

Release files / duckless-0.3.1.tar.gz

Download URL duckless-0.3.1.tar.gz
Size 42.6 kB
Tags Source
SHA-256 checksum
How to use checksums
c9d3fd26372ea9fd713111610c60923f8d0b4fced3cf80432762f420df459f33
BLAKE2b-256 checksum
How to use checksums
945e3154b6fcf63b8511b274ef270a0e3f1ae1ed8f4385cc1f244e04febd62cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / duckless-0.3.1-py3-none-any.whl

Download URL duckless-0.3.1-py3-none-any.whl
Size 59.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bf21d830400da4b50e95a2cd2b3384af36e191382f1a4838234e209de16388dc
BLAKE2b-256 checksum
How to use checksums
734bc20822846107e721ae8a729bef825fea408998d05ae312d7d7b2ef2fb7b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release 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