v4.0Time-travel joins · Changelog →

Realtime data, one command away.

Basalt turns Kafka topics, Postgres changes and webhooks into typed tables and APIs in milliseconds. Define it in SQL, ship it from the CLI, read it from anywhere.

~/acme-prod · zsh
eu-north-1
$ basalt source add payments --kafka payments.v3
✓ connected payments.v3 · 12 partitions · 1.28M ev/s
✓ schema inferred · 14 fields · 0.4 s
$ basalt view apply revenue.sql
✓ revenue_by_minute materialized · 812 ms
$ basalt deploy --region eu-north-1
✓ build 41c9e2 · 2 sources · 3 views · 9.4 s
✓ GET /v1/revenue_by_minute live · p99 3.1 ms
$
$ npx basalt initCopy
Events per second
1,284,301
p99 read
4.2 ms
Regions
38
Views served
61.4k
Uptime · 90 days
99.995%
Before and after

Seven systems, or one.

Without Basalt
The usual stack
KAFKAFLINKAIRFLOWDBTWAREHOUSEREDISAPIRETRYCRON 5MTTL 60SBACKFILL

A pipeline you babysit.

Every hop has its own config, its own retries and its own pager. Numbers drift between the cache and the warehouse, and nobody owns the gap.

7
Systems
4
Teams on call
2 h
Typical lag
With Basalt
One system
KAFKAPG CDCWEBHOOKAPIDASHBOARDMODELBASALT · 4.2 MS

A pipeline you deploy.

Sources, views and endpoints live in one project and ship with one command. The API, the dashboard and the model all read the same row.

1
System
0
Glue jobs
4.2 ms
End to end
Features

Six things you stop building yourself.

01
Ingest

Connect any stream.

Kafka topics, Streamtide shards, Postgres change streams, webhooks and SDK calls land in one ordered log. Retries are deduplicated, so every event counts once.

Kafka · Streamtide · PG CDC · Webhooks
02
SQL views

Views in plain SQL.

Write a SELECT and Basalt keeps it current with every event. Joins, windows and aggregates update incrementally, never as a nightly batch.

Postgres dialect · Incremental
03
Lineage

Trace any column back.

Every cell knows which events produced it. Click a number in the console and walk the path to the raw rows, column by column.

Column level · Built in
04
Time travel

Query any second.

Read a view as of any moment in the last 30 days. Debug an incident with the exact rows your API served at 02:14:07.

30 days on Scale · 1 year on Enterprise
05
Schemas

Fields change, nothing breaks.

Add or retype a field and Basalt versions the schema in place. Old readers keep working while new code picks up the change.

Versioned · Zero downtime
06
Autoscale

Partitions that split themselves.

Hot keys get their own partition and quiet ones merge back. Throughput follows traffic with no capacity planning or rebalancing jobs.

Up to 4M ev/s per project
SDKs

One pipeline, your language.

Typed SDKs for TypeScript, Python and Go, or plain SQL files the CLI deploys. Each tab below builds the same source, view and endpoint.

import { basalt } from "@basalt/sdk";

const db = basalt({ project: "acme-prod" });

await db.source("payments", { kafka: "payments.v3" });

await db.view("revenue_by_minute", `
  SELECT window(ts, '1m') AS minute, sum(amount) AS revenue
  FROM payments GROUP BY 1`);

const rows = await db.table("revenue_by_minute").last(3);
from basalt import Basalt

db = Basalt(project="acme-prod")

db.source("payments", kafka="payments.v3")

db.view("revenue_by_minute", """
  SELECT window(ts, '1m') AS minute, sum(amount) AS revenue
  FROM payments GROUP BY 1""")

rows = db.table("revenue_by_minute").last(3)
package main

import "github.com/basalt-dev/basalt-go"

func main() {
  db := basalt.New("acme-prod")
  db.Source("payments", basalt.Kafka("payments.v3"))
  db.View("revenue_by_minute", `
    SELECT window(ts, '1m') AS minute, sum(amount) AS revenue
    FROM payments GROUP BY 1`)
  rows, _ := db.Table("revenue_by_minute").Last(3)
}
-- views/revenue.sql · deploy with: basalt view apply
CREATE SOURCE payments FROM KAFKA 'payments.v3';

CREATE VIEW revenue_by_minute AS
SELECT window(ts, '1m') AS minute,
       sum(amount)        AS revenue
FROM payments
GROUP BY 1;

SELECT * FROM revenue_by_minute ORDER BY minute DESC LIMIT 3;
Result
revenue_by_minute
minute
revenue
2026-10-03 14:02
$48,210.40
2026-10-03 14:01
$51,377.15
2026-10-03 14:00
$46,902.88
3 rows · 3.1 ms · eu-north-1
Community

Built by people who ship.

We replaced a Flink job, two Airflow DAGs and a Redis cache with one SQL file. Our on-call rotation noticed before finance did.
Rowan Achebe
@rowan.ships
basalt deploy is the shortest path from a Kafka topic to an API I have ever used.
Sasha Moreau
@sashamoreau
Time travel made our incident review easy. We queried the fraud view as of 02:14:07 and saw exactly what the model saw at that second. No log archaeology, no guessing which cache was stale.
Emery Tanaka
@emerytk
The Go SDK reads like it was written by people who write Go.
Noor Haddad
@noorh
We moved 41 materialized views over in a weekend. Column lineage made the review boring, which is the best thing a review can be.
Quinn Halvorsen
@quinn_h
p99 holds at 3 ms from Reykjavík to Sydney. I stopped checking the dashboard.
Lake Adeyemi
@lakeadeyemi
Pricing

Start free. Pay as it flows.

Hobby

Free forever
$0 / mo

10M events a month, 3 views and community support. Enough for a side project that needs real streaming.

Start free

Scale

Most teams
$249 / mo

1B events included, unlimited views and sources, a 99.95% SLA and 30 days of time travel.

Start 14-day trial

Enterprise

Annual
Custom

Dedicated cells, VPC peering, SSO, a year of history and an engineer who knows your schema.

Talk to us
Get started

Set your data in stone.

Free up to 10M events a month. No card, no sales call. Your first pipeline is live in about four minutes.

Project reserved · check your inbox
That didn't go through · check the address and try again
2,400+ teams in productionSOC 2 Type II38 regions