Learning objectives
After reading this article you will be able to:
- Understand what changes between using Redis as a cache and as a database
- Configure expiration, a memory limit and an eviction policy for a cache
- Choose between RDB and AOF for data you cannot lose
Redis keeps its data in RAM, which is what makes it so fast. That same trait raises the most common question about it: if memory is wiped when the process stops, can you trust it with real data?
It depends on the role it plays in your app. As a cache, losing the data is acceptable. As a database, it is not, and you need to configure persistence to disk. For an overview of the tool itself, see what Redis is.
What is the difference between Redis as a cache and as a database?#
One question separates the two uses: if this data disappears, can I rebuild it?
- Cache: the data is a copy of something that already lives in another database or can be recomputed. If it vanishes, the app fetches it again from the source. Redis only speeds things up.
- Database: the data exists only in Redis (sessions, queues, counters, leaderboards). If it vanishes, it is gone for good.
| Cache | Database | |
|---|---|---|
| Source of truth | Another database | Redis itself |
| Losing data on restart | Acceptable | Not acceptable |
| Disk persistence | Can stay off | RDB, AOF or both |
| Expiration (TTL) | Almost always | On some keys only |
| When memory fills up | Evict old keys | Reject writes and raise an error |
| Sizing | Only the "hot" set | The whole dataset |
How do you use Redis as a cache?#
The most common pattern is cache-aside: the app checks the cache first and goes to the database only on a miss, then stores the result with an expiry.
// npm install ioredis pg
import { Redis } from "ioredis";
import pg from "pg";
const redis = new Redis(process.env.REDIS_URL);
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
export async function getUser(id) {
const key = `user:${id}`;
const cached = await redis.get(key);
if (cached) return JSON.parse(cached); // hit
const { rows } = await pool.query("SELECT id, name FROM users WHERE id = $1", [id]);
if (rows.length === 0) return null;
await redis.set(key, JSON.stringify(rows[0]), "EX", 60); // expires in 60 s
return rows[0];
}Two points matter more than the code:
- Every cache needs a TTL.
EX 60makes the key expire after 60 seconds. Without one, the cache turns into a stale copy nobody invalidates. See the EXPIRE reference. - When the data changes in the database, invalidate the key (
redis.del(key)) or accept that the cache is stale until the TTL runs out.
Because a cache is disposable, persistence can stay off. The Redis documentation itself mentions running without persistence as a setup sometimes used for caching.
What happens when a cache fills the memory?#
A memory limit exists only if you set one. The maxmemory directive sets the ceiling, and maxmemory-policy decides what to do when it is reached:
redis-cli CONFIG SET maxmemory 256mb
redis-cli CONFIG SET maxmemory-policy allkeys-lruWithout maxmemory, the limit on 64-bit systems is zero, meaning no ceiling: Redis keeps growing until it exhausts the memory available to the machine or container. The most common policies, per the official documentation:
noeviction: evicts nothing and returns an error on commands that add data. Read commands keep working.allkeys-lru: evicts the least recently used keys. The docs call it a good default when a small subset of keys gets most of the reads.allkeys-lfu: evicts the least frequently used keys.volatile-lru,volatile-ttland variants: evict only keys that have a TTL. With no expiring keys, they behave likenoeviction.
For a pure cache, allkeys-lru is the starting point. For Redis as a database, use noeviction: a memory-full error is better than silently deleting data.
How does Redis write data to disk?#
There are two persistence methods, which you can use separately or together, per the persistence documentation.
RDB: periodic snapshots#
RDB saves a point-in-time copy of the dataset to a file (dump.rdb) at set intervals. This rule saves every 60 seconds if at least 1000 keys changed:
save 60 1000The file is compact, good for backups, and speeds up restarts with large datasets. The cost: if the process dies without a clean shutdown, you lose what was written since the last snapshot, usually a few minutes.
AOF: a log of every write#
AOF (append-only file) appends every write command to a log, which is replayed at startup to rebuild the data. Turn it on with:
appendonly yesDurability depends on the appendfsync policy:
| Policy | Behavior | Risk |
|---|---|---|
always |
fsync on every write |
Very slow, the safest |
everysec |
fsync every second (suggested default) |
Up to about 1 s of writes |
no |
Leave it to the operating system | The fastest, the least safe |
AOF files are usually larger than RDB files and, depending on the fsync policy, can be slower. Redis rewrites the log in the background so it does not grow forever.
RDB, AOF or both?#
The Redis documentation advises:
- Want data safety comparable to what PostgreSQL gives you: use both.
- Can live with a few minutes of loss in a disaster: RDB alone is enough.
- AOF alone is common, but the docs discourage it, since an RDB snapshot now and then helps with backups, faster restarts and bugs in the AOF engine.
With both enabled, Redis rebuilds the data from the AOF on restart, because it is guaranteed to be the most complete.
When should you use each mode?#
Use Redis as a cache when:
- the data originates in another database and querying it is slow or expensive;
- the data can be a few seconds stale;
- losing the whole cache only causes temporary slowness, not errors.
Use Redis as a database when:
- the data is naturally in-memory and needs fast access: sessions, queues, counters, rate limiting, leaderboards;
- you accept the loss window of the persistence you chose;
- the whole dataset fits in RAM with room to spare.
Pick another database when the data is relational, needs complex queries, or cannot lose even a second of writes. In that case, see how to choose a database.
You can mix both roles in one instance, but the documentation suggests running two instances when possible: a cache that evicts keys and a persistent Redis that never does.
Is persistence the same as a backup?#
No. Persistence lets Redis survive a restart on the same disk. If the disk or the machine is lost, the files go with it, so you still need copies stored elsewhere. An RDB file is safe to copy while the server is running, because it is never modified once produced. The guide on how to back up a database covers the full routine.
How to do this on Square Cloud#
Square Cloud offers Redis hosting starting on the Standard plan, with persistence. You create the database in the dashboard, and it is ready in seconds in the same datacenter as your applications, with about 1 ms of average latency. The connection uses mandatory TLS (rediss://, with the certificate downloaded from the dashboard). The Hobby plan does not include database hosting.
Since Redis keeps everything in RAM, the size of your dataset sets how much memory you allocate to it, starting at 512 MB. For a cache, give every key a TTL, as in the example above, so the dataset does not grow without a ceiling. There is a single logical database, so separate cache and durable data by key prefix. Also use a client that reconnects on its own, because idle clients are disconnected after 5 minutes.
You take manual snapshots whenever you want, and every plan that includes databases also has a daily automatic snapshot. A snapshot can be restored into the same database, another one of the same engine or a new database, or downloaded as a .zip. See Redis hosting on Square Cloud and snapshots.
Database hosting
MongoDB, PostgreSQL, MySQL and Redis next to your app
FAQs
Does Redis lose data when it restarts?
It depends on persistence. With neither RDB nor AOF, everything in memory is gone after a restart. With RDB you can lose whatever was written since the last snapshot; with AOF on everysec, about one second of writes.
Can I use Redis as the only database of my app?
You can, if you accept the limits: the whole dataset must fit in RAM and durability depends on the persistence you configure. For complex relational data, a database like PostgreSQL is usually a better fit.
What is the difference between RDB and AOF?
RDB writes periodic point-in-time snapshots of the dataset to a compact file. AOF logs every write and replays the log at startup, giving better durability and a larger file.
What happens when Redis runs out of memory?
With maxmemory set, Redis applies the chosen eviction policy (for example allkeys-lru) to free space. With the noeviction policy, it rejects new write commands and returns an error.
More in Databases
See all 24 articles- How much does database hosting cost?Cloud database hosting costs from zero to hundreds of dollars a month. See what sets the price: instance, disk, traffic, snapshots, and how to estimate yours.
- How to host a database for your appTo host a database, pick an engine, create the instance, store the connection string in an environment variable and test the connection. Step-by-step guide.
- What is Redis used for?Redis is an in-memory data store that keeps key-value pairs and rich data structures. Learn how it works, what it is used for and when not to use it.
- How to back up your databaseBack up MySQL, PostgreSQL and MongoDB with mysqldump, pg_dump and mongodump, then restore the dump. See the commands, how to verify and common mistakes.