Deploy Cube
Define your business metrics once and query them from any tool
cube-refresh-worker
Just deployed
cube-api
Just deployed
Just deployed
/var/lib/postgresql/data
cubestore
Just deployed
/cube/data
cubestore
Bucket
Just deployed
Deploy and Host Cube on Railway
Cube is an open-source semantic layer that sits between your database and everything that reads from it. You define metrics, dimensions and joins once in YAML, and Cube serves them to BI tools, dashboards, embedded charts and AI agents through a REST API, a GraphQL API and a Postgres-compatible SQL API. It exists to stop metric drift: when "revenue" is written as SQL in six dashboards, six teams eventually report six numbers. Cube makes that definition one versioned object, applies access control to it, and caches results so dashboards stop re-scanning the warehouse.
To self-host Cube this template runs the documented production shape, not one container. cube-api compiles the model and answers REST, GraphQL and SQL queries; it is the only service with a public domain. cube-refresh-worker runs the same image with the refresh flag set, so building pre-aggregations never competes with query traffic. cubestore is Cube Store, Cube's own columnar engine, holding the query queue, the cache and the pre-aggregations the worker materialises, on a volume that survives redeploys. Postgres is the data source, pre-loaded with a sample e-commerce dataset and a matching model, so the deployment answers real queries the moment it is live.

Getting Started with Cube on Railway
Deploy the template and wait for all four services to go green; cube-api seeds the sample dataset on its first boot. Cube Core runs in production mode, so there is no login page and no Playground — this deployment is an API, and every call must carry a JSON Web Token signed with your CUBEJS_API_SECRET using HS256. Mint one with any JWT library, then call /cubejs-api/v1/meta with an Authorization header: a healthy deployment answers with the catalogue of cubes, views, measures and dimensions your model defines. Next, POST a query to /cubejs-api/v1/load asking for sales.revenue grouped by sales.products_category and check the external field — true means Cube Store answered rather than Postgres, confirming the refresh worker built its pre-aggregations. For a BI tool, add a TCP proxy on port 15432 and point Tableau, Metabase, Superset or psql at the host Railway hands back, signing in with CUBEJS_SQL_USER and CUBEJS_SQL_PASSWORD. To use your own warehouse, repoint the CUBEJS_DB_* variables, set CUBE_SAMPLE_DATA to false and replace the model files in a fork of the source repository. /readyz and /livez stay open for uptime monitoring.



