lower() 인덱스 대신 GIN 인덱스를 사용해보는건 고려해보셨을지 궁금하네요. 어차피 jdbctemplate로 raw sql 쓰셨으니 이 참에 FTS는 어떠신가요?

CompletableFuture.supplyAsync() 를 사용한 비동기 방식도 별도 ExecutorService를 지정하지 않는다면 forkjoinpool의 commonpool을 사용하니
리퀘스트 스레드 대신 사용하는 commonpool이 가득 차는 정도까지(cpu 코어 - 1개) 동시접속자가 많아지면 감당하지 못할 수도 있습니다.
이 부분은 reactive 방식으로 변경하거나 jvm 버전을 올려서 가상 스레드를 도입하는 편이 깔끔하게 해결할 수 있을 겁니다.

안녕하세요! 먼저 피드백 댓글 달아주셔서 정말 감사합니다.

GIN 인덱스는 해당 경우에서 필요하지 않다고 판단했습니다! 현재 검색어 자동완성 추천 API에서는 term 자체만 필요합니다. 해당 term이 어떤 article들에 속하는지는 필요하지 않습니다.
반면에, 검색 API에서는 GIN 인덱스와 유사한 인덱스를 사용하고 있습니다. postgres의 extension인 paradeDB를 활용해서 BM25 인덱스를 사용합니다.
포스팅에는 자세히 안 나와있지만 현재는 ExecutorService를 별도로 지정해서 사용하고 있습니다. 다만 말씀해주신 것처럼 reactive 방식이나 가상 스레드도 추후 고려해보겠습니다!!