← Back to blog

Guide

Redis 6379 already in use: check whether you even need to start one

September 14, 20263 min read

Could not create server TCP listening socket *:6379: bind: Address already in use

redis-server prints that and exits. Before you go hunting for a process to kill, there is a question worth asking that people skip.

Is a working Redis already running?

Often the conflict is not a problem at all. A Redis you started last week, or one Homebrew starts at login, is sitting there working perfectly. You do not need a second one, you need to use the one you have.

redis-cli ping

If that answers PONG, Redis is up and healthy, and your app can connect right now. Nothing needs fixing. Close the terminal and carry on.

This is the single most useful thing on this page, and it is surprising how often the answer is “you already have one”.

If you do need to stop it, find the owner

lsof -i :6379

As with any database, the owner matters more than the PID, because managers restart what you kill.

Homebrew:

brew services list
brew services stop redis

Homebrew registers a launchd job. Kill the process directly and launchd starts it again within seconds, which looks exactly like the kill did nothing.

Docker:

docker ps --filter "publish=6379"
docker stop <container>

Killing docker-proxy is pointless, Docker republishes the port immediately.

Started by hand: then a normal termination is right.

redis-cli shutdown

That is cleaner than kill, because Redis saves its dataset on the way out if persistence is configured. Use it in preference to signals when you can.

Two Redis instances on purpose

Running separate instances per project is reasonable, and easy, since Redis takes the port as an argument:

redis-server --port 6380

Then point that project at 6380. Better than stopping and starting one shared instance every time you switch projects, and it keeps each project’s keyspace separate, which avoids a whole category of confusing bugs.

If you prefer one instance, Redis has numbered databases, SELECT 1, SELECT 2 and so on, though separate instances are clearer in practice.

The case where nothing is listening

lsof -i :6379 prints nothing and Redis still refuses to bind. That is TIME_WAIT, a TCP state holding a recently closed port for around thirty seconds. No process owns it, so there is nothing to kill and waiting is the fix.

Detail in what EADDRINUSE actually means.

A note on exposing Redis

By default Redis binds to localhost, which is what you want on a development machine. If you change it to 0.0.0.0 to reach it from a container or another device, you have exposed a database with no password to everything on your network.

Redis’s protected mode blocks the worst of that by default, but the safe habit on a laptop that joins untrusted networks is to leave the bind address alone unless you have a specific reason, and to set a password if you must open it.

More on that distinction in what localhost really is.

Bosun shows what is on 6379 in your menu bar, and whether the Redis holding it is a container, a brew service or something you started yourself. macOS 14 or later, 14 day trial.

See this instead of typing it

Bosun lives in your menu bar and shows every open port on your Mac, live, mapped to the process behind it. One-click kill, SIGTERM first. Useful the first time this happens. Genuinely useful the fifth time it happens in one afternoon.