Quickstart

DuckDB runtimeDownload PDF (2.8 MB)

This section takes you from nothing to a working job, dataset and notebook. You need a Groundzero site with at least one connection to a data source. The examples use an Amazon S3 connection named sales_s3 whose bucket, acme-retail-data, holds Parquet files of orders.

The orders files in these examples have the following columns.

Column Type Meaning
order_id BIGINT Unique order number
customer_id BIGINT Customer who placed the order
region VARCHAR Sales region, for example EMEA
amount DOUBLE Order value
status VARCHAR open, shipped or returned
ordered_at TIMESTAMP When the order was placed

Your first job#

An ETL job is a Python file that runs once. This job reads one day of orders from S3, computes revenue per region and writes the result back to S3 as Parquet.

python
from GZ.DuckDBUtils import duckSession

session = duckSession()

orders = session.readS3File(
    connName="sales_s3",
    bucketName="acme-retail-data",
    filePath="raw/orders/2026-09-30.parquet",
    fileType="parquet",
)
session.register("orders", orders)

revenue_sql = """
    SELECT region,
           count(*)               AS orders,
           round(sum(amount), 2)  AS revenue
    FROM orders
    WHERE status <> 'returned'
    GROUP BY region
    ORDER BY revenue DESC
"""

print(session.query(revenue_sql, returnFormat="pandas"))

session.writeS3File(
    connName="sales_s3",
    bucketName="acme-retail-data",
    filePath="curated/daily_revenue/2026-09-30.parquet",
    fileType="parquet",
    sourceQuery=revenue_sql,
)
session.close()

What happened:

  1. duckSession() created a DuckDB connection and attached every connector method to the returned session object.
  2. readS3File configured S3 access from the sales_s3 connection and returned a lazy DuckDB relation. No data was downloaded yet.
  3. register exposed the relation to SQL under the name orders.
  4. query ran the aggregation. With returnFormat="pandas" the result is materialized as a DataFrame. The print output appears in the job's log.
  5. writeS3File ran a COPY ... TO that streamed the result to S3.

To check it worked, open the job log for the printed table, then look for the new Parquet file under curated/daily_revenue/ in the bucket.

Keep data in DuckDB for as long as possible

Relations are lazy. Convert to pandas or Arrow only for the final step or when a library requires it. Doing joins and filters in SQL avoids copying data into Python memory.

Your first dataset#

A dataset runs your code and returns rows to the Groundzero UI, dashboards and APIs. Instead of writing files, you leave the rows you want to return in a variable called outputDF (or pass them to gz_output()).

python
from GZ.DuckDBUtils import duckSession

session = duckSession()

orders = session.readS3File(
    connName="sales_s3",
    bucketName="acme-retail-data",
    filePath="raw/orders/2026-09-30.parquet",
    fileType="parquet",
)
session.register("orders", orders)

outputDF = session.query(
    """
    SELECT region, status, count(*) AS orders, sum(amount) AS revenue
    FROM orders
    GROUP BY region, status
    ORDER BY region, status
    """
)

outputDF can be a DuckDB relation, a PyArrow table, record batch or reader, a pandas DataFrame, or a list of dictionaries. Groundzero converts it to JSON rows plus a schema, returns at most 100,000 rows, and pages the result for the UI.

Your first notebook#

In a notebook the runtime pre-imports numpy as np, pandas as pd, boto3, getClient and duckSession, so the first cell can start working immediately:

python
session = duckSession()
orders = session.readS3File("sales_s3", "acme-retail-data",
                            "raw/orders/2026-09-30.parquet")
orders.limit(5).df()

The notebook session stays alive until you stop it, and you cannot change the runtime while it runs.

In the UI#

You choose the runtime in the same control everywhere it appears. The control is a single-line field that shows the selected runtime name and, for non-Standard runtimes, a small badge with the compute name. Clicking it opens a panel with:

  • Runtime: a dropdown listing the runtimes your administrators have enabled for the site. It shows No RTEs Available if none are enabled.
  • Compute: a dropdown whose entries read Name | memory | cpu, one per compute size defined for the site. It shows Insufficient Permission if you cannot describe compute resources.
  • GPU Size and, for Spark only, Minimum Workers: numeric steppers.

Where the control appears:

Place Notes
Dataset designer In the editor toolbar. Standard is offered only for no connection or a single SQL connection; DuckDB and Spark need a compute.
ETL job editor In the toolbar next to Code. Choose DuckDB or Spark.
Notebook editor Locked while the session runs; hovering shows Stop the session to change compute.
Job scheduler A field labelled RTE that opens a Runtime and Compute menu; Save stays disabled until both are chosen.

If you run a dataset without a compute, the designer shows Please select Compute or Please select RTE and Compute.

DuckDB selected: Compute and GPU Size, with no Minimum Workers control.
DuckDB selected: Compute and GPU Size, with no Minimum Workers control.
A notebook before its session starts: choose a runtime, then Start session.
A notebook before its session starts: choose a runtime, then Start session.
Notebook runtime picker with duckdb and Medium compute.
Notebook runtime picker with duckdb and Medium compute.