---
title: "Deploy RudderStack"
description: "Customer data platform that collects app events into your warehouse"
category: "Analytics"
url: https://railway.com/deploy/rudder-server
---

# Deploy RudderStack

Customer data platform that collects app events into your warehouse

**[Deploy RudderStack on Railway](https://railway.com/template/rudder-server)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/rudder-server/manifest.json

- **Creator:** A3A
- **Category:** Analytics
- **Total deploys:** 1

## Template content

### rudder-transformer https://cdn.jsdelivr.net/gh/gridalpha/rudderstack-railway@c8227df59baeefec898a50ac848556720e897af7/icons/rudderstack.svg

- **Image:** rudderstack/rudder-transformer:latest
- **Health check:** /health

### Postgres https://cdn.jsdelivr.net/gh/gridalpha/rudderstack-railway@c8227df59baeefec898a50ac848556720e897af7/icons/postgresql.svg

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

### statsd-exporter https://cdn.jsdelivr.net/gh/gridalpha/rudderstack-railway@c8227df59baeefec898a50ac848556720e897af7/icons/prometheus.svg

- **Image:** prom/statsd-exporter:latest
- **Health check:** /metrics

### rudder-server https://cdn.jsdelivr.net/gh/gridalpha/rudderstack-railway@c8227df59baeefec898a50ac848556720e897af7/icons/rudderstack.svg

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

### warehouse-db https://cdn.jsdelivr.net/gh/gridalpha/rudderstack-railway@c8227df59baeefec898a50ac848556720e897af7/icons/postgresql.svg

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

## Buckets

- **rudder-storage**

## Documentation

# Deploy and Host RudderStack on Railway

Deploy RudderStack to collect clickstream events from your websites, apps and servers and land them in a data warehouse you own. RudderStack is an open-source, warehouse-first customer data platform and the best-known self-hosted Segment alternative: its HTTP API and SDKs speak the same `identify` / `track` / `page` / `screen` / `group` calls, so existing instrumentation keeps working once you change the endpoint and write key. Teams self-host it when analytics data is too sensitive or too high-volume to send through a vendor.

This template runs the whole open-source stack. **rudder-server** is the public gateway: it authenticates events against a write key, queues them in **Postgres**, hands each to **rudder-transformer** for destination-specific shaping, writes batched load files to the **rudder-storage** bucket, and loads them into **warehouse-db**, a second Postgres that becomes your event warehouse. **statsd-exporter** exposes the pipeline's metrics in Prometheus format. Only rudder-server gets a public domain.

![Diagram of the RudderStack services deployed on Railway](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789570213/rudderstack-architecture.webp)

## Getting Started with RudderStack on Railway

There is no login screen and no admin account to create — RudderStack open source is a headless pipeline, configured entirely by this template's variables. When the deploy finishes, open the rudder-server URL at `/health`: a healthy deployment answers `"server": "UP"`, `"db": "UP"`, `"acceptingEvents": "TRUE"` and `"backendConfigMode": "JSON"`, the last confirming it runs from this configuration and not a hosted control plane. Visit `/docs` for the HTTP API reference, rendered by the server itself in eleven languages.

Your write key is the `RUDDER_WRITE_KEY` variable on rudder-server, generated at deploy time. Send it as HTTP Basic auth with an empty password:

```
curl -u "$RUDDER_WRITE_KEY:" -X POST \
  https://your-app.up.railway.app/v1/track \
  -H 'Content-Type: application/json' \
  -d '{"userId":"user-1","event":"Order Completed",
       "properties":{"order_id":"ORD-1","revenue":249.5,"currency":"USD"}}'
```

A correct key returns `200 ok`; a missing or wrong one returns `401`. Within a few minutes the warehouse sync creates the `rudder_events` schema in warehouse-db and a table per event name — `tracks`, `order_completed`, `identifies`, `users`, `pages` — with properties flattened into typed columns. Query it from Railway's Postgres data panel to confirm the round trip, then point your SDKs at the same URL and key.

![RudderStack HTTP API reference served by the deployed gateway](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789570216/rudderstack-http-api-reference.webp)

![Track endpoint documentation with its JavaScript SDK sample](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789570218/rudderstack-track-endpoint.webp)

![Live gateway health showing the pipeline accepting and routing events](https://res.cloudinary.com/rroe4rtk/image/upload/f_auto,q_auto/v1789570220/rudderstack-pipeline-health.webp)

## About Hosting RudderStack

A customer data platform sits between the places events happen and the places they are analysed. RudderStack inverts the usual model: the warehouse is the primary destination and every other tool is downstream of it. Self-hosted, events never leave your infrastructure and there is no per-event pricing.

Key features:

- Segment-compatible HTTP API and SDKs for web, iOS, Android, React Native, Node, Python, Go, Java and Ruby
- Warehouse-first loading into Postgres, Snowflake, BigQuery, Redshift and ClickHouse
- 200+ event-stream destinations, plus a JavaScript framework for transforming events in flight
- A durable retry layer, so a destination outage loses no events

The architecture mirrors how RudderStack splits work internally. rudder-server holds the gateway, processor, router and warehouse scheduler in one process — the shape upstream's own Helm chart deploys. Postgres is not the warehouse: it is the durable job queue, holding every event until every destination has accepted it. rudder-transformer is separate because destination logic changes far more often than the core server.

## Why Deploy RudderStack on Railway

Railway removes the infrastructure work self-hosting a data pipeline usually implies.

- Both Postgres databases and the S3-compatible bucket are provisioned and wired up for you
- Private networking keeps the transformer, queue, warehouse and metrics off the internet
- Health checks on every service, and a volume for in-flight event batches
- Scaling without a Kubernetes manifest
- One TLS public domain for your SDKs

## Common Use Cases

- **Replacing Segment** on a product that has outgrown per-MTU pricing, with no instrumentation rewrite
- **Building a customer data warehouse** where events sit beside billing and CRM tables
- **Meeting data-residency rules** by keeping events inside your own cloud account and region
- **Fanning one event stream out** to product analytics, a marketing tool, a webhook and the warehouse at once

## Dependencies for RudderStack

- **rudder-server** — [gridalpha/rudderstack-railway](https://github.com/gridalpha/rudderstack-railway), a thin layer over `rudderlabs/rudder-server:latest` that renders the workspace configuration from variables at boot
- **rudder-transformer** — `rudderstack/rudder-transformer:latest`, destination transformations
- **Postgres** — `ghcr.io/railwayapp-templates/postgres-ssl:18`, the job queue
- **warehouse-db** — the same image, as the event warehouse
- **statsd-exporter** — `prom/statsd-exporter:latest`, Prometheus metrics
- **rudder-storage** — object storage for staging and load files

### Environment Variables Reference

| Variable | Purpose |
|---|---|
| `RUDDER_WRITE_KEY` | The credential every SDK sends. Generated at deploy |
| `RUDDER_WAREHOUSE_NAMESPACE` | Schema the event tables land in. Default `rudder_events` |
| `RUDDER_WAREHOUSE_SYNC_FREQUENCY` | Minutes between warehouse loads. Default `5` |
| `RUDDER_WEBHOOK_URL` | Set to also POST every event to your own HTTPS endpoint |
| `NUM_PROCS` | Transformer worker processes. Raise with traffic |

### Deployment Dependencies

- [rudderlabs/rudder-server](https://github.com/rudderlabs/rudder-server), [rudderlabs/rudder-transformer](https://github.com/rudderlabs/rudder-transformer), [docs](https://www.rudderstack.com/docs/)

## Hardware Requirements for Self-Hosting RudderStack

| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU in total | 4+ vCPU |
| RAM | 2 GB total | 4–8 GB |
| Storage | 5 GB per Postgres, 1 GB volume | Grows with retention and volume |
| Runtime | Go, Node 22 | Provided by the images |

Throughput is bounded by the job queue more than the gateway: if it backs up, give Postgres more CPU and RAM before scaling rudder-server.

## Self-Hosting RudderStack

RudderStack open source has no self-hosted control plane, so the server reads its sources and destinations from a JSON workspace configuration file rather than an admin UI. A minimal local stack is three containers:

```
services:
  db:
    image: postgres:16-alpine
    environment: [POSTGRES_USER=rudder, POSTGRES_PASSWORD=pw, POSTGRES_DB=jobsdb]
  transformer:
    image: rudderstack/rudder-transformer:latest
  backend:
    image: rudderlabs/rudder-server:latest
    depends_on: [db, transformer]
    ports: ["8080:8080"]
    volumes: ["./workspaceConfig.json:/wc.json"]
    environment:
      - JOBS_DB_HOST=db
      - JOBS_DB_USER=rudder
      - JOBS_DB_PASSWORD=pw
      - JOBS_DB_DB_NAME=jobsdb
      - DEST_TRANSFORM_URL=http://transformer:9090
      - RSERVER_BACKEND_CONFIG_CONFIG_FROM_FILE=true
      - RSERVER_BACKEND_CONFIG_CONFIG_JSONPATH=/wc.json
```

Writing that configuration by hand is the awkward part — it needs matching source, destination and definition objects. The template's source repository generates it at boot from plain environment variables.

## Is RudderStack Free to Self-Host?

RudderStack's server is released under the Elastic License 2.0, which permits running it for your own data at no cost; the paid product is RudderStack Cloud, priced per monthly tracked user. Self-hosting has no licence fee and no event cap — you pay only for the Railway resources the services use. The licence does not allow offering RudderStack itself to third parties as a managed service.

## FAQ

**What is RudderStack?**
An open-source customer data platform. It collects behavioural events from your websites, apps and servers through Segment-compatible SDKs, then routes them to your data warehouse and to analytics and marketing tools.

**What does this Railway template deploy?**
Five services and a bucket: the rudder-server gateway on a public URL, rudder-transformer, a Postgres job queue, a second Postgres as the event warehouse, statsd-exporter for metrics, and object storage for staging files.

**Why does it need two Postgres databases?**
They do different jobs. The first is rudder-server's durable job queue — every event lands there on arrival and is deleted only once every destination has accepted it, which is what makes retries safe. The second is your warehouse, holding the event tables you query.

**Why is an object-storage bucket required?**
Warehouse loads go through files, not row-by-row inserts. rudder-server batches events into compressed load files in the bucket, then loads them one transaction per table, so a failed sync replays without duplicating rows.

**How do I add a destination like Amplitude or a webhook?**
Set `RUDDER_WEBHOOK_URL` to fan every event out to your own HTTPS endpoint. For the 200+ native destinations, fork the source repository and add the destination to `workspaceConfig.template.json`.



## 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/rudder-server
