How to Install ScyllaDB on Ubuntu 24.04 — Cassandra-Compatible NoSQL at Millions of Ops/sec
Modern workloads — ad tech pipelines, IoT telemetry, real-time personalization engines, fraud scoring, time-series telemetry — punish databases that were not designed for predictable sub-millisecond latency at high concurrency. ScyllaDB is a C++ rewrite of Apache Cassandra that uses a shard-per-core architecture, user-space task scheduling via the Seastar framework, and direct AIO disk access to deliver 10-50x higher throughput on the same hardware. This tutorial walks you through a production-ready install on an Ubuntu 24.04 VPS — from repository setup through the scylla_setup wizard, CQL shell bring-up, systemd tuning, monitoring, and cluster bootstrap.
Why this guide matters: The public ScyllaDB docs cover the happy path, but a real VPS install collides with kernel tuning, AIO limits, IO scheduler choice, and the fact that most small VPS plans lack the headroom ScyllaDB expects. This guide is written for a CloudCore Business VPS and calls out every place the defaults need adjustment.
Table of Contents
What Is ScyllaDB?
ScyllaDB is an open-source, distributed, wide-column NoSQL database that is wire-compatible with Apache Cassandra and (via the Alternator interface) with Amazon DynamoDB. It was designed from scratch in C++ around three principles:
- Shard-per-core architecture — Each CPU core owns a subset of the data and processes requests for that subset without locks. This eliminates contention on the JVM-style shared heap that bottlenecks Cassandra.
- Seastar runtime — A user-space task scheduler that polls for network and disk events without syscalls, avoiding the overhead of kernel thread context switches.
- Direct AIO on XFS — ScyllaDB bypasses the kernel page cache and manages its own memory, which is why
scylla_setupinsists on XFS and a tuned IO scheduler.
For application developers, the day-to-day experience is pure Cassandra: you use the CQL query language, the same driver ecosystem (Java, Python, Go, Rust, Node.js), the same replication strategies, and the same consistency levels. What changes is throughput, tail latency, and operational cost per operation.
Why Self-Host ScyllaDB on a VPS Instead of DBaaS?
Managed NoSQL services — DynamoDB, ScyllaDB Cloud, Cosmos DB, Bigtable — are attractive for teams that do not want to operate databases. But they trade convenience for real costs:
- Unpredictable pricing — DynamoDB's read/write capacity unit model penalizes bursty traffic. A 10x spike multiplies your bill by 10x, and on-demand mode is 7x more expensive per request than provisioned mode. Self-hosted ScyllaDB on a VPS costs the same whether you serve 1,000 req/sec or 100,000 req/sec.
- Egress fees — Reading data out of a managed DB to another cloud or to your own analytics pipeline incurs per-GB charges. A VPS plan with unmetered bandwidth makes this free.
- Tuning is locked down — You cannot change compaction strategy, replication factor, or consistency defaults on many DBaaS offerings. ScyllaDB on your own VPS exposes every knob.
- Vendor lock-in — DynamoDB data is hard to migrate out. ScyllaDB SSTables are standard Cassandra format, so you can move to self-hosted Cassandra, another ScyllaDB cluster, or a different provider without data conversion.
- Compliance — If you need to keep customer data in a specific country or under specific regulatory frameworks, you pick the VPS region. With DBaaS you inherit whatever the provider offers.
- Cost per GB stored — ScyllaDB Cloud and DynamoDB both charge roughly $0.25-$0.30/GB/month for data at rest. On a CloudCore Business VPS, you pay a flat rate for the full 200+ GB NVMe volume — an order of magnitude cheaper at any meaningful dataset size.
Cost Comparison at 500 GB, 10K ops/sec
| Scenario | ScyllaDB Cloud | AWS DynamoDB (provisioned) | Self-Hosted CloudCore Business |
|---|---|---|---|
| Monthly cost | ~$450/mo | ~$380/mo + storage + egress | EUR 29.99/mo |
| Egress (100 GB/mo) | Included | ~$9/mo | Free (unmetered) |
| Tuning freedom | Limited | Very limited | Full |
| Driver support | Cassandra-compatible | DynamoDB SDK only | Cassandra-compatible |
| Backups | Managed, extra cost | Managed | nodetool + rclone to S3 |
Prerequisites
- A VPS running Ubuntu 24.04 LTS (Noble Numbat) with root or
sudoaccess. - Minimum 4 vCPU, 8 GB RAM, 100 GB NVMe SSD. ScyllaDB will refuse to start in production mode on less — you would have to pass
--developer-mode 1which disables the performance optimizations that make ScyllaDB worth running. - AIO support — the default Ubuntu 24.04 kernel has this, do not replace it with a stripped-down container kernel.
- Open ports within your private network: 9042 (CQL), 19042 (CQL SSL), 7000 (internode), 7001 (internode SSL), 7199 (JMX), 10000 (REST API), 9180 (Prometheus).
- SSH access from your workstation.
Recommended Plan: CloudCore Business>
ScyllaDB's shard-per-core design means every additional vCPU directly increases throughput. For a production-grade single-node install or the first node of a cluster, we recommend the CloudCore Business plan:>
- 8 vCPU cores
- 24 GB RAM
- 200 GB NVMe SSD
- Unmetered bandwidth
- EUR 29.99/month>
The 8 cores give ScyllaDB 8 shards to parallelize across, 24 GB RAM lets the row cache absorb the hot working set, and the NVMe SSD provides the sustained IOPS ScyllaDB needs for compactions to keep up with ingestion. Smaller plans work for development but will push you into --developer-mode and mask production pitfalls.Connect to your server:
ssh root@your-server-ipStep 1: Prepare the System
Update the package index and apply pending security patches:
sudo apt update && sudo apt upgrade -yIf the kernel was upgraded, reboot:
sudo rebootInstall the baseline utilities ScyllaDB expects on the host:
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release \
software-properties-common net-tools wgetConfirm the kernel supports AIO (it will on any stock Ubuntu 24.04):
grep -i config_aio /boot/config-$(uname -r)Expected output:
CONFIG_AIO=yRaise the AIO limit if your VPS inherits a tight default:
echo "fs.aio-max-nr = 1048576" | sudo tee /etc/sysctl.d/99-scylla.conf
sudo sysctl --systemStep 2: Add the ScyllaDB Repository
ScyllaDB publishes Debian packages for each stable release. Use the ScyllaDB Open Source 6.2 line, which is the latest LTS-style release targeting Ubuntu 24.04.
Import the GPG key:
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://downloads.scylladb.com/deb/scylladb.gpg | \
sudo tee /etc/apt/keyrings/scylladb.gpg > /dev/nullRegister the repository:
sudo tee /etc/apt/sources.list.d/scylla.list > /dev/null <<'EOF'
deb [signed-by=/etc/apt/keyrings/scylladb.gpg] http://downloads.scylladb.com/deb/debian/scylladb-6.2 noble scylladb/multiverse
EOFRefresh the index:
sudo apt updateExpected output includes a line for the ScyllaDB repository:
Get:1 http://downloads.scylladb.com/deb/debian/scylladb-6.2 noble InRelease
...
Reading package lists... DoneStep 3: Install the Scylla Package
Install ScyllaDB itself plus the OpenJDK headless runtime that the Java-based management tools (nodetool, cqlsh in some builds, JMX agent) require:
sudo apt install -y scylla openjdk-17-jre-headlessThe install pulls down several hundred megabytes of binaries and their dependencies (scylla-server, scylla-tools, scylla-cqlsh, scylla-machine-image, scylla-node-exporter). Expect the install to take 1-2 minutes.
Verify the version:
scylla --versionExpected output (exact patch number may differ):
6.2.1-0.20251012.abcdef1234At this point the scylla-server systemd unit exists but is not yet started — the scylla_setup wizard must run first to apply kernel tuning and lay out data directories.
Step 4: Run the scylla_setup Wizard
scylla_setup is an interactive wizard that performs the one-time host tuning ScyllaDB needs to reach peak performance. It calls a series of sub-scripts that configure the data RAID (if multiple disks are present), benchmark the IO subsystem, tune kernel parameters, set up NTP via chrony, and enable CPU performance governors.
Launch it with:
sudo scylla_setupYou will be prompted through several questions. The recommended answers for a typical single-VPS install:
| Prompt | Recommended answer | Why |
|---|---|---|
| Do you want to run scylla_raid_setup? | yes (if multiple data disks) / no (single disk) | On a typical VPS with one NVMe disk, answer no. The setup will still format the target directory on the existing filesystem. |
| Path to mount point | /var/lib/scylla | Default. Leave unchanged. |
| Do you want to run scylla_io_setup? | yes | This benchmarks the disk and writes /etc/scylla.d/io.conf. Mandatory for production mode. |
| Do you want to run scylla_ntp_setup? | yes | Installs chrony. ScyllaDB's gossip protocol depends on accurate clocks across nodes. |
| Do you want to run scylla_coredump_setup? | yes | Routes core dumps to a dedicated directory. Invaluable for debugging. |
| Do you want to run scylla_sysconfig_setup? | yes | Tunes THP (transparent huge pages), swappiness, network stack, and file descriptor limits. |
| Do you want to run scylla_cpuscaling_setup? | yes | Pins the governor to performance, disabling dynamic frequency scaling. |
| Enable autostart at boot? | yes | Self-explanatory. |
| Enable fstrim? | yes | Periodic TRIM keeps NVMe write amplification low. |
--developer-mode. On a CloudCore Business plan this does not apply.Once complete, scylla_setup prints something like:
scylla_raid_setup: Skipped
scylla_io_setup: io_properties.yaml written
scylla_ntp_setup: chrony configured
scylla_sysconfig_setup: applied kernel tuning
scylla_cpuscaling_setup: governor set to performance
Setup completed. You can now start scylla-server.What scylla_io_setup actually writes
The IO benchmark produces /etc/scylla.d/io_properties.yaml:
disks:
- mountpoint: /var/lib/scylla
read_iops: 410000
read_bandwidth: 3921000000
write_iops: 185000
write_bandwidth: 1780000000These numbers are the measured ceiling of your disk. ScyllaDB uses them to size its internal IO queues so that compactions never starve reads. If you change disks later, rerun sudo scylla_io_setup to regenerate this file.
Step 5: Review and Edit scylla.yaml
The main configuration file lives at /etc/scylla/scylla.yaml. For a single-node install, the defaults are almost correct — but a few fields must be set explicitly for the node to start.
Open the file:
sudo nano /etc/scylla/scylla.yamlSet the following keys (search and edit in place):
cluster_name: 'production-cluster'
listen_address: 10.0.0.10 # your server's private/primary IP
rpc_address: 10.0.0.10 # same, for CQL clients
broadcast_address: 10.0.0.10
broadcast_rpc_address: 10.0.0.10
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "10.0.0.10" # for single-node, this IS the seed
endpoint_snitch: GossipingPropertyFileSnitchWhy each field matters:
cluster_name— Nodes refuse to gossip with any other node whosecluster_namediffers. Rename deliberately.listen_address/broadcast_address— The interface ScyllaDB binds to for internode traffic. On a VPS with a single interface, use the primary IP.rpc_address— The interface CQL clients connect to. Set to0.0.0.0to listen on all interfaces, but then protect the port with a firewall.seeds— The list of contact points new nodes use to discover the cluster. For a single node, the node is its own seed.endpoint_snitch—GossipingPropertyFileSnitchreads/etc/scylla/cassandra-rackdc.propertiesto determine the datacenter and rack name. This is the correct choice for almost every deployment;SimpleSnitchis only acceptable for throwaway dev.
/etc/scylla/cassandra-rackdc.properties:dc=dc1
rack=rack1Save and close.
Step 6: Start ScyllaDB and Verify the Node
Enable the service and start it:
sudo systemctl enable --now scylla-serverThe first startup takes 30-90 seconds because ScyllaDB initializes its row cache, memtables, and compaction manager. Stream the logs to watch:
sudo journalctl -u scylla-server -fYou are looking for a line that says:
Starting listening for CQL clients on 10.0.0.10:9042Once that appears, check cluster status with nodetool:
nodetool statusExpected output:
Datacenter: dc1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 10.0.0.10 242.34 KB 256 100.0% a1b2c3d4-e5f6-7890-abcd-1234567890ab rack1UN= Up, Normal. The node has joined the ring and is serving traffic.Tokens: 256= the default virtual node count, good for most deployments.Owns: 100.0%= this node owns the entire keyspace (expected for a single-node cluster).
curl -s http://localhost:10000/storage_service/release_version
curl -s http://localhost:9180/metrics | head -5The REST endpoint returns the version string. The metrics endpoint returns Prometheus-format metrics.
Step 7: Connect with cqlsh
cqlsh is the interactive shell for running CQL statements:
cqlsh 10.0.0.10 9042You should see:
Connected to production-cluster at 10.0.0.10:9042
[cqlsh 6.2.1 | Scylla 6.2.1-0 | CQL spec 3.3.1 | Native protocol v4]
Use HELP for help.
cqlsh>Create a keyspace using NetworkTopologyStrategy (the production-appropriate replication strategy — SimpleStrategy is dev-only):
CREATE KEYSPACE demo
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 1
};For a multi-node cluster set the factor to 3 or higher. For now 1 is correct because there is only one node.
Create a table modeling a simple IoT time-series:
USE demo;
CREATE TABLE sensor_readings ( sensor_id UUID, bucket_hour TIMESTAMP, reading_time TIMESTAMP, temperature_c DOUBLE, humidity_pct DOUBLE, PRIMARY KEY ((sensor_id, bucket_hour), reading_time) ) WITH CLUSTERING ORDER BY (reading_time DESC) AND compaction = {'class': 'TimeWindowCompactionStrategy', 'compaction_window_unit': 'HOURS', 'compaction_window_size': 1};
Insert a row:
INSERT INTO sensor_readings (sensor_id, bucket_hour, reading_time, temperature_c, humidity_pct)
VALUES (uuid(), '2026-04-16 10:00:00+0000', toTimestamp(now()), 22.5, 48.2);Query it back:
SELECT * FROM sensor_readings LIMIT 5;Exit with exit or Ctrl+D.
Design note: The composite partition key(sensor_id, bucket_hour)bounds the partition size, which is critical in wide-column stores. Unbounded partitions (for example, using onlysensor_idas the partition key) will eventually blow past the recommended 100 MB partition size and wreck tail latency.TimeWindowCompactionStrategyis specifically tuned for time-series and dramatically reduces write amplification versus the defaultSizeTieredCompactionStrategy.
Step 8: Tune systemd Limits
ScyllaDB's shipped systemd unit already sets generous limits, but a few adjustments make sense for VPS deployments.
Check the current unit:
systemctl cat scylla-serverCreate a drop-in override for any customizations:
sudo mkdir -p /etc/systemd/system/scylla-server.service.d
sudo tee /etc/systemd/system/scylla-server.service.d/override.conf > /dev/null <<'EOF'
[Service]
Raise file descriptor limit if running with many client connections
LimitNOFILE=1048576
Ensure the service can lock memory (Scylla uses mlockall on startup)
LimitMEMLOCK=infinity
Optional: pin to a cgroup slice for resource accounting alongside other services
Slice=database.slice
Graceful shutdown: give nodetool drain + flush up to 5 minutes
TimeoutStopSec=300
EOFReload and restart:
sudo systemctl daemon-reload
sudo systemctl restart scylla-serverConfirm the overrides are active:
systemctl show scylla-server | grep -E 'LimitNOFILE|LimitMEMLOCK|Slice|TimeoutStopSec'Install the Scylla node exporter
The Prometheus node_exporter exposes host-level metrics (CPU, memory, disk, network). Scylla ships a packaged version:
sudo apt install -y scylla-node-exporter
sudo systemctl enable --now scylla-node-exporterConfirm it is listening on port 9100:
curl -s http://localhost:9100/metrics | head -5These metrics pair with ScyllaDB's own :9180 endpoint to drive the monitoring dashboards in the next step.
Step 9: Deploy the Monitoring Stack
ScyllaDB publishes the scylla-monitoring stack — a Docker Compose bundle of Prometheus, Alertmanager, Grafana, and a set of battle-tested dashboards. Deploy it on the ScyllaDB host itself (fine for single-node) or on a dedicated observability VPS (recommended for multi-node production).
Install Docker and Compose if not already present (see our Docker installation guide for full instructions):
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USERLog out and back in so group membership takes effect, then clone the monitoring repo:
cd /opt
sudo git clone https://github.com/scylladb/scylla-monitoring.git
cd scylla-monitoring
sudo git checkout scylla-monitoring-4.9 # match your Scylla major versionEdit prometheus/scylla_servers.yml to point at your node:
- targets:
- 10.0.0.10
labels:
cluster: production-cluster
dc: dc1And prometheus/node_exporter_servers.yml:
- targets:
- 10.0.0.10:9100
labels:
cluster: production-cluster
dc: dc1Start the stack:
sudo ./start-all.sh -v 6.2After 30 seconds Grafana is reachable at http://your-server-ip:3000 (default login admin/admin). You get out-of-the-box dashboards for:
- Overview — cluster health at a glance
- Detailed — per-shard read/write latency percentiles
- CQL — prepared statement hit rate, protocol errors
- OS — CPU, RAM, disk, network from node_exporter
- Alternator — DynamoDB-compatible API metrics if you use that interface
- Advanced — compaction throughput, hinted handoff queue depth, commitlog
Step 10: Bootstrap a Multi-Node Cluster
Single-node ScyllaDB is fine for development, but production needs at least 3 nodes with replication factor 3 to survive one-node failures without data loss. Here is how to add a second and third node to the cluster.
On node 2 and node 3, repeat Steps 1 through 5 (install, scylla_setup, edit scylla.yaml). In scylla.yaml on the new nodes:
cluster_name: 'production-cluster' # MUST match node 1
listen_address: 10.0.0.11 # node 2's IP
rpc_address: 10.0.0.11
broadcast_address: 10.0.0.11
broadcast_rpc_address: 10.0.0.11
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
- seeds: "10.0.0.10" # points at node 1
endpoint_snitch: GossipingPropertyFileSnitchDo not list node 2 as its own seed. Seeds are the bootstrap contact points — a joining node must gossip with an existing node.
Start scylla-server on node 2:
sudo systemctl enable --now scylla-serverWatch the logs on node 2 for:
JOINING: waiting for ring information
JOINING: schema complete, bootstrapping
JOINING: Starting to bootstrap
JOINING: Bootstrap completedFrom node 1, verify the new node joined:
nodetool statusExpected output now shows two UN lines. Repeat for node 3.
Update the keyspace replication factor
After all three nodes are up, increase the replication factor from 1 to 3:
ALTER KEYSPACE demo
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3
};Run nodetool repair on every node to stream data to the new replicas:
nodetool repair --full demoThis is a one-time operation. Going forward, the driver's consistency level (QUORUM, LOCAL_QUORUM, etc.) handles replica coordination automatically.
Backups with nodetool snapshot
ScyllaDB snapshots are the foundation of backup. They use filesystem hard links, so creating a snapshot costs almost nothing in disk space or IO — the snapshot becomes expensive only when the underlying SSTables are later compacted, triggering a copy-on-write.
Take a snapshot
nodetool snapshot --tag pre-migration-2026-04-16 demoExpected output:
Requested creating snapshot(s) for [demo] with snapshot name [pre-migration-2026-04-16]
Snapshot directory: pre-migration-2026-04-16The snapshot appears under each table's directory:
/var/lib/scylla/data/demo/sensor_readings-<uuid>/snapshots/pre-migration-2026-04-16/Ship snapshots off-box
Use rclone or restic to push the snapshot to object storage. Example with rclone to Backblaze B2:
sudo apt install -y rclone rclone config # configure a B2 remote called "b2"BUCKET="scylla-backups-prod" HOST=$(hostname) DATE=$(date -u +%Y-%m-%dT%H-%M-%SZ)
rclone sync --transfers 8 --checkers 16 \ /var/lib/scylla/data/demo \ b2:$BUCKET/$HOST/$DATE/demo \ --include "/snapshots/pre-migration-2026-04-16/"
Schedule it with a systemd timer (create /etc/systemd/system/scylla-backup.timer and the matching .service, enabled with systemctl enable --now scylla-backup.timer).
Prune old snapshots
Local snapshots do not auto-expire. Clear them after they are safely off-box:
nodetool clearsnapshot -t pre-migration-2026-04-16 demoOr all snapshots of a keyspace:
nodetool clearsnapshot demoRestore a snapshot
Stop the node, copy snapshot files back into the table's directory, refresh with nodetool refresh:
sudo systemctl stop scylla-server
cp -a /backup/snapshots/pre-migration-2026-04-16/* /var/lib/scylla/data/demo/sensor_readings-<uuid>/
sudo systemctl start scylla-server
nodetool refresh demo sensor_readingsFor production disaster recovery, the Scylla Manager (free for up to 5 nodes) automates snapshot scheduling, upload to S3/GCS/B2, and point-in-time restore. Install it on a separate host from your ScyllaDB nodes.
Multi-Datacenter Considerations
ScyllaDB's topology awareness shines when you replicate across geographic regions for disaster recovery or latency reduction. The mechanics:
- Each datacenter gets its own
dc=label incassandra-rackdc.propertieson every node in that DC. NetworkTopologyStrategyaccepts per-DC replication factors, e.g.{'dc1': 3, 'dc2': 3}.- Clients use
LOCAL_QUORUMto read/write with quorum within their local DC only, avoiding cross-region latency on the hot path. - Asynchronous cross-DC replication happens in the background — writes are applied locally first, then streamed to remote DCs.
Latency budget
A read at LOCAL_QUORUM stays under 5 ms even with cross-region replication, because the coordinator only waits for local replicas. Cross-DC traffic is bounded by your VPS provider's backbone — typically 20-80 ms between European DCs, 100-150 ms across the Atlantic.
Firewall rules for multi-DC
Internode TCP 7000 (or 7001 for SSL) must be reachable between all nodes in all DCs. If you are crossing providers or regions, a WireGuard mesh or Tailscale is the simplest way to build a trusted private network — see our WireGuard setup guide.
Enabling internode encryption
For cross-DC traffic over the public internet, enable server_encryption_options in scylla.yaml:
server_encryption_options:
internode_encryption: all
certificate: /etc/scylla/conf/node.crt
keyfile: /etc/scylla/conf/node.key
truststore: /etc/scylla/conf/ca.crt
require_client_auth: trueGenerate certificates per node with your CA of choice (cfssl, step-ca, HashiCorp Vault PKI). Restart all nodes in a rolling fashion — one at a time, waiting for nodetool status to show UN before moving to the next.
Benchmarking with cassandra-stress
ScyllaDB ships with a fork of the Apache Cassandra stress tool. Use it to validate your install delivers the expected throughput before pointing production traffic at it.
sudo apt install -y scylla-toolsWrite test
Insert 1 million rows with 10 concurrent threads:
cassandra-stress write n=1000000 cl=QUORUM \
-rate threads=50 \
-node 10.0.0.10 \
-schema "keyspace=stress_test replication(factor=3)"Expected output after ~10-30 seconds on a Business-plan node:
Results:
Op rate : 38,452 op/s [WRITE: 38,452 op/s]
Partition rate : 38,452 pk/s [WRITE: 38,452 pk/s]
Row rate : 38,452 row/s [WRITE: 38,452 row/s]
Latency mean : 1.3 ms [WRITE: 1.3 ms]
Latency median : 0.9 ms [WRITE: 0.9 ms]
Latency 95th percentile : 3.5 ms [WRITE: 3.5 ms]
Latency 99th percentile : 8.2 ms [WRITE: 8.2 ms]
Latency 99.9th percentile : 24.1 ms [WRITE: 24.1 ms]
Latency max : 127.4 ms [WRITE: 127.4 ms]
Total partitions : 1,000,000
Total errors : 0
Total GC count : 0Mixed read/write test
The realistic workload:
cassandra-stress mixed ratio\(write=1,read=3\) n=1000000 cl=QUORUM \
-rate threads=100 \
-node 10.0.0.10If your numbers are dramatically lower (e.g. < 10k ops/sec on Business hardware), look for:
developer-modeaccidentally enabled — check/etc/scylla.d/dev-mode.conf- Wrong IO scheduler — should be
noneormq-deadline, check withcat /sys/block/nvme0n1/queue/scheduler - Noisy neighbor on shared VPS — run
iostat -xm 2during the benchmark and check disk await times - NTP drift —
chronyc trackingshould show offset under 1 ms
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
Could not setup Async I/O: Resource temporarily unavailable on start | AIO limit too low | echo 1048576 \</td><td>sudo tee /proc/sys/fs/aio-max-nr<code>, make permanent in </code>/etc/sysctl.d/99-scylla.conf |
Cluster name mismatch in logs | Joining node has different cluster_name than seeds | Fix cluster_name in scylla.yaml, then nodetool drain, stop service, clear /var/lib/scylla/data/system/peers, start again |
No keyspace has been specified in cqlsh | Expected — run USE <keyspace>; first | Specify keyspace at connection: cqlsh -k demo 10.0.0.10 |
Node stuck in JOINING state | Seed unreachable, or streaming failed | Check network with nc -zv 10.0.0.10 7000, inspect nodetool netstats for streaming progress |
FailedToLoadTokens on start | Corrupt system keyspace | Last resort on a non-production node: systemctl stop scylla-server && rm -rf /var/lib/scylla/data/system/ && systemctl start scylla-server (this wipes data) |
| 100% CPU on one shard | Hot partition (a single partition receiving disproportionate traffic) | Check nodetool toppartitions <keyspace> <table> 10000, redesign partition key |
| Compaction backlog grows unbounded | Write rate exceeds compaction throughput | Increase compaction_throughput_mb_per_sec in scylla.yaml, or add nodes |
Disk error: No space left on device | SSTables + commitlog filled disk | Attach additional volume, move /var/lib/scylla/data or enable TWCS for time-series tables to age out old data |
Reading logs effectively
# Live stream
sudo journalctl -u scylla-server -fLast 500 lines, no pager
sudo journalctl -u scylla-server -n 500 --no-pagerErrors only since boot
sudo journalctl -u scylla-server -b -p errKey nodetool commands
nodetool status— ring membership and ownershipnodetool info— load, uptime, heap, key cachenodetool tablestats <keyspace>— per-table read/write counts, SSTable countnodetool compactionstats— pending compactionsnodetool netstats— streaming progress during bootstrap or repairnodetool tpstats— thread pool stats, watch for dropped mutationsnodetool drain— flush memtables and stop gossiping; use before stopping the service cleanly
FAQ
Is ScyllaDB really Cassandra-compatible?
Yes. ScyllaDB implements the Apache Cassandra protocols (CQL binary protocol v4/v5, native Thrift in older versions), the SSTable on-disk format, and the nodetool management surface. Applications written for Cassandra drivers generally work unchanged by simply pointing them at ScyllaDB. Replication strategies, consistency levels, secondary indexes, materialized views, and lightweight transactions all behave the same way. The small set of Cassandra features not supported in ScyllaDB (e.g. triggers, some older CQL syntax) are documented in the ScyllaDB Cassandra parity matrix.
How much RAM does ScyllaDB need?
For production single-node workloads, we recommend a minimum of 8 GB RAM and 4 cores. ScyllaDB's shard-per-core architecture scales almost linearly with available hardware, so 16-32 GB RAM and 8+ vCPUs deliver dramatically better throughput. The CloudCore Business plan at EUR 29.99/month is the practical starting point — anything smaller forces scylla_setup into --developer-mode which disables performance optimizations like memory locking, CPU pinning, and AIO-based disk access.
Can I run ScyllaDB on a single node?
Yes. ScyllaDB runs as a single-node deployment for development, staging, or low-criticality production workloads. You lose replication-based fault tolerance, so pair single-node setups with frequent nodetool snapshot backups shipped off-box. For production workloads where data loss is unacceptable, run at least three nodes with replication factor 3, spread across three separate failure domains (different VPS hosts, ideally different racks or availability zones).
Why self-host ScyllaDB instead of using ScyllaDB Cloud or DynamoDB?
Self-hosting on a VPS gives you a flat monthly cost regardless of read/write volume, full control over replication topology and compaction strategy, no per-request or per-GB egress fees, and zero vendor lock-in. A ScyllaDB Cloud cluster of equivalent capacity typically costs 5-10x more than an equivalently sized VPS fleet. You also avoid the read/write capacity unit model that makes DynamoDB pricing unpredictable at scale. The downside is that you operate the database yourself — if you lack Cassandra/ScyllaDB operational experience, budget time for learning compactions, repairs, and backup restoration.
How do I back up ScyllaDB safely?
Use nodetool snapshot to create a hard-linked, consistent snapshot of the SSTable files for a keyspace or table. Snapshots are effectively free because they use filesystem hard links. Then rsync or use restic/rclone to ship the snapshot directory to S3, Backblaze B2, or another object store. Schedule snapshots with a systemd timer every 6-24 hours, and use nodetool clearsnapshot to prune old local snapshots. For automation, Scylla Manager handles scheduling, retention, and restore orchestration across a cluster.
What does the scylla_setup wizard actually change?
scylla_setup runs a sequence of sub-scripts: scylla_raid_setup formats data disks as XFS on mdraid, scylla_io_setup benchmarks disk IO and writes io.conf, scylla_ntp_setup configures chrony, scylla_coredump_setup routes core dumps, scylla_sysconfig_setup tunes kernel parameters including THP and swappiness, and scylla_cpuscaling_setup pins the governor to performance. Each sub-script can be re-run individually if you change hardware later — for example, if you attach a new data disk, just re-run sudo scylla_io_setup.
Can I migrate from Cassandra to ScyllaDB?
Yes. Because the SSTable format is compatible, the documented path is to stand up a ScyllaDB cluster, use sstableloader to stream existing Cassandra SSTables into it, and then cut over application traffic. For live migrations with zero downtime, the Scylla Spark Migrator or Scylla Migrator tool performs dual-writes and backfill while the application keeps running against Cassandra until verification completes. Full migration runbooks are in the ScyllaDB migration docs.
Related Guides
Deepen your data platform on vps-server.host:
- How to Install CockroachDB on Ubuntu 24.04 — distributed SQL with Postgres wire compatibility, when you need ACID transactions instead of eventual consistency.
- Cassandra Alternatives Compared — side-by-side view of ScyllaDB, Cassandra, and CockroachDB for wide-column workloads.
- How to Install Redis on Ubuntu 24.04 — in-memory cache and pub/sub layer to put in front of ScyllaDB for microsecond read latency on hot keys.
- How to Install PostgreSQL on Ubuntu 24.04 — when relational queries, joins, and JSONB are a better fit than a wide-column model.
- How to Build a Self-Hosted Monitoring Stack on Ubuntu — Prometheus + Grafana + Alertmanager recipe that extends the scylla-monitoring dashboards to the rest of your infrastructure.
- ScyllaDB Open Source Documentation
- ScyllaDB University — free courses
- scylladb.com blog — production case studies
- Seastar framework documentation
- Scylla Manager docs
Ready to run ScyllaDB in production?>
The CloudCore Business plan gives you the 8 vCPU / 24 GB RAM / 200 GB NVMe footprint ScyllaDB needs to operate outside developer-mode and deliver sub-millisecond p99 latency.
>
- 8 dedicated vCPUs (one shard per core)
- 24 GB RAM for row cache + memtables
- 200 GB NVMe SSD with measured 400k+ read IOPS
- Unmetered bandwidth for cross-DC replication
- EUR 29.99/month>
Deploy a CloudCore Business VPS and have ScyllaDB serving queries within 45 minutes.