About Hosting Cube
Cube is a server, not a library. It reads a data model from disk, compiles it into SQL for whichever database you point it at, and exposes the result over several protocols at once. Self-hosting suits teams who treat metric definitions as version-controlled business logic, need a cache in front of an expensive warehouse, or cannot let data leave their own infrastructure.
- One model, four protocols — REST, GraphQL, the Postgres-wire SQL API and Cube's JavaScript client read the same definitions.
- Pre-aggregations — Cube materialises rollups into Cube Store and rewrites queries to hit them, turning warehouse scans into fast lookups.
- Views — a curated member set you expose to analysts and AI tools without exposing every underlying cube.
- Row-level security — the token's claims flow into a security context your model filters on, which is what makes multi-tenant embedding safe.
- Wide database support — Postgres, MySQL, ClickHouse, BigQuery, Snowflake, Databricks, Redshift and DuckDB among others.
The split matters under load: an API instance that also builds pre-aggregations stalls user queries while it does.
Why Deploy Cube on Railway
Railway removes the operational work around a four-service analytics stack:
- Private networking wires all four services together with no exposed ports.
- Only the API takes a public domain; cache and database stay off the internet.
- A persistent volume keeps pre-aggregations across deploys.
- Managed Postgres is provisioned, backed up and connected for you.
- Health checks and restart policies come configured on every service.
Common Use Cases
- A consistent metrics layer for BI — define revenue, churn and retention once, then let Metabase, Superset, Tableau and Excel read the same numbers.
- Embedded analytics in your own product — query the REST API from React or Vue, with per-tenant filtering enforced by the token, not the frontend.
- A governed interface for AI agents — expose curated views so a model asks for
sales.revenue by monthinstead of writing arbitrary SQL. - An acceleration cache over a costly warehouse — pre-aggregate the queries dashboards run and cut both latency and per-query billing.
Dependencies for Cube
- cubejs/cube (
latest) — the Cube API server and the refresh worker, from github.com/cube-js/cube. - cubejs/cubestore (
latest) — the columnar engine behind the cache, query queue and pre-aggregation storage. - PostgreSQL 18 — the data source, holding the sample schema the model queries.
- A persistent volume — mounted at
/cube/dataon Cube Store for its local replica and pre-aggregation storage.
Environment Variables Reference
| Variable | Service | Purpose |
|---|---|---|
CUBEJS_API_SECRET | api, worker | HS256 key every API token is signed with |
CUBEJS_CUBESTORE_HOST | api, worker | Private hostname of the Cube Store service |
CUBEJS_REFRESH_WORKER | worker | Makes that container build pre-aggregations only |
CUBEJS_DEV_MODE | api, worker | Must stay false; true disables token checks |
CUBEJS_SQL_USER, CUBEJS_SQL_PASSWORD | api | Credentials BI tools use on the SQL API |
CUBESTORE_REMOTE_DIR | cubestore | Where pre-aggregations persist on the volume |
Deployment Dependencies
- Source repository: github.com/cube-js/cube · Docs: cube.dev/docs
- Images: cubejs/cube, cubejs/cubestore
Hardware Requirements for Self-Hosting Cube
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU across the services | 4+ vCPU |
| RAM | 2 GB total | 4–8 GB, most of it for Cube Store |
| Storage | 5 GB volume | 10 GB+, sized to your pre-aggregations |
| Runtime | Node.js 20+, Docker | Docker |
Cube Store is the memory-hungry component; the API and refresh worker stay modest.
Self-Hosting Cube with Docker
A local run mounts a model directory and points Cube at a database, with docker run:
docker run -p 4000:4000 \
-v $(pwd)/model:/cube/conf/model \
-e CUBEJS_DB_TYPE=postgres \
-e CUBEJS_DB_HOST=host.docker.internal \
-e CUBEJS_DB_NAME=analytics \
-e CUBEJS_DB_USER=postgres \
-e CUBEJS_DB_PASS=secret \
-e CUBEJS_API_SECRET=change-me \
cubejs/cube:latest
Production adds Cube Store and a refresh worker, the shape this template deploys. A minimal cube in model/cubes/orders.yml is YAML:
cubes:
- name: orders
sql_table: public.orders
dimensions:
- name: id
sql: id
type: number
primary_key: true
measures:
- name: count
type: count
How Much Does Cube Cost to Self-Host?
Cube Core is open source under the Apache 2.0 licence and free at any scale, with no seat limits and no query metering. Cube Cloud is the commercial product, from around $40 per developer per month up to custom enterprise pricing for the hosted workbench, managed scaling and SSO. Self-hosting on Railway costs infrastructure only, and nothing per query.
FAQ
What is Cube? An open-source semantic layer. It turns metric definitions written in YAML into governed APIs over your existing database, so every dashboard, application and AI tool reads the same numbers.
What does this Railway template deploy? Four services: the Cube API, a refresh worker, Cube Store for caching and pre-aggregations, and a PostgreSQL database seeded with a sample dataset and matching model.
Why does the template include Cube Store and a separate refresh worker? Cube Store holds the query queue, the cache and the pre-aggregation tables, so without it production mode has nowhere to store rollups. The refresh worker builds them on a schedule, in its own container so long refreshes never slow live queries.
How do I authenticate against the self-hosted Cube API?
Every request needs an Authorization header carrying a JWT signed with CUBEJS_API_SECRET using HS256. Anonymous requests get 403, and there is no default account to change.
Can I connect Metabase, Superset or Tableau to Cube?
Yes. Add a TCP proxy on port 15432 and connect any Postgres client with CUBEJS_SQL_USER and CUBEJS_SQL_PASSWORD. Views appear as tables; measures are read with MEASURE().
Why is there no Playground on my deployment? The Playground exists only in development mode, which also turns off token verification. This template runs production mode, so the API is never open to the internet.
Template Content
cube-refresh-worker
gridalpha/cube-railwaycube-api
gridalpha/cube-railwaycubestore
gridalpha/cube-railwaycubestore
Bucket