Deploy a Redis or Valkey cache with the redis-cache template
Deploy a Redis or Valkey cache with the redis-cache template
Stand up a private Valkey or Redis cache on a Quake AI private network using the validated OpenTofu template redis-cache. You set a password and apply the template, confirm the cache binds to the private interface only, connect from an application instance on the same private network, run a key-value and a queue operation, and check persistence behavior.
The template runs Valkey by default (the BSD-licensed Redis fork) and runs Redis OSS with a two-variable change. The cache has no floating IP: it is reachable only from the private network, which is the right shape for a session store, cache, or queue backend that your app tier talks to over private addresses.
Monthly cost estimate
Pricing calculator ↗Sized as a custom package on shared vCPU.
Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.
What each resource is for
Cache
s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.
Included in baseline
s1a.small
2 shared vCPU, 2 GiB RAM, 0.5 Gbps
Compute + RAM rate basis
2 vCPU + 2 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.
Block storage (30 GiB)
30 GiB at $0.08/GiB/mo
Package promotional discount
Flat −$5.00/mo on the custom package (same promotion as named plans).
Included at no charge
These line items are zero on Quake AI. Many other providers meter them separately.
Data transfer (inbound and outbound)
Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.
AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.
Learn morePrivate networking
Private networks, subnets, Neutron routers, and security groups are included with the plan.
VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.
Control-plane API requests
OpenStack API calls for provisioning and management are included.
Some managed services on other clouds meter API calls or charge for premium control-plane features.
Pricing data last validated: . For current rates, check quake.ai/pricing.
Prerequisites#
You need:
- OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
- Your OpenStack credentials sourced into the shell (
source openrc.sh). See the OpenStack CLI guide. - An SSH keypair that already exists in your project. Record its name for the
key_namevariable. - A way to reach the cache's private subnet after apply, because the template allocates no floating IP: a bastion jump host, a VPN, or an application instance on the same private network. See How to set up SSH bastion access into a private subnet.
- A copy of the
redis-cachetemplate directory from the template reference page.
If private networks are new to you, work through Build a private network with two virtual machines first. It covers the primitives this template wires together.
Step 1: Set the password and apply the template#
The template requires key_name and redis_password. It ships no default password, so the cache is never reachable without a credential you choose.
Get the template into a dedicated working directory, then load your credentials:
Follow Generate app credentials to create and download your credentials file.
Source the file to load credentials into your shell session:
source ~/path/to/openrc.shCopy the example variables file and open it:
cp terraform.tfvars.example terraform.tfvarsSet the SSH keypair name and a strong password:
key_name = "YOUR_KEY_NAME"
redis_password = "CHOOSE_A_STRONG_PASSWORD"The engine defaults to Valkey. To run Redis OSS instead, add these two lines:
redis_image = "redis:7-alpine"
server_command = "redis-server"Leave persistence_enabled at its default of true so the cache keeps an append-only file on an attached volume. The remaining variables match the redis-cache reference page.
Initialize, preview, and apply:
tofu init
tofu plan
tofu applyOpenTofu provisions a private network, a subnet on 10.20.0.0/24, a router to PublicStatic, a security group, a block volume (when persistence is on), and the cache instance. Type yes to confirm. On first boot, cloud-init mounts the data volume at /data, installs Docker, and starts the engine container with requirepass set from your password.
When the apply finishes, read the outputs:
tofu outputRecord private_ip and connection_string_shape. The connection string shape is redis://:REDIS_PASSWORD@PRIVATE_IP:6379/0; substitute your own password (the secret is not emitted in the output).
Step 2: Confirm the cache binds to the private interface#
The cache must not listen on all interfaces. The template runs the container bound to the instance's private IP, and the security group allows port 6379 only from private_cidr.
Open an SSH session to the cache instance from a host that routes to 10.20.0.0/24 (your bastion or a peer instance), using the keypair you set:
PRIVATE=$(tofu output -raw private_ip)
ssh ubuntu@${PRIVATE}On the instance, confirm the container is running and check what address it listens on:
sudo docker ps --filter name=redis-cache
sudo ss -tlnp | grep 6379The listening socket shows the private IP and port 6379, not 0.0.0.0:6379. A bind to the private address confirms the cache is not exposed on a public interface. Type exit to close the session.
Step 3: Connect from an application instance#
Connect from an instance on the same private network, the way your app tier reaches the cache in practice. On that application instance, install a client. The Redis CLI talks to both Valkey and Redis:
sudo apt-get update && sudo apt-get install -y redis-toolsSet the password in the environment so it stays out of the command line and the shell history:
export REDISCLI_AUTH='CHOOSE_A_STRONG_PASSWORD'Confirm the cache answers, using the private IP from the template output:
redis-cli -h PRIVATE_IP -p 6379 PINGThe cache returns PONG.
Step 4: Run a key-value check and a queue operation#
Store and read a key to confirm the cache serves reads and writes:
redis-cli -h PRIVATE_IP -p 6379 SET greeting "hello from quake ai"
redis-cli -h PRIVATE_IP -p 6379 GET greetingSET returns OK and GET returns "hello from quake ai".
A Redis-style list backs a simple job queue. Push two jobs, inspect the queue, then pop the oldest:
redis-cli -h PRIVATE_IP -p 6379 RPUSH jobs "job-1" "job-2"
redis-cli -h PRIVATE_IP -p 6379 LRANGE jobs 0 -1
redis-cli -h PRIVATE_IP -p 6379 LPOP jobsRPUSH returns the list length 2, LRANGE returns both jobs in order, and LPOP returns "job-1", the oldest entry. A producer uses RPUSH to enqueue and a worker uses LPOP (or the blocking BLPOP) to dequeue.
Step 5: Check persistence behavior#
With persistence_enabled = true, the engine writes an append-only file to /data, which is the attached block volume. Data survives a container or instance restart.
To see this, SSH back to the cache instance and restart the container:
ssh ubuntu@${PRIVATE} "sudo docker restart redis-cache"Wait a few seconds, then read the key again from your application instance:
redis-cli -h PRIVATE_IP -p 6379 GET greetingThe value is still "hello from quake ai", restored from the append-only file on the volume.
If you set persistence_enabled = false, the template attaches no volume and the cache runs in memory only. That is the right choice for a pure cache where losing the contents on restart is acceptable, and it skips the volume.
What you built#
- Applied the
redis-cachetemplate with a required password to provision a private network, security group, optional data volume, and a cache instance - Confirmed the cache binds to the private IP, with port 6379 reachable only from
private_cidrand no floating IP - Connected from an application instance on the same private network with the Redis CLI
- Ran a key-value check and a list-based queue operation to confirm reads, writes, and queue semantics
- Checked append-only persistence by restarting the container and reading the key back from the volume
Scope of this deployment#
This template runs a single cache instance, not a replicated or clustered cache. There is no automatic failover and no read replica. For a workload that needs high availability, add replication and a failover mechanism yourself, or size a single instance to your working set and accept a restart window. You operate the instance, the engine, and its backups.
Next steps#
- self-managed Postgres template: run the relational tier your app pairs with this cache
- Deploy a Next.js app with the nextjs-app template: wire an app to this cache over the private network with a
REDIS_URLenvironment variable - How to store application secrets and inject them at runtime: move the cache password out of plain environment variables
- Redis / Valkey cache template: the template reference, parameters, and resource map
Clean up#
When you no longer need the cache, destroy everything the template created, including the instance, the private network, the security group, and the data volume:
tofu destroyType yes to confirm. Because the append-only file lives on the attached volume, tofu destroy removes the cached and persisted data along with the infrastructure. Export anything you want to keep before you destroy.