Skip to main content

DuckLess

Serverless DuckDB on GCP. Submit SQL or your own code; DuckLess runs it on a right-sized Compute Engine VM (Cloud Batch) in your project, reads and writes GCS through ADC (no HMAC keys), spills on local SSD, then tears the VM down. Nothing runs between jobs.

Status: early releases (v0.1.x). Changes are listed in the GitHub Releases; spike/README.md has 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.

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.

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 (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, GCS, Cloud Logging, Compute quotas
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, tuned for the VM
duckless/terraform/ APIs, work bucket, least-privilege runner service account, Artifact Registry remote repository proxying the runner image
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.

Development

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

License: Apache-2.0

Metadata

Release files for duckless 0.1.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.1.1
File Size Uploaded
duckless-0.1.1.tar.gz 25.5 kB Details

Built distribution (wheel)

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

Total release size: 61.3 kB

Release files / duckless-0.1.1.tar.gz

Download URL duckless-0.1.1.tar.gz
Size 25.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3f04c55c4c96eb68d041e0dc21b27303b144e4df6010a45274f172a2f9fa6bc4
BLAKE2b-256 checksum
How to use checksums
00bf7fcaaf37802dd1d85458e1ad6a68db5dee4dfde16764a91f782a27cd028d
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 6, 2026.

Transparency log

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

Download URL duckless-0.1.1-py3-none-any.whl
Size 35.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bfdede98727f14df49a66110955f52a36e89e6b28871d254ccb9b8c2bac443eb
BLAKE2b-256 checksum
How to use checksums
ab69e9b4d0c076a349d8d410ae772fd971b7678fe678623d90bb1a10f06b27b3
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 6, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.1 This release

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