이번 추천 시스템 개발 과정에서 사용자 피드백을 수렴해 두 가지 큰 방향으로 개선을 진행했다.
추천 상품 수 확장
기존에는 추천 결과를 4개까지만 응답하도록 제한했는데 사용자 입장에서는 선택지가 너무 적다는 의견이 많았다. 선물이라는 특성상 비교/고민 후 선택하는 흐름이 중요한데 4개의 결과로는 만족스럽지 못하다는 피드백이었다. 이에 우리는 추천 상품 수를 최소 6개에서 최대 10개까지로 확대하기로 했다.
상품 다양성 개선
이전에는 유사 상품(동일 브랜드, 옵션만 다른 상품 등)이 연속으로 추천되는 현상이 자주 발생했다. 이를 해결하기 위해 한글 제목 기반 유사도 필터링, 브랜드 중복 최소화, 태그 기반 조합 우선순위 설계 등의 리팩토링을 거쳤다.
결과적으로 사용자 만족도는 높아졌지만 시스템 입장에서는 새로운 이슈가 생겼다. 바로 성능 문제, 특히 응답 지연이었다.
추천 결과의 수가 늘어나고 각 결과를 필터링하거나 다양한 기준으로 정렬해야 하다 보니 추천 로직의 복잡도가 기하급수적으로 증가했다. 기존에는 단순한 키워드 매칭 및 가격 필터 정도로 빠르게 조회가 가능했지만 이제는 다음과 같은 과정을 거친다.
특히 이 중 외부 API 호출과 제목 유사도 비교 단계가 가장 병목을 일으켰다. 추천 수를 늘리기 위해 후보군을 더 많이 가져오게 되고 그 후보군에 대해 유사도 비교 및 중복 필터링을 하다 보니 전체 로직의 처리 시간이 눈에 띄게 늘어났다. 프론트엔드에서는 로딩이 체감될 정도로 길어졌다는 피드백이 있었고 사용자 경험 측면에서도 성능 최적화가 필요한 시점이라는 판단이 들었다.
현재 이 문제를 해결하기 위해 아래와 같은 아이디어들을 고려하고 있다.
동일 키워드 조합/조건으로 유사도 비교가 반복되는 경우가 많다. 유사도 비교 결과를 Redis 또는 Local Cache에 저장해두고 같은 상품 쌍에 대해 다시 계산하지 않도록 캐싱하는 구조를 도입할 수 있다.
상품 후보군이 부족할 경우 외부 API를 동기적으로 호출하는 방식은 성능을 심각하게 떨어뜨린다. 후보가 부족해도 일단 현재 조건에 맞는 상품만 응답하고 부족한 경우는 백그라운드에서 비동기적으로 수집/캐싱하여 다음 요청 시 활용하는 구조로 전환하는 것도 고려 중이다. 프론트에서는 “추천 보강 중입니다”와 같은 UI 메시지를 통해 사용자에게 안내할 수 있다.
내부에서 태그 조합별로 상품을 검색하는 과정은 독립적인 작업이다. 이를 병렬로 처리할 수 있도록 CompletableFuture + ExecutorService 구조로 리팩토링하면 성능 개선 효과가 있을 것으로 기대된다. 단, 외부 API와 DB 트랜잭션이 얽힌 부분은 병렬성 적용 시 주의가 필요하다.
특정 인기 키워드 조합, 시간대, 가격 조건은 반복적으로 요청되는 경향이 있다. 이런 경우에 대비해 사전 캐싱된 상품 풀을 준비하고 추천 응답 시 바로 활용하는 전략도 고려할 수 있다.
이번 경험을 통해 기능 개선이 언제나 시스템 부담을 수반한다는 점을 다시금 느꼈다. 추천 수를 늘리고 상품의 다양성을 높이는 것이 사용자에게 더 나은 경험을 제공하는 일이라는 건 분명하다. 하지만 그만큼 백엔드 입장에서는 데이터 처리량, 필터링 복잡도, 연산량, API 호출 수가 기하급수적으로 증가하며 결과적으로 사용자 경험을 떨어뜨릴 수 있는 “응답 지연”이라는 새로운 문제로 되돌아오게 된다.
성능 개선은 단순한 코드 리팩토링만으로 해결되지 않는다. 서비스 흐름 자체를 어떻게 설계하느냐, 데이터 흐름과 캐싱을 어떻게 가져가느냐, 어디까지 실시간성을 유지하고 어디부터는 비동기로 넘길 수 있을지를 명확히 구분하는 판단력이 점점 더 중요해진다고 느낀다.