Laravel에서 Queue를 처음 적용할 때는 Job 코드보다 어떤 Queue Connection을 사용할지 먼저 고민하게 된다.
Laravel 프로젝트에서는 별도 인프라 없이 시작할 수 있는 Database Queue가 접근하기 쉽다.
Application
↓
jobs 테이블
↓
Queue Worker
서비스 규모가 커지거나 Queue 처리량이 많아지면 Redis Queue도 자연스럽게 후보에 들어온다.
Application
↓
Redis
↓
Queue Worker
그러면 이런 질문이 생긴다.
Database Queue도 잘 동작하는데 Redis로 바꿔야 할까?
Redis Queue는 정확히 무엇이 다른가?
Job이 얼마나 많아지면 Redis를 사용해야 할까?
Redis가 무조건 더 좋은 선택일까?
단순히 Redis가 메모리 기반이라 빠르다 정도로만 비교하면 실제 Queue Driver를 선택하기 어렵다.
Queue는 애플리케이션과 Worker 사이에서 계속 데이터를 넣고 가져가는 인프라이기 때문에 처리량뿐 아니라 운영 복잡도, 장애 대응, 모니터링까지 함께 봐야 한다.
이번 글에서는 Laravel Database Queue와 Redis Queue가 어떻게 다른지 살펴보고, 실제 서비스에서는 어떤 기준으로 선택하면 좋은지 정리해보려고 한다.
Database Queue와 Redis Queue의 핵심 차이
먼저 핵심적인 차이를 간단히 정리하면 다음과 같다.
| 구분 | Database Queue | Redis Queue |
|---|---|---|
| 저장 위치 | RDB 테이블 | Redis |
| 추가 인프라 | 거의 없음 | Redis 필요 |
| 도입 난이도 | 낮음 | 상대적으로 높음 |
| Queue 처리량 | 규모가 커질수록 DB 영향 고려 | 높은 처리량에 상대적으로 유리 |
| 애플리케이션 DB 영향 | 있음 | Queue 부하를 Redis로 분리 가능 |
| Laravel Horizon | 사용 불가 | 사용 가능 |
| 운영 복잡도 | 비교적 낮음 | Redis 운영 필요 |
| 적합한 상황 | 소규모·중간 규모 Queue, 빠른 도입 | Queue 비중과 처리량이 큰 서비스 |
여기서 중요한 것은
Database Queue = 나쁨
Redis Queue = 좋음
이 아니라는 점이다.
서비스 규모가 작고 Queue 처리량이 많지 않다면 Database Queue가 오히려 단순하고 실용적인 선택일 수 있다.
반대로 Queue가 서비스의 중요한 처리 경로가 되고 Job 처리량이 계속 증가한다면 Redis로 분리하는 장점이 커질 수 있다.
Database Queue는 어떻게 동작할까?
Laravel에서 Database Queue를 사용하면 Job이 일반적으로 jobs 테이블에 저장된다.
환경 설정은 Laravel 버전과 프로젝트 설정에 따라 다를 수 있지만 개념적으로 다음과 같다.
QUEUE_CONNECTION=database
Job을 Dispatch한다.
SendNotificationJob::dispatch($userId);
그러면 흐름은 다음과 같다.
Application
↓
jobs 테이블 INSERT
↓
Worker가 처리할 Job 조회 및 예약
↓
Job 실행
↓
정상 완료 후 Queue에서 제거
즉, 애플리케이션에서 사용하는 관계형 데이터베이스가 Queue Backend 역할도 담당하게 된다.
Database Queue의 가장 큰 장점은 단순함이다
이미 MySQL을 사용하고 있다면 Redis 같은 별도 인프라 없이 Queue를 도입할 수 있다.
기존
Application + MySQL
Queue 도입
Application + MySQL
└ Queue
Queue 때문에 새로운 서버나 관리 대상을 추가하지 않아도 된다.
초기 서비스나 Queue 사용량이 많지 않은 프로젝트에서는 꽤 큰 장점이다.
Database Queue는 언제 문제가 될 수 있을까?
Database Queue라고 해서 처리량이 조금만 증가해도 바로 문제가 생기는 것은 아니다.
다만 Queue 사용량이 커지면 애플리케이션 데이터베이스가 Queue 처리까지 담당한다는 점을 생각해야 한다.
예를 들어 서비스에서 다음 작업이 동시에 발생한다고 해보자.
사용자 API
↓
SELECT / INSERT / UPDATE
관리자 기능
↓
대량 조회
Scheduler
↓
Batch 처리
Queue
↓
Job INSERT / 조회 / 예약 / 삭제
모두 같은 MySQL을 사용한다.
Queue 처리량이 적을 때는 큰 문제가 없을 수 있다.
하지만 Job 생성과 처리가 매우 빈번해지면 Queue를 위한 DB 작업도 무시하기 어려워진다.
Worker를 늘릴수록 DB 접근도 증가할 수 있다
Queue가 밀린다고 Worker를 계속 늘려보자.
Worker 1 ─┐
Worker 2 ─┤
Worker 3 ─┤
... ├→ MySQL jobs
Worker 20 ┘
Worker가 늘어나면 동시에 Queue를 확인하고 Job을 처리하는 프로세스도 많아진다.
여기에 Job 내부에서도 MySQL을 사용한다면 DB 입장에서는
Queue 자체를 위한 DB 접근
+
Job 비즈니스 로직의 DB 접근
+
일반 API의 DB 접근
을 모두 처리해야 한다.
이 시점부터는 Queue 처리 성능만 볼 것이 아니라 애플리케이션 DB에 미치는 영향도 함께 봐야 한다.
Redis Queue는 무엇이 다를까?
Redis Queue를 사용하면 Queue 데이터를 관계형 데이터베이스가 아니라 Redis에서 관리한다.
개념적인 설정은 다음과 같다.
QUEUE_CONNECTION=redis
흐름은 다음과 같이 바뀐다.
Application
↓
Redis Queue
↓
Worker
↓
Job 실행
Job 내부에서 MySQL을 사용할 수 있다는 점은 동일하다.
하지만 Queue 자체를 관리하기 위한 작업은 Redis로 분리된다.
MySQL
→ 비즈니스 데이터
Redis
→ Queue
이 분리가 Redis Queue를 사용하는 중요한 이유 중 하나다.
Redis가 메모리 기반이라는 것만 보면 안 된다
Redis Queue를 설명할 때 흔히 다음처럼 이야기한다.
Redis는 메모리를 사용한다.
↓
DB보다 빠르다.
↓
Queue도 빠르다.
방향 자체가 완전히 틀린 설명은 아니지만 실제 선택 기준으로는 부족하다.
Queue에서는 단순 조회 속도 하나보다 다음을 같이 봐야 한다.
Job 유입량
Worker 수
Queue Polling
Queue 대기 시간
애플리케이션 DB 부하
Redis 운영 비용
장애 대응
모니터링
Redis Queue의 장점은 단순히 SELECT보다 Redis 명령이 빠르다는 것에만 있지 않다.
Queue의 저장과 소비에 필요한 부하를 애플리케이션 RDB에서 분리할 수 있다는 점도 중요하다.
처리량이 많아지면 차이가 커질 수 있다
예를 들어 하루에 몇십 개 정도의 메일 Job만 처리한다고 해보자.
하루 Job
50건
이 정도 규모라면 Queue Backend의 성능 차이가 서비스에서 중요한 병목이 아닐 가능성이 높다.
굳이 Queue 때문에 Redis 인프라를 추가하는 것이 더 복잡할 수도 있다.
반대로 다음과 같은 서비스라면 이야기가 달라질 수 있다.
대량 알림
상품 데이터 동기화
외부 API 데이터 수집
대량 Batch
이벤트 처리
수많은 비동기 Job
특정 시간에 수만 개 이상의 Job이 생성되고 여러 Worker가 동시에 처리한다면 Queue Backend 자체의 처리량과 DB 부하를 검토할 필요가 있다.
다만
Job 10,000개부터 Redis
처럼 특정 숫자로 기준을 정하기는 어렵다.
Job 하나의 처리 시간과 Payload, Worker 수, Job 생성 패턴, DB 성능, 서버 구조가 모두 다르기 때문이다.
Queue가 느리다고 Redis부터 도입하면 안 된다
Queue 대기 시간이 길어지면 Database Queue가 원인이라고 생각하기 쉽다.
Queue 느림
↓
Database Queue 때문?
↓
Redis 전환
하지만 실제 병목이 다른 곳에 있을 수도 있다.
예를 들어 Job 하나가 다음 Query 때문에 30초 걸린다고 해보자.
SELECT ...
FROM orders
JOIN customers ...
WHERE ...;
Queue Backend를 Redis로 변경해도 Job 내부 Query는 그대로 30초가 걸린다.
또는 외부 API가 느릴 수도 있다.
Redis
↓
Worker
↓
외부 API 요청
↓
30초 대기
Redis로 바꿔도 해결되지 않는다.
그래서 Queue가 밀린다면 먼저 다음을 구분하는 것이 좋다.
Queue Backend가 병목인가?
Job 자체가 느린가?
Worker가 부족한가?
DB가 느린가?
외부 API가 느린가?
Retry가 반복되고 있는가?
Redis는 Queue 성능 문제의 만능 해결책이 아니다.
Database Queue가 충분한 경우
Redis가 있다고 해서 모든 프로젝트의 Queue를 Redis로 운영할 필요는 없다.
Database Queue가 잘 맞는 상황도 많다.
Queue 사용량이 많지 않다
예를 들어 다음 정도의 작업만 비동기로 처리한다고 해보자.
간헐적인 메일 발송
관리자 Excel 생성
소규모 Batch
일부 외부 API 연동
Job 유입량이 적고 Queue 대기 시간에도 문제가 없다면 Database Queue로 충분할 수 있다.
운영 구조를 단순하게 유지하고 싶다
Redis를 추가하면 관리 대상도 하나 늘어난다.
Redis Connection
Memory
장애
Persistence
Monitoring
Network
Queue 규모가 작은데 이런 운영 비용까지 추가하는 것이 항상 이득인 것은 아니다.
MySQL에 충분한 여유가 있다
Database Queue를 사용하더라도 MySQL CPU와 Connection에 충분한 여유가 있고 Queue 처리 때문에 일반 API가 영향을 받지 않는다면 당장 변경할 이유가 크지 않을 수 있다.
기술 선택에서는
더 좋은 기술이 무엇인가?
보다
현재 문제를 해결하기 위해 필요한가?
를 보는 것이 중요하다.
Redis Queue를 검토할 만한 시점
반대로 다음 상황이 반복된다면 Redis Queue를 검토할 이유가 생긴다.
Queue 처리량이 계속 증가한다
Job 유입량 증가
↓
Worker 증가
↓
Queue Backend 접근 증가
Queue가 서비스의 주요 처리 경로가 되기 시작했다면 별도의 Queue Backend를 사용하는 장점이 커진다.
Queue 때문에 애플리케이션 DB 부하가 커진다
Database Queue를 사용하는 상황에서 Queue 작업 자체가 DB 부하의 의미 있는 부분을 차지하기 시작한다면 Redis로 분리하는 것을 검토할 수 있다.
Worker를 많이 운영해야 한다
Queue별 Worker 수가 증가하고 동시 처리량이 커진다면 Queue Backend의 확장성도 중요해진다.
Horizon을 사용하고 싶다
Laravel Horizon은 Redis Queue를 대상으로 한다.
Queue 처리량과 Runtime, 실패 Job 등을 관리하고 Worker 운영을 더 체계적으로 가져가고 싶다면 Redis + Horizon 구성을 검토할 수 있다.
Redis Queue에도 운영 비용이 있다
Redis Queue가 성능과 확장성 측면에서 유리한 경우가 있지만 무료로 얻는 장점은 아니다.
Redis도 하나의 인프라다.
운영 환경에서는 다음을 생각해야 한다.
Redis 장애
Memory 부족
Connection 문제
Eviction 정책
Persistence
Network 장애
Failover
Monitoring
Redis 메모리는 무한하지 않다
Queue가 비정상적으로 쌓이면 Redis 메모리도 증가한다.
외부 API 장애
↓
Job 처리 실패
↓
Queue 처리 지연
↓
새로운 Job 계속 유입
↓
Queue 증가
↓
Redis Memory 증가
Queue를 Redis로 옮겼다고 Queue 적체 문제가 사라지는 것은 아니다.
오히려 Redis 메모리 사용량이라는 새로운 운영 지표가 생긴다.
캐시와 Queue를 같은 Redis에서 사용할 때도 주의한다
예를 들어 하나의 Redis를 다음 용도로 모두 사용한다고 해보자.
Cache
Session
Queue
Lock
서비스 규모가 작다면 충분히 가능한 구성이다.
하지만 사용량이 커지면 하나의 Redis 장애가 여러 기능에 동시에 영향을 줄 수 있다.
특히 메모리 정책과 장애 영향 범위를 생각해야 한다.
Queue 데이터와 일반 캐시 데이터는 중요도가 다를 수 있기 때문이다.
규모가 커진다면 Redis를 용도별로 어떻게 분리할지도 별도의 설계 문제가 된다.
Redis Persistence도 생각해야 한다
Redis를 단순 캐시로만 사용한다면 일부 데이터 손실을 허용할 수 있는 경우가 있다.
Cache 삭제
↓
DB에서 다시 조회
↓
Cache 재생성
Queue는 성격이 다르다.
처리되지 않은 Job이 사라지면 비즈니스 작업 자체가 누락될 수 있다.
예를 들어
결제 후처리
알림
외부 시스템 동기화
포인트 처리
같은 Job이라면 데이터 유실이 서비스 문제로 이어질 수 있다.
따라서 Redis Queue를 운영할 때는
Persistence
Replication
Backup
Failover
장애 시 Job 처리 정책
같은 부분도 서비스 요구 수준에 맞게 검토해야 한다.
단순히 Redis를 Cache처럼 생각하고 Queue를 올리는 것은 위험할 수 있다.
Redis Queue로 변경하면 Job 코드는 달라질까?
Laravel Queue 추상화를 사용하고 있다면 기본적인 Job 코드는 크게 달라지지 않는 경우가 많다.
class SendNotificationJob implements ShouldQueue
{
public function handle(): void
{
// 비동기 처리
}
}
Dispatch도 동일하다.
SendNotificationJob::dispatch($userId);
Connection 설정을 통해 Queue Backend를 변경할 수 있다.
이런 추상화 덕분에 애플리케이션 코드 전체를 다시 작성하지 않고 Queue Backend를 변경할 수 있는 경우가 많다.
하지만 실제 전환에서는 설정만 바꾸고 끝내면 안 된다.
Database Queue에서 Redis로 전환할 때 확인할 것
운영 중인 서비스의 Queue Backend를 변경한다면 기존 Job 처리 상태까지 생각해야 한다.
예를 들어 Database Queue에 아직 Job이 남아 있는 상태에서
database
↓
redis
로 Connection만 변경했다고 해보자.
기존 jobs 테이블의 Job은 Redis로 자동 이동되는 것이 아니다.
따라서 전환 시에는
기존 Database Queue에 남은 Job
현재 Worker 상태
새로운 Job이 들어갈 Connection
Supervisor 설정
배포 순서
실패 Job
모니터링
을 함께 확인해야 한다.
Worker 설정도 확인한다
Supervisor에서 Connection을 명시했다면 Worker 명령도 변경해야 할 수 있다.
예를 들어 기존에
php artisan queue:work database \
--queue=default
를 사용했다면 Redis 전환 후에는 해당 운영 설정도 맞춰야 한다.
설정 변경 후 Worker 재시작까지 배포 과정에서 관리하는 것이 좋다.
Queue 이름과 Connection은 다른 개념이다
Laravel Queue를 처음 다룰 때 헷갈리기 쉬운 부분이다.
다음 두 개는 서로 다른 개념이다.
Connection
database
redis
Queue
default
notification
export
batch
예를 들어 Redis Connection 안에서도 여러 Queue를 운영할 수 있다.
Redis
├ default
├ notification
├ export
└ batch
Database Connection에서도 마찬가지다.
Database
├ default
├ notification
├ export
└ batch
따라서
SendSmsJob::dispatch()
->onQueue('notification');
에서 notification은 Redis나 Database를 의미하는 것이 아니다.
어떤 Connection을 사용할지는 별도로 결정된다.
필요하다면 Connection 자체를 지정할 수도 있다.
SendSmsJob::dispatch()
->onConnection('redis')
->onQueue('notification');
운영 설정을 볼 때 이 두 개념을 구분하면 Queue 구조를 이해하기 쉬워진다.
SQS 같은 다른 선택지도 있다
Laravel Queue 선택지가 Database와 Redis만 있는 것은 아니다.
서비스 규모와 인프라 환경에 따라 Amazon SQS 같은 관리형 메시지 Queue를 선택할 수도 있다.
개념적으로 보면 선택지가 다음처럼 넓어진다.
Database Queue
→ 도입과 운영이 단순
Redis Queue
→ 빠른 Queue 처리
→ Horizon 활용
→ Redis 직접 운영 필요
Managed Queue
→ Queue 인프라 운영 부담 일부 감소
→ 클라우드 서비스 특성과 비용 고려
따라서 Database Queue에서 바로 Redis로 가는 것이 항상 정답은 아니다.
AWS 중심의 인프라라면 SQS가 더 자연스러운 선택일 수도 있다.
다만 Redis와 SQS는 동작 특성과 전달 모델, 운영 방식이 다르기 때문에 별도의 비교가 필요하다.
어떤 Queue Driver를 선택하면 좋을까?
실무에서는 특정 Job 개수보다 현재 서비스 상황을 기준으로 판단하는 편이 좋다.
Database Queue를 먼저 고려할 수 있는 경우
Queue 규모가 작다.
↓
Database Queue
Queue 사용량이 많지 않다.
↓
Database Queue
별도 Redis 운영이 부담스럽다.
↓
Database Queue
현재 DB 부하에 문제가 없다.
↓
Database Queue 유지
Redis Queue를 검토할 수 있는 경우
Queue 처리량이 계속 증가한다.
↓
Redis 검토
Queue Worker가 많아지고 있다.
↓
Redis 검토
Queue 작업의 DB 부하가 커지고 있다.
↓
Redis 검토
Horizon을 활용하고 싶다.
↓
Redis 필요
중요한 것은
서비스가 커졌으니까 Redis
가 아니라 현재 Queue Backend가 실제 병목이나 운영상의 제약이 되고 있는지를 확인하는 것이다.
Queue Driver를 바꾸기 전에 먼저 확인할 것
Database Queue가 느리다고 느껴진다면 Redis로 변경하기 전에 다음 정도는 확인해보는 것이 좋다.
□ Queue 대기 시간이 실제로 증가하고 있는가?
□ Job 자체의 실행 시간이 긴 것은 아닌가?
□ Worker 수가 부족한 것은 아닌가?
□ Worker가 정상적으로 실행되고 있는가?
□ Job 내부에 Slow Query가 있지 않은가?
□ 외부 API가 느린 것은 아닌가?
□ Retry가 반복되고 있지 않은가?
□ jobs 테이블 접근이 실제 DB 부하의 원인인가?
□ Redis를 추가했을 때 운영 복잡도를 감당할 수 있는가?
□ Queue Job의 유실 허용 수준을 정했는가?
□ Redis 장애 시 대응 방법을 생각했는가?
이 질문을 확인했을 때 Database Queue 자체가 병목이라면 Redis 전환의 근거도 훨씬 명확해진다.
마무리
Laravel Database Queue와 Redis Queue의 차이를 단순하게 정리하면 다음과 같다.
Database Queue
→ 기존 RDB 활용
→ 도입이 단순
→ Queue 규모가 크지 않을 때 실용적
Redis Queue
→ Queue 부하를 RDB에서 분리
→ 높은 처리량에 유리
→ Horizon 활용 가능
→ Redis 운영 필요
그래서 처음부터 Redis Queue를 선택해야 하는 것은 아니다.
Queue 사용량이 많지 않고 Database Queue가 안정적으로 처리되고 있다면 굳이 구조를 복잡하게 만들 필요가 없다.
반대로 Job과 Worker가 계속 증가하면서 Queue 처리 자체가 애플리케이션 DB에 부담을 주기 시작한다면 Redis를 검토할 이유가 생긴다.
그리고 Queue가 느리다는 이유만으로 Redis로 변경해서도 안 된다.
Queue Wait Time
Job Runtime
Worker 상태
DB 부하
외부 API
Retry
를 먼저 확인해 실제 병목을 찾는 것이 우선이다.
결국 Queue Driver를 선택할 때 가장 중요한 질문은
Redis가 Database보다 빠른가?
가 아니라
현재 서비스에서 Queue를 어디에 저장하고 처리하는 것이
성능과 운영 복잡도 사이에서 가장 적절한가?
라고 생각한다.
현재 Database Queue가 문제없이 동작한다면 그대로 사용하는 것도 충분히 좋은 선택이다.
문제가 생기기 전에 모든 인프라를 미리 복잡하게 만드는 것보다 Queue 처리량과 DB 부하를 관찰하면서 전환이 필요한 시점을 판단하는 것이 운영 환경에서는 더 현실적인 접근이다.
'개발 > Laravel' 카테고리의 다른 글
| Laravel Queue 모니터링에서 어떤 지표를 확인해야 할까? (0) | 2026.08.27 |
|---|---|
| Laravel Queue 대기 시간이 길어질 때 무엇부터 확인해야 할까? (0) | 2026.08.26 |
| Laravel Queue Worker 수는 어떻게 결정해야 할까? (0) | 2026.08.19 |
| Laravel Queue를 목적별로 분리해서 운영하는 방법 (0) | 2026.08.19 |
| Laravel ShouldBeUnique와 WithoutOverlapping 차이는 무엇일까? (0) | 2026.08.18 |