Skip to content

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

DistributionWhen to use it
ghcr.io/spiculedata/saiku:developmentTracks 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 ReleasesJava 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

  1. Pull the image and start it with a persistent saiku-home volume and an admin password. Saiku refuses to serve while the default admin/admin credentials are unchanged, so set your password on the very first boot with SAIKU_ADMIN_PASSWORD:

    Terminal window
    docker volume create saiku-home
    docker 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.2

    On first boot Saiku bcrypt-hashes it into saiku-home/users.properties on 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).

  2. Open http://localhost:8080/ui/ and log in as admin with the password you set.

  3. 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 shapeRAMCPUJVM heap (-Xmx)
Evaluation / demo2 GB1 vCPU1 GB (default)
Small team (< 20 users)4 GB2 vCPU2 GB
Medium (20-100 users)8 GB4 vCPU4 GB
Large (100+ users)16 GB+8 vCPU8 GB
Heavy AI workload+50% RAM over base+2 vCPU over baseMatch 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.

  1. Snapshot the volume first (see Backups below — do this before every upgrade).

  2. Stop the running container.

    Terminal window
    docker stop saiku && docker rm saiku
  3. Pull the new tag and start it against the same volume.

    Terminal window
    docker pull ghcr.io/spiculedata/saiku:4.5.3
    docker run -d --name saiku \
    --restart unless-stopped \
    -p 8080:8080 \
    -v saiku-home:/app/saiku-home \
    ghcr.io/spiculedata/saiku:4.5.3
  4. 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):

Terminal window
# Once
docker run --rm \
-v saiku-home:/data \
-v $(pwd):/backup \
alpine tar czf /backup/saiku-home-$(date +%F).tar.gz -C /data .
# Restore
docker run --rm \
-v saiku-home:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/saiku-home-2026-07-10.tar.gz -C /data

Scheduled backups (Linux cron):

Terminal window
0 2 * * * /usr/local/bin/saiku-backup.sh

Where 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:

  1. File-backed authoritative users. The admin password lives in saiku-home/users.properties on the volume (the launcher writes it there from SAIKU_ADMIN_PASSWORD on first boot). Edit that file for a small flat-file setup with more accounts — entries are user={bcrypt}$2y$...,ROLE_USER,ROLE_ADMIN; generate a hash with htpasswd -nbBC 12 <user> '<password>'. To rotate the admin password later, re-run with a new SAIKU_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.
  2. LDAP / Active Directory. Standard Spring Security LDAP config in applicationContext-security-ldap.xml. See the LDAP wiring guide (link forthcoming).
  3. SAML 2.0 SSO. Wired through Spring Security SAML. Wiring guide (link forthcoming).
  4. 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:

Terminal window
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.2

The 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_id in 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:

VariableDefaultPurpose
OTEL_EXPORTER_OTLP_ENDPOINTunsetOTLP collector URL. Setting this is what activates the agent. gRPC (:4317) or HTTP/protobuf (:4318).
OTEL_EXPORTER_OTLP_PROTOCOLgrpcgrpc or http/protobuf — match your collector.
OTEL_SERVICE_NAMEsaikuService identifier in your tracing UI.
OTEL_RESOURCE_ATTRIBUTESunsete.g. deployment.environment=prod,service.version=4.5.2.
OTEL_METRICS_EXPORTERotlpotlp / prometheus / none.
OTEL_EXPORTER_OTLP_HEADERSunsetFor SaaS collectors needing auth: api-key=….
OTEL_TRACES_SAMPLERparentbased_always_onSampling strategy — see below.

Sampling. The default captures every trace — right for the demo, wrong under load. For production, sample root traces:

Terminal window
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.05 # 5% of root traces; children follow the root

Lean 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

If you’re evaluating self-hosted vs Cloud and want a second opinion, book a 30-minute call — honest answers, no contract signing.