Self-hosting Saiku
Saiku ships a self-hosted build under Apache 2.0 + EPL — the same build we run in Saiku Cloud. Every feature that’s in the OSS repository is in the self-hosted binary. No enterprise SKUs, no gated MCP tier, no Excel connector Cloud-only.
The trade-off is operational responsibility: you run the box, you handle updates, you own backups. This section is the current operator playbook.
Which build to grab
| Distribution | When to use it |
|---|---|
ghcr.io/spiculedata/saiku:development | Tracks the development branch — new features land here first. Best for evaluation and non-critical deployments. |
ghcr.io/spiculedata/saiku:4.6.2 (pin to a version) | Point at an immutable tag. Recommended for anything running in production. |
saiku-dist-<version>.zip from Releases | Java 21 runnable fat-JAR + run.sh/run.bat wrappers. For teams that don’t run Docker. |
Everything below assumes the Docker image; the fat-JAR flow is the same env vars + the same volume mounts, minus the container.
First boot
-
Pull the image and start it with a persistent
saiku-homevolume and an admin password. Saiku refuses to serve while the defaultadmin/admincredentials are unchanged, so set your password on the very first boot withSAIKU_ADMIN_PASSWORD:Terminal window docker volume create saiku-homedocker run -d --name saiku \--restart unless-stopped \-p 8080:8080 \-v saiku-home:/app/saiku-home \-e SAIKU_HOME=/app/saiku-home \-e SAIKU_ADMIN_PASSWORD='a-strong-password' \ghcr.io/spiculedata/saiku:4.6.2On first boot Saiku bcrypt-hashes it into
saiku-home/users.propertieson the volume. The env var is only needed the first time — it persists across restarts, so you can drop it (or leave it; re-supplying just re-applies the same password). -
Open http://localhost:8080/ui/ and log in as
adminwith the password you set. -
Add your first datasource at Admin → Connections. Postgres, MySQL, BigQuery, Snowflake, ClickHouse, DuckDB, MotherDuck, and H2 are wired out of the box.
Sizing
Rules of thumb, drawn from real deployments. Every dimension scales independently — most bottlenecks show up at the warehouse layer, not on the Saiku container.
| Deployment shape | RAM | CPU | JVM heap (-Xmx) |
|---|---|---|---|
| Evaluation / demo | 2 GB | 1 vCPU | 1 GB (default) |
| Small team (< 20 users) | 4 GB | 2 vCPU | 2 GB |
| Medium (20-100 users) | 8 GB | 4 vCPU | 4 GB |
| Large (100+ users) | 16 GB+ | 8 vCPU | 8 GB |
| Heavy AI workload | +50% RAM over base | +2 vCPU over base | Match the base |
Disk: /app/saiku-home grows with your workbook count and query
history retention. 20 GB is comfortable for most single-tenant
deployments; scale to 100 GB+ if you’re keeping years of audit
history.
JVM heap: set via -e JAVA_OPTS="-Xmx4g" on the docker run
line. Default heap is intentionally conservative — bump it if you
see OutOfMemoryError in saiku-home/logs/.
Upgrades
Saiku follows semver: 4.5.2 → 4.5.3 is
patch, 4.5 → 4.6 is minor, 4.x → 5.x is major. Minor and patch
upgrades are drop-in — pull the new image, restart the container,
your saiku-home volume carries every workbook and connection
through.
-
Snapshot the volume first (see Backups below — do this before every upgrade).
-
Stop the running container.
Terminal window docker stop saiku && docker rm saiku -
Pull the new tag and start it against the same volume.
Terminal window docker pull ghcr.io/spiculedata/saiku:4.5.3docker run -d --name saiku \--restart unless-stopped \-p 8080:8080 \-v saiku-home:/app/saiku-home \ghcr.io/spiculedata/saiku:4.5.3 -
Check the changelog for any migration notes on the version you just landed. Most releases have none; the load-bearing ones are called out explicitly at the top of the entry.
Rolling back is the reverse: docker pull an older tag, restart
against the same volume. Compatible as long as you haven’t crossed a
major version — the changelog flags the incompatible ones.
Backups
saiku-home holds everything worth backing up: connections,
workbooks, saved queries, users, audit history, tenant metadata.
Back it up on the same cadence as anything else in your data
platform.
Docker volume snapshot (simple):
# Oncedocker run --rm \ -v saiku-home:/data \ -v $(pwd):/backup \ alpine tar czf /backup/saiku-home-$(date +%F).tar.gz -C /data .
# Restoredocker run --rm \ -v saiku-home:/data \ -v $(pwd):/backup \ alpine tar xzf /backup/saiku-home-2026-07-10.tar.gz -C /dataScheduled backups (Linux cron):
0 2 * * * /usr/local/bin/saiku-backup.shWhere saiku-backup.sh runs the docker run --rm ... alpine tar ...
command above and rotates old archives (find /backup -mtime +30 -delete).
Off-box storage. The volume snapshot is a plain tarball — rsync it to S3, wasabi, or any object store on a schedule. Cross-region replication if you need it.
Point-in-time recovery requires a warehouse-side backup of the data Saiku queries. Saiku’s own state is small (metadata + saved queries); losing 24 hours of it is usually recoverable from the last backup + git-committed schema files.
Authentication
Out of the box, Saiku ships with in-memory auth backed by
users.properties — fine for evaluation, replace before
production. Three replacement paths, in increasing order of
integration effort:
- File-backed authoritative users. The admin password lives in
saiku-home/users.propertieson the volume (the launcher writes it there fromSAIKU_ADMIN_PASSWORDon first boot). Edit that file for a small flat-file setup with more accounts — entries areuser={bcrypt}$2y$...,ROLE_USER,ROLE_ADMIN; generate a hash withhtpasswd -nbBC 12 <user> '<password>'. To rotate the admin password later, re-run with a newSAIKU_ADMIN_PASSWORD, or edit the file directly and restart. Note the bundled store is read-only to the admin UI’s user-management screens — manage accounts in this file or move to one of the paths below. - LDAP / Active Directory. Standard Spring Security LDAP
config in
applicationContext-security-ldap.xml. See the LDAP wiring guide (link forthcoming). - SAML 2.0 SSO. Wired through Spring Security SAML. Wiring guide (link forthcoming).
- OAuth 2.0 / OIDC. Same story via Spring Security OIDC. Wiring guide (link forthcoming).
Saiku Cloud uses the SAML path with Auth0 as the IdP; the config is the same one that ships in the OSS build.
Observability
Saiku ships with opt-in OpenTelemetry — no data leaves the box unless you configure it. To turn it on, point the OTLP endpoint at your collector:
docker run -d --name saiku \ -e OTEL_EXPORTER_OTLP_ENDPOINT="https://otel-collector:4317" \ -e OTEL_SERVICE_NAME="saiku-prod" \ ghcr.io/spiculedata/saiku:4.6.2The Java agent auto-instruments:
- Jetty (HTTP request / response)
- Jersey (REST endpoints)
- JDBC (every SQL query to your warehouse — beware cardinality)
java.net.http.HttpClient(LLM provider calls, MCP outbound)- Log4j 2 (
trace_id/span_idin the MDC) - JVM metrics (heap, GC, threads)
- DBCP2 connection pool stats
Without the env var, the agent is never loaded. Zero overhead when observability is off.
Configuration
Every setting is a standard OpenTelemetry SDK environment variable — Saiku passes them straight through to the agent. The ones you’ll actually reach for:
| Variable | Default | Purpose |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | unset | OTLP collector URL. Setting this is what activates the agent. gRPC (:4317) or HTTP/protobuf (:4318). |
OTEL_EXPORTER_OTLP_PROTOCOL | grpc | grpc or http/protobuf — match your collector. |
OTEL_SERVICE_NAME | saiku | Service identifier in your tracing UI. |
OTEL_RESOURCE_ATTRIBUTES | unset | e.g. deployment.environment=prod,service.version=4.5.2. |
OTEL_METRICS_EXPORTER | otlp | otlp / prometheus / none. |
OTEL_EXPORTER_OTLP_HEADERS | unset | For SaaS collectors needing auth: api-key=…. |
OTEL_TRACES_SAMPLER | parentbased_always_on | Sampling strategy — see below. |
Sampling. The default captures every trace — right for the demo, wrong under load. For production, sample root traces:
export OTEL_TRACES_SAMPLER=parentbased_traceidratioexport OTEL_TRACES_SAMPLER_ARG=0.05 # 5% of root traces; children follow the rootLean to 1–5% for usage-billed SaaS backends; a self-hosted Tempo or Jaeger handles 25–100% comfortably at Saiku’s typical query volume.
When to escalate to Cloud
Self-hosted is the honest option for teams that can staff it. Rough thresholds where the Cloud economics start to win:
- You need multi-tenant isolation. Cloud’s tenant isolation (audit + billing + connection scope) is a substantial platform layer on top of the OSS build. Feasible to build yourself; not cheap.
- You need audit + SIEM integration you don’t want to run.
- You need SSO with SLAs. Self-host + Auth0 works, but if you don’t already have an IdP running, Cloud is faster than standing one up.
- You want SOC 2 without doing the compliance work. Cloud’s target is Q4 2026 (see the security posture page).
Getting help
- GitHub Discussions — public Q&A.
- GitHub Issues — bug reports.
- Enterprise support — SLA-backed, tiered by response time.
If you’re evaluating self-hosted vs Cloud and want a second opinion, book a 30-minute call — honest answers, no contract signing.