TL;DR
Apache Superset connects to RisingWave using the standard PostgreSQL SQLAlchemy URI (postgresql+psycopg2://root@localhost:4566/dev). Once connected, any materialized view in RisingWave becomes a Superset dataset. Charts built on those datasets reflect streaming data automatically as RisingWave updates them, giving you genuinely live dashboards without scheduled ETL jobs or manual refreshes.
Why Superset + RisingWave?
Apache Superset is one of the most widely deployed open-source BI platforms. It supports dozens of database backends through SQLAlchemy, renders interactive charts and dashboards, and is actively maintained by the Apache Software Foundation. Most teams that need a self-hosted visualization layer choose Superset because it combines a rich UI with full control over data and deployment.
The problem with traditional Superset deployments is data freshness. Superset queries your database on demand, so the freshness of your charts is limited by how quickly data lands in your warehouse. If your pipeline runs once an hour, your "real-time" dashboard is an hour stale.
RisingWave changes that equation. As a streaming database, RisingWave maintains materialized views that update incrementally as events arrive. When Superset queries a RisingWave materialized view, it reads the latest computed results -- not a snapshot from the last ETL run. For data that matters in the moment (sales, operations, user activity), this difference is significant.
Why RisingWave is a natural Superset backend:
- PostgreSQL compatibility -- RisingWave exposes a PostgreSQL-compatible interface on port 4566. Superset connects via the standard
psycopg2driver with no extra configuration. - Always-current materialized views -- RisingWave updates views incrementally as new data arrives from Kafka, CDC, or other sources. Superset reads the result, not the raw stream.
- Standard SQL -- All charts and custom SQL queries in Superset work against RisingWave without modification.
- Low query latency -- Because results are precomputed and maintained, even complex aggregations answer in milliseconds.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Event Sources │
│ (Kafka topics, CDC from PostgreSQL/MySQL, REST APIs) │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ RisingWave │
│ ┌──────────────┐ ┌────────────────────────────────────┐ │
│ │ Sources │ → │ Materialized Views │ │
│ │ (ingestion) │ │ sales_by_region, event_counts, │ │
│ └──────────────┘ │ user_sessions, funnel_steps ... │ │
│ └────────────────────────────────────┘ │
│ PostgreSQL wire protocol, port 4566 │
└────────────────────────────┬────────────────────────────────┘
│ SQLAlchemy PostgreSQL URI
▼
┌─────────────────────────────────────────────────────────────┐
│ Apache Superset │
│ Datasets → Charts → Dashboards → Auto-refresh │
└─────────────────────────────────────────────────────────────┘
│
▼
Browser / Embedded Dashboards
Superset queries RisingWave directly. There is no intermediate data warehouse, no scheduled export job, and no cache that goes stale.
Step 1: Connect Superset to RisingWave
Prerequisites
- RisingWave running locally or in the cloud (default port: 4566)
- Apache Superset installed (Docker Compose or pip)
- Python driver
psycopg2-binaryavailable in Superset's Python environment
If you run Superset via Docker Compose, add psycopg2-binary to your requirements-local.txt and rebuild:
echo "psycopg2-binary" >> requirements-local.txt
docker compose build --no-cache superset
docker compose up -d
Adding the Database Connection
- Open Superset in your browser (default:
http://localhost:8088). - Go to Settings (top-right gear icon) -> Database Connections.
- Click + DATABASE.
- Select PostgreSQL from the database type list.
- In the SQLAlchemy URI field, enter:
postgresql+psycopg2://root@localhost:4566/dev
For RisingWave Cloud or a remote deployment, substitute the host, port, username, password, and database name:
postgresql+psycopg2://username:password@your-risingwave-host:4566/dev
- Click Test Connection. You should see "Connection looks good!"
- Click Connect to save.
What the URI Fields Mean
| Field | Value | Notes |
|---|---|---|
| Driver | psycopg2 | Standard PostgreSQL adapter |
| User | root | Default RisingWave user |
| Password | (empty) | No password in local dev |
| Host | localhost | Or your RisingWave host |
| Port | 4566 | RisingWave PostgreSQL port |
| Database | dev | Default database name |
Step 2: Create a Dataset from a Materialized View
In Superset, a dataset is the query-able object that charts are built on. You can create a dataset from any RisingWave table, materialized view, or custom SQL query.
Using a Materialized View as a Dataset
First, create a materialized view in RisingWave. This example tracks sales by region and product in real time:
CREATE TABLE sales (
product VARCHAR,
region VARCHAR,
amount DECIMAL,
sale_time TIMESTAMPTZ
);
INSERT INTO sales VALUES
('Widget A', 'US', 150.00, NOW() - INTERVAL '10 minutes'),
('Widget B', 'EU', 220.00, NOW() - INTERVAL '5 minutes'),
('Widget A', 'EU', 180.00, NOW() - INTERVAL '2 minutes');
CREATE MATERIALIZED VIEW sales_by_region AS
SELECT
region,
product,
SUM(amount) AS total,
COUNT(*) AS count
FROM sales
GROUP BY region, product;
-- Verified output:
-- region | product | total | count
-- --------+----------+--------+-------
-- EU | Widget A | 180.00 | 1
-- EU | Widget B | 220.00 | 1
-- US | Widget A | 150.00 | 1
In a real deployment, the sales table would be replaced by a source connected to Kafka or a CDC connector -- the materialized view definition stays the same.
Registering the Dataset in Superset
- Go to Datasets (top menu) -> + DATASET.
- Select your RisingWave database connection.
- Select schema
public. - Select the materialized view
sales_by_region. - Click ADD DATASET AND CREATE CHART.
Superset reads the column schema directly from RisingWave. The total and count columns are immediately available as metrics in the chart builder.
Using a Custom SQL Dataset
For more control, use a virtual dataset backed by a SQL query:
SELECT
region,
product,
SUM(amount) AS revenue,
COUNT(*) AS orders,
AVG(amount) AS avg_order_value,
MAX(sale_time) AS last_sale_at
FROM sales
GROUP BY region, product
ORDER BY revenue DESC
Virtual datasets let you build dashboards on any SQL expression that RisingWave supports, including window functions, joins across multiple materialized views, and time-series bucketing.
Step 3: Build a Live Dashboard
Creating Charts
From the dataset, click CREATE CHART and choose a visualization type. Common patterns for streaming data:
Bar chart -- revenue by region:
- Chart type: Bar Chart
- Metrics:
SUM(total) - Dimensions:
region
Pivot table -- product performance by region:
- Chart type: Pivot Table
- Rows:
region - Columns:
product - Metrics:
SUM(total),SUM(count)
Big Number -- total revenue:
- Chart type: Big Number with Trendline
- Metric:
SUM(total)
Time-series line chart -- events per minute: Assuming a materialized view with a time-bucketed column:
CREATE MATERIALIZED VIEW events_per_minute AS
SELECT
date_trunc('minute', ts) AS minute,
event_type,
COUNT(*) AS events
FROM events
GROUP BY date_trunc('minute', ts), event_type;
Use this as a dataset and build a line chart with minute on the X axis and events as the metric.
Assembling the Dashboard
- Go to Dashboards -> + DASHBOARD.
- Name your dashboard (e.g., "Live Sales Monitor").
- Click Edit Dashboard and drag charts onto the canvas.
- Arrange layout using the grid.
- Save the dashboard.
Refresh Strategies
Superset offers several options for keeping dashboards current. The right strategy depends on how often your underlying data changes and your acceptable staleness window.
Manual Refresh
The simplest approach: users click the refresh button. Works well for dashboards that are only occasionally consulted or where staleness of a few minutes is acceptable.
Auto-Refresh on the Dashboard
- Open the dashboard in view mode.
- Click the ... (ellipsis) menu in the top-right.
- Select Set auto-refresh interval.
- Choose an interval (10 seconds is the minimum).
With this setting, Superset re-issues all chart queries on the configured interval. Because RisingWave maintains materialized views incrementally, these queries are fast -- often sub-100ms even for complex aggregations.
Cache Configuration
Superset has a query result cache (backed by Redis by default). For dashboards powered by RisingWave materialized views, you typically want a short cache TTL or no cache at all, since the value of RisingWave is that results are already precomputed and fast to retrieve.
Configure this in superset_config.py:
# Short TTL for streaming data dashboards
CACHE_CONFIG = {
"CACHE_TYPE": "RedisCache",
"CACHE_DEFAULT_TIMEOUT": 10, # seconds
"CACHE_KEY_PREFIX": "superset_",
"CACHE_REDIS_URL": "redis://localhost:6379/0",
}
# Or disable caching entirely for maximum freshness
DATA_CACHE_CONFIG = {
"CACHE_TYPE": "NullCache",
}
Row-Level Security and Filters
For multi-tenant dashboards, Superset's Row Level Security rules apply directly to the SQL sent to RisingWave. This means you can filter materialized view results by user, team, or region without maintaining separate views per tenant.
Example: E-Commerce Live Sales Dashboard
Here is a complete example for an e-commerce operations team that wants a live view of sales activity.
RisingWave schema
-- In production, this comes from a Kafka source
CREATE TABLE orders (
order_id BIGINT,
customer_id BIGINT,
product VARCHAR,
region VARCHAR,
amount DECIMAL,
status VARCHAR,
created_at TIMESTAMPTZ
);
-- Running totals by region
CREATE MATERIALIZED VIEW orders_by_region AS
SELECT
region,
COUNT(*) AS total_orders,
SUM(amount) AS total_revenue,
AVG(amount) AS avg_order_value,
COUNT(DISTINCT customer_id) AS unique_customers
FROM orders
WHERE status = 'completed'
GROUP BY region;
-- Orders per 5-minute bucket (time-series)
CREATE MATERIALIZED VIEW orders_timeseries AS
SELECT
date_trunc('minute', created_at) -
(EXTRACT(MINUTE FROM created_at)::INT % 5) * INTERVAL '1 minute'
AS bucket,
region,
COUNT(*) AS orders,
SUM(amount) AS revenue
FROM orders
WHERE status = 'completed'
GROUP BY 1, region;
Superset dashboard panels
| Panel | Chart type | Dataset | Key metric |
|---|---|---|---|
| Revenue by Region | Bar Chart | orders_by_region | total_revenue |
| Order Volume | Big Number | orders_by_region | SUM(total_orders) |
| Orders Over Time | Line Chart | orders_timeseries | orders |
| Top Regions Table | Table | orders_by_region | All columns |
Set the dashboard auto-refresh to 30 seconds. Each refresh issues a single fast query against a precomputed materialized view -- no full table scan, no aggregation at query time.
Key Takeaways
- Apache Superset connects to RisingWave via the standard PostgreSQL SQLAlchemy URI -- no special driver or plugin required.
- Materialized views in RisingWave serve as always-fresh datasets for Superset charts.
- Dashboard auto-refresh at short intervals is practical because RisingWave's precomputed views answer queries in milliseconds.
- The combination replaces the traditional BI stack (warehouse + scheduled ETL + BI tool) with a leaner pipeline: event broker + RisingWave + Superset.
FAQ
Does Superset need a special driver for RisingWave?
No. Use psycopg2-binary, the standard PostgreSQL adapter. RisingWave's PostgreSQL compatibility handles the rest.
What SQLAlchemy URI do I use?
postgresql+psycopg2://root@localhost:4566/dev for a local RisingWave instance. Adjust host, port, user, password, and database name for other deployments.
Can I query materialized views directly in Superset's SQL Lab?
Yes. Open SQL Lab, select the RisingWave connection, and write any SQL against your materialized views, tables, or system catalog views.
How fresh is the data in a Superset chart?
Charts reflect the state of the materialized view at query time. RisingWave updates views incrementally as new events arrive -- typically within seconds of source data. The staleness is bounded by the Superset refresh interval, not by a batch ETL schedule.
Can I use Superset's Jinja templating against RisingWave?
Yes. Superset's {{ filter_values() }} and other Jinja macros are rendered before the query is sent to RisingWave, so they work as expected.
What happens if a materialized view is being updated while Superset queries it?
RisingWave provides snapshot isolation. Superset reads a consistent snapshot of the materialized view; ongoing updates do not cause partial reads.
What to Read Next
Ready to build your first live dashboard? Start RisingWave for free and connect Superset in under five minutes.

