← Overview

Orchestration and compute

Jobs and workflows that run on their own

A job is declared in a few fields, a workflow is assembled as a dependency graph, and scheduling is set without a single line of YAML. Every run executes in your Kubernetes, at the size you chose, and can be followed live.

A Spark run in the graal console: “En cours” status, “Agent” badge, job conso-regionale-daily triggered by Claude Code, 4 vCPU and 8 GiB of resources, attempt 1 of 3, and the log streaming line by line, including a Parquet file written to S3.A Spark run in the graal console: “En cours” status, “Agent” badge, job conso-regionale-daily triggered by Claude Code, 4 vCPU and 8 GiB of resources, attempt 1 of 3, and the log streaming line by line, including a Parquet file written to S3.

A run followed live: who triggered it, on which resources, at which attempt, and its logs line by line.

Real graal console interface, not retouched; fictional demonstration data (tenant energie-demo — people, projects and tokens are invented).

Key capabilities

Everything that runs, in one place

Every job type you need

Python, Spark, SQL, bash, notebooks, SAS and dbt, each in its own runtime image, with its libraries and secrets.

Workflows as graphs

You chain jobs of different types, set the dependencies, and each step retries on its own when it fails.

Cron, events and backfills

A cron expression, a file landing in a bucket, or a catch-up over a date range: every run knows its logical date.

Retries and alerts

Number of attempts and maximum duration per job; an alert goes out on failure or success, to the recipients you choose.

Distributed Spark

A driver and its workers, created for the run and removed after it, on your Kubernetes. No permanent Spark cluster to maintain.

GPUs and instance types

You pick an instance type per job, GPUs included. Project quotas cap what a run can request.

How it works

From code to scheduled run

  1. Step 01

    Declare the job

    A type, a code file, an image, an instance type. Parameters and secrets are injected by reference.

  2. Step 02

    Assemble and schedule

    You connect jobs into a workflow and pick the trigger: cron, event, or on-demand launch.

  3. Step 03

    Follow every run

    Live logs, step-by-step events, output files and metrics: every run keeps its record.

Every run is isolated

A run is born with its own containers, identity and network rules, and disappears with them. It only sees its project’s secrets and only reaches the destinations it is allowed to. Containers run without privileges, under Kubernetes’ restricted security profile.

Scheduling lives in graal

Cron schedules, triggers and workflows are handled by graal itself, not by one more scheduler to install. A schedule is changed in the console, through the API or by an agent, and takes effect at the next trigger.

Standards and integrations

Open engines

  • Kubernetes
  • Apache Spark
  • Python
  • bash
  • SQL
  • Trino
  • dbt
  • Jupyter
  • SAS
  • cron
  • GPU

Governance

Who runs what, at what cost

  • Separate permissions to create, launch and schedule, per project
  • vCPU, memory and GPU quotas checked before every run
  • Every run is attributed to a person or an agent, and its cost to the project

Frequently asked questions

Can we bring our existing jobs?

Yes. A Python script, a Spark job or a dbt project is uploaded as is; your job chains are rebuilt as workflows.

Do we need a separate Spark cluster?

No. Spark runs on your Kubernetes, sized run by run: a driver and its workers, then nothing.

What happens if a run fails at night?

It is retried as many times as planned. If it still fails, the alert goes out, and its logs are waiting for you in the console.

How do we recompute history?

With a backfill: you pick a date range, and graal creates one run per date, without duplicates, within the project’s quotas.

Schedule your first workflow

One job, a two-step workflow, a schedule: end to end, in a demonstration.