---
title: "Deploy RisingWave"
description: "RisingWave streaming DB on Railway: meta, compute, compactor, frontend"
category: "Analytics"
url: https://railway.com/deploy/risingwave
---

# Deploy RisingWave

RisingWave streaming DB on Railway: meta, compute, compactor, frontend

**[Deploy RisingWave on Railway](https://railway.com/template/risingwave)**

- **Creator:** A3A
- **Category:** Analytics

## Template content

### dashboard https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/caddy.svg

- **Source:** https://github.com/gridalpha/risingwave-railway
- **Health check:** /healthz
- **Public domain:** Yes

### compactor https://raw.githubusercontent.com/risingwavelabs/risingwave/v3.0.3/dashboard/public/risingwave.svg

- **Image:** risingwavelabs/risingwave:v3.0.3
- **Start command:** `/bin/sh -c 'case "$RW_META_ADDR" in ""|"http://:"*) RW_META_ADDR=http://meta.railway.internal:5690;; esac; export RW_META_ADDR; echo "rw-boot: meta at $RW_META_ADDR"; exec /risingwave/bin/risingwave compactor-node'`
- **Health check:** /metrics

### prometheus https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/prometheus.svg

- **Source:** https://github.com/gridalpha/risingwave-railway
- **Start command:** `/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.listen-address=[::]:9500 --storage.tsdb.retention.time=15d --storage.tsdb.retention.size=4GB`
- **Health check:** /metrics

### frontend https://raw.githubusercontent.com/risingwavelabs/risingwave/v3.0.3/dashboard/public/risingwave.svg

- **Source:** https://github.com/gridalpha/risingwave-railway
- **Start command:** `/bin/sh -c 'case "$RW_META_ADDR" in ""|"http://:"*) RW_META_ADDR=http://meta.railway.internal:5690;; esac; export RW_META_ADDR; case "$RW_PROMETHEUS_ENDPOINT" in ""|"http://:"*) RW_PROMETHEUS_ENDPOINT=http://prometheus.railway.internal:9500;; esac; export RW_PROMETHEUS_ENDPOINT; echo "rw-boot: meta at $RW_META_ADDR, prometheus at $RW_PROMETHEUS_ENDPOINT"; exec /usr/local/bin/rw-frontend-entrypoint.sh'`
- **Health check:** /metrics

### compute https://raw.githubusercontent.com/risingwavelabs/risingwave/v3.0.3/dashboard/public/risingwave.svg

- **Image:** risingwavelabs/risingwave:v3.0.3
- **Start command:** `/bin/sh -c 'case "$RW_META_ADDR" in ""|"http://:"*) RW_META_ADDR=http://meta.railway.internal:5690;; esac; export RW_META_ADDR; echo "rw-boot: meta at $RW_META_ADDR"; exec /risingwave/bin/risingwave compute-node'`
- **Health check:** /metrics

### Postgres https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgresql.svg

- **Image:** ghcr.io/railwayapp-templates/postgres-ssl:18

### meta https://raw.githubusercontent.com/risingwavelabs/risingwave/v3.0.3/dashboard/public/risingwave.svg

- **Image:** risingwavelabs/risingwave:v3.0.3
- **Start command:** `/bin/sh -c 'case "$RW_PROMETHEUS_ENDPOINT" in ""|"http://:"*) RW_PROMETHEUS_ENDPOINT=http://prometheus.railway.internal:9500;; esac; export RW_PROMETHEUS_ENDPOINT; exec /risingwave/bin/risingwave meta-node'`
- **Health check:** /metrics

## Buckets

- **risingwave-state**

## Documentation

![RisingWave logo](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTZ9qUhteN4xnBTBj8pI6Nu5W_P6acVI0spMnVDAERZfehwcHmHG7C4L4A&s=10)

# Deploy and Host RisingWave on Railway

RisingWave is an open-source streaming database that keeps SQL materialized views continuously up to date as events arrive. You write ordinary `CREATE MATERIALIZED VIEW` statements over Kafka topics, database change streams or tables you insert into, and it maintains the results incrementally rather than recomputing them per query. It speaks the PostgreSQL wire protocol, so any psql client, BI tool or driver can read those results — no new SDK, no Java operators.

Self-host RisingWave on Railway as a real distributed cluster rather than one all-in-one container. This template runs the four roles as separate services — meta, compute, compactor and frontend — alongside managed PostgreSQL for cluster metadata, an object storage bucket for streaming state, Prometheus scraping every role, and a Caddy gateway putting HTTP basic authentication in front of the dashboard. SQL clients reach the frontend over a TCP proxy; everything else stays private.

![Diagram of the seven RisingWave services deployed on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/v1788265868/risingwave-architecture.png)

## Getting Started with RisingWave on Railway

There are two entry points. The first is SQL: open the frontend service, copy its TCP proxy host and port from the Networking panel, and connect with any PostgreSQL client as `root` against database `dev`, using the password you set in `RW_ROOT_PASSWORD`. There are no default credentials to change — that password is applied on every boot, so the endpoint is never open.

The second is the dashboard: open the public URL of the `dashboard` service and sign in with `DASHBOARD_USERNAME` and `DASHBOARD_PASSWORD` for node health, live CPU and memory charts, the catalog of sources, tables and views, and a fragment graph per job.

Prove the engine end to end first. Connect with psql and run:

```
CREATE TABLE orders (id int PRIMARY KEY, region varchar, amount numeric);
CREATE MATERIALIZED VIEW revenue_by_region AS
  SELECT region, count(*) AS orders, sum(amount) AS revenue
  FROM orders GROUP BY region;
INSERT INTO orders VALUES (1,'emea',120.5),(2,'amer',310.25),(3,'apac',45.75);
FLUSH;
SELECT * FROM revenue_by_region ORDER BY revenue DESC;
```

Insert three more rows, run `FLUSH` and select again — the totals change without the view being rebuilt. From there point a real stream at it with `CREATE SOURCE ... WITH (connector = 'kafka', ...)` and build views on top. The dashboard's Materialized Views and Fragment Graph pages confirm the job is running.

![RisingWave cluster overview with live node CPU and memory charts](https://res.cloudinary.com/rroe4rtk/image/upload/v1788265871/risingwave-cluster-overview.png)
![Two RisingWave materialized views listed with their primary keys](https://res.cloudinary.com/rroe4rtk/image/upload/v1788265872/risingwave-materialized-views.png)
![Streaming fragment graph for the orders materialized view job](https://res.cloudinary.com/rroe4rtk/image/upload/v1788265874/risingwave-fragment-graph.png)

## About Hosting RisingWave

RisingWave separates compute from storage. Streaming state lives in object storage in a log-structured format called Hummock, cluster metadata lives in a SQL database, and the nodes doing the work hold only caches — which is why a node can be replaced without losing anything.

- PostgreSQL-compatible SQL surface, including `psql`, JDBC and most BI tools
- Incrementally maintained materialized views over streams and tables
- Connectors for Kafka, Redpanda, Pulsar, Kinesis, MySQL and PostgreSQL CDC, and S3
- Sinks back out to Kafka, Iceberg, PostgreSQL, Redis and object storage
- Sub-second freshness and second-scale recovery, since checkpoints sit in object storage
- A dashboard for cluster health, catalog browsing and job inspection

The role split matters when you scale. The **meta node** owns the catalog and schedules barriers. The **compute node** runs streaming operators and batch queries, and is where to add memory when views grow. The **compactor** merges storage files and scales with write volume. The **frontend** plans SQL and holds connections; stateless, so it is the safe place to add replicas.

## Why Deploy RisingWave on Railway

Railway removes the infrastructure work that surrounds a streaming database.

- Managed PostgreSQL for cluster metadata, provisioned and wired up automatically
- A managed object storage bucket for state, credentials injected as references
- Private networking, so only the SQL endpoint and dashboard are exposed
- A TCP proxy giving the PostgreSQL wire protocol a public endpoint
- Per-service scaling, so compute and compactor grow independently

## Common Use Cases

- **Real-time dashboards** reading pre-aggregated views instead of scanning raw events on every refresh
- **Streaming ETL** joining Kafka topics with database change streams and sinking the result into a warehouse or Iceberg table
- **Operational monitoring** built from windowed aggregations over application or IoT event streams
- **Feature serving** for machine learning, where features must reflect events from seconds ago

## Dependencies for RisingWave

- `risingwavelabs/risingwave:v3.0.3` — meta, compute and compactor, from [risingwavelabs/risingwave](https://github.com/risingwavelabs/risingwave)
- A thin layer on the same image for the frontend, applying the superuser password at startup
- `caddy:2-alpine` — basic authentication in front of the dashboard, which ships none of its own
- `prom/prometheus:v3` — scrapes all four roles so the dashboard's metric panels have data
- Railway PostgreSQL — metadata store holding the catalog and checkpoint bookkeeping
- Railway object storage — the Hummock state store for streaming state and checkpoints

### Environment Variables Reference

| Variable | Service | Purpose |
|---|---|---|
| `RW_ROOT_PASSWORD` | frontend | Password applied to the `root` superuser on every boot |
| `DASHBOARD_USERNAME` / `DASHBOARD_PASSWORD` | dashboard | Basic-auth credentials for the dashboard |
| `RW_SECRET_STORE_PRIVATE_KEY_HEX` | meta | Encrypts connector secrets at rest; must stay stable |
| `RW_STATE_STORE` | meta | Object storage URL for streaming state |
| `RW_LICENSE_KEY` | all roles | Optional key unlocking premium connectors |

### Deployment Dependencies

- Source code: [github.com/risingwavelabs/risingwave](https://github.com/risingwavelabs/risingwave)
- Image: [hub.docker.com/r/risingwavelabs/risingwave](https://hub.docker.com/r/risingwavelabs/risingwave)
- Docs: [docs.risingwave.com](https://docs.risingwave.com)

## Hardware Requirements for Self-Hosting RisingWave

Requirements are per service. Compute needs the headroom, since view state is cached in memory before spilling to object storage.

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU per role | 4+ on compute, 2 on compactor |
| RAM | 2 GB per role | 8 GB+ on compute, 4 GB on compactor |
| Storage | Object storage bucket | Object storage plus a Prometheus volume |
| Runtime | Linux container | Linux container |

Every RisingWave binary reads its container's CPU and memory limits directly, so parallelism and memory budgets retune themselves when you resize a service. Override them with `RW_PARALLELISM` and `RW_TOTAL_MEMORY_BYTES` only when you must.

## Self-Hosting RisingWave

For a local trial the single-node image needs only Docker:

```
docker run -it --pull=always -p 4566:4566 -p 5691:5691 \
  risingwavelabs/risingwave:v3.0.3 single_node
psql -h localhost -p 4566 -d dev -U root
```

A production cluster is the shape this template deploys: four processes sharing one metadata database and one bucket. Upstream ships a compose file:

```
git clone https://github.com/risingwavelabs/risingwave.git
cd risingwave/docker
docker compose -f docker-compose-distributed.yml up -d
```

Running that yourself means operating MinIO or S3, a PostgreSQL instance and the networking between the roles.

## Is RisingWave Free to Self-Host?

RisingWave Community Edition is open source under the Apache 2.0 licence, and the version this template deploys costs nothing to run. Some premium features — certain enterprise connectors, elastic disk caching — need a licence key from RisingWave Labs, and the cluster logs a clear message when one is gated. On Railway you pay only for the resources the services consume.

## FAQ

**What is RisingWave?**
A distributed SQL streaming database. It ingests event streams and change data, maintains materialized views over them incrementally, and serves the results over the PostgreSQL wire protocol.

**What does this Railway template deploy?**
Seven services — RisingWave meta, compute, compactor and frontend, Prometheus, a Caddy authentication gateway for the dashboard, and managed PostgreSQL — plus an object storage bucket.

**Why does the template include PostgreSQL and object storage?**
RisingWave stores cluster metadata in a SQL database and streaming state in object storage. That separation is what lets a node be replaced without data loss, and is not optional in a multi-node cluster.

**How do I connect to self-hosted RisingWave with psql?**
Use the frontend service's TCP proxy host and port, database `dev`, user `root`, and the password from `RW_ROOT_PASSWORD`. Any PostgreSQL 13-compatible client works.

**Is RisingWave a replacement for Apache Flink?**
For SQL-shaped streaming work it usually is, with far less operational overhead. Flink stays the better fit when you need custom Java operators or event-processing patterns RisingWave's SQL cannot express.

**Can I scale RisingWave on Railway?**
Yes. The frontend is stateless and safe to replicate, the compactor scales with write volume, and compute is where to add CPU and memory as view state grows.


## Similar templates

- [Typesense vs Meilisearch](https://railway.com/deploy/typesense-vs-meilisearch) — self-hosted Typesense vs Meilisearch
- [Betterlytics](https://railway.com/deploy/betterlytics) — Betterlytics is a cookieless analytics platform GDPR-compliant.
- [Finance Tracker](https://railway.com/deploy/finance-tracker-1) — Private multi-user household finance ledger with budgets and CSV import.

Open this page in a browser: https://railway.com/deploy/risingwave
