AI로 생성된 API를 위한 Go + Postgres 성능 튜닝 플레이북: 연결 풀, EXPLAIN으로 쿼리 읽기, 스마트한 인덱싱, 안전한 페이지네이션, 빠른 JSON 설계.

AI로 생성한 API는 초기 테스트에서 빠르게 느껴질 수 있습니다. 엔드포인트를 몇 번 호출하고 데이터셋이 작으면 요청이 한 번에 들어옵니다. 하지만 실제 트래픽이 오면: 혼합된 엔드포인트, 버스트성 부하, 캐시가 차가워짐, 예상보다 많은 행—같은 코드가 아무 문제도 없는데도 불규칙하게 느려집니다.
느림은 보통 다음과 같이 나타납니다: 지연 스파이크(대부분은 괜찮은데 일부 요청이 5x~50x 길어짐), 타임아웃(소수의 요청 실패), 또는 CPU 과부하(Postgres는 쿼리 작업으로, Go는 JSON 처리, 고루틴, 로깅, 재시도로 인해).
흔한 시나리오는 유연한 검색 필터가 있는 리스트 엔드포인트가 큰 JSON 응답을 반환하는 경우입니다. 테스트 DB에서는 수천 행을 스캔해 빠르게 끝나지만, 프로덕션에서는 수백만 행을 스캔하고 정렬한 뒤에야 LIMIT를 적용합니다. API는 여전히 "작동"하지만 p95 지연이 폭증하고 버스트 동안 일부 요청이 타임아웃됩니다.
데이터베이스 느림과 애플리케이션 느림을 구분하려면 단순한 사고 모델을 유지하세요.
데이터베이스가 느리면 Go 핸들러는 쿼리를 기다리는 데 대부분 시간을 보냅니다. 이때 많은 요청이 "진행 중"으로 쌓이는데 Go CPU는 정상 범위를 보일 수 있습니다.
애플리케이션이 느리면 쿼리는 빠르게 끝나지만 쿼리 이후에 시간이 소요됩니다: 큰 응답 객체 생성, JSON 마샬링, 행당 추가 쿼리 또는 요청당 과도한 작업. 이 경우 Go CPU와 메모리가 증가하고 응답 크기에 따라 지연이 커집니다.
출시 전의 “충분히 좋음”은 완벽이 아닙니다. 많은 CRUD 엔드포인트의 목표는 안정적인 p95 지연(평균이 아니라), 버스트 중 예측 가능한 동작, 그리고 기대치에서 타임아웃이 발생하지 않는 것입니다. 목표는 간단합니다: 데이터와 트래픽이 증가해도 깜짝 느려지는 요청이 없고, 무언가 변동이 생기면 명확한 신호가 있어야 합니다.
무엇이 "좋다"는지 정하기 전에는 아무것도 튜닝하지 마세요. 기준이 없으면 설정을 바꾸고 나서 개선인지 병목 이동인지 알기 어렵습니다.
보통 세 가지 수치가 대부분의 이야기를 알려줍니다:
p95는 "안 좋은 날" 지표입니다. p95가 높고 평균이 괜찮다면, 일부 요청이 과도한 작업을 하거나 잠김에 막히거나 느린 플랜을 유발하고 있다는 뜻입니다.
느린 쿼리는 초반부터 가시화하세요. Postgres에서 사전 출시 테스트용으로 낮은 임계값(예: 100–200ms)으로 느린 쿼리 로깅을 켜고 전체 문장을 기록해 SQL 클라이언트로 바로 복사할 수 있게 하세요. 다만 임시로만 사용하세요—운영에서 모든 느린 쿼리를 기록하면 금방 시끄러워집니다.
다음으로 실제와 비슷한 요청으로 테스트하세요. 단일 "hello world" 라우트가 아니라 사용자가 실제 할 작업과 일치하는 소수의 요청이면 충분합니다: 필터와 정렬이 있는 리스트 호출, 몇 개의 조인을 포함한 상세 페이지, 유효성 검사가 있는 생성/수정, 부분 일치가 있는 검색 스타일 쿼리.
스펙에서 엔드포인트를 생성한다면(예: Koder.ai 같은 도구로), 일관된 입력으로 같은 소수의 요청을 반복 실행하세요. 이렇게 하면 인덱스, 페이지네이션 조정, 쿼리 재작성 같은 변경을 측정하기 쉬워집니다.
마지막으로 소리 내어 말할 수 있는 목표를 정하세요. 예: "대부분 요청은 50 동시 사용자에서 p95 200ms 미만, 오류 0.5% 미만." 정확한 숫자는 제품에 따라 다르지만 명확한 목표가 끝없는 손질을 막아줍니다.
연결 풀은 열린 DB 연결 수를 제한하고 재사용합니다. 풀 없이 각 요청이 새 연결을 열면 Postgres는 세션 관리에 시간과 메모리를 쓰게 되어 쿼리를 실행하는 데 집중하지 못합니다.
목표는 Postgres가 실제 작업을 하도록 하고 너무 많은 연결 간 문맥 전환에 시간을 쓰지 않게 하는 것입니다. 이는 특히 조용히 통신량이 많은 엔드포인트로 변질되기 쉬운 AI 생성 API에서 첫 번째로 의미 있는 개선이 되는 경우가 많습니다.
Go에서는 보통 max open connections, max idle connections, connection lifetime을 튜닝합니다. 많은 작은 API에 안전한 출발점은 CPU 코어 수의 작은 배수(대개 총 520 연결), 유사한 수의 idle을 유지, 주기적으로(예: 3060분) 연결을 재활용하는 것입니다.
여러 API 인스턴스를 운영 중이라면 풀 수는 곱해진다는 점을 기억하세요. 인스턴스 10개에 풀 20이면 Postgres로 200 연결이 들어가고, 이 때문에 팀들이 예기치 않게 연결 제한에 걸리는 경우가 많습니다.
풀 문제는 느린 SQL과는 다르게 느껴집니다.
풀 크기가 너무 작으면 요청은 Postgres에 도달하기 전에 대기합니다. 지연이 스파이크하지만 DB CPU와 쿼리 시간은 정상이 보일 수 있습니다.
풀이 너무 크면 Postgres가 과부하되어 많은 활성 세션, 메모리 압박, 엔드포인트 간 불균형한 지연이 나타납니다.
빠른 분리 방법은 DB 호출을 두 부분으로 측정하는 것입니다: 연결을 기다리는 데 걸린 시간 vs 쿼리 실행 시간. 대부분이 "대기"라면 풀이 병목입니다. 대부분이 "쿼리 중"이라면 SQL과 인덱스에 집중하세요.
유용한 빠른 점검:
max_connections에 얼마나 근접한지 모니터링하세요.pgxpool을 사용하면 Postgres 관점에서 더 나은 기본값과 명확한 통계를 얻습니다. database/sql은 여러 DB에서 공통으로 쓰이는 인터페이스를 제공하지만 풀 설정과 드라이버 동작을 명시적으로 다뤄야 합니다.
실용 규칙: Postgres만 사용하고 직접 제어하고 싶다면 pgxpool이 더 간단한 경우가 많습니다. 라이브러리가 database/sql을 기대한다면 그쪽을 쓰되 풀을 명확히 설정하고 대기를 측정하세요.
예: 주문 목록을 반환하는 엔드포인트가 평상시에는 20ms인데 동시 사용자 100명에서는 2s로 뛰면, 로그에서 1.9s가 연결 대기라면 풀과 총 Postgres 연결 수를 맞출 때까지 쿼리 튜닝은 도움이 되지 않습니다.
엔드포인트가 느리면 Postgres가 실제로 무엇을 하는지 확인하세요. EXPLAIN을 빠르게 읽으면 몇 분 안에 해결책이 보이는 경우가 많습니다.
API가 보내는 정확한 SQL로 다음을 실행하세요:
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, status, created_at
FROM orders
WHERE user_id = $1 AND status = $2
ORDER BY created_at DESC
LIMIT 50;
몇 줄이 가장 중요합니다. Postgres가 선택한 최상위 노드와 하단의 합계(걸린 시간)를 보세요. 그리고 추정 행 수와 실제 행 수를 비교하세요. 큰 차이는 보통 플래너가 잘못 추정했다는 신호입니다.
Index Scan 또는 Index Only Scan을 보면 인덱스를 사용하고 있는 것이고 보통 좋습니다. Bitmap Heap Scan은 중간 크기 매치에서 괜찮습니다. Seq Scan은 전체 테이블을 읽었다는 의미로, 테이블이 작거나 거의 모든 행이 매치될 때만 괜찮습니다.
일반적인 적신호:
ORDER BY와 함께)느린 플랜은 보통 몇 가지 패턴에서 옵니다:
WHERE + ORDER BY 패턴에 맞는 인덱스가 없음(예: (user_id, status, created_at))WHERE에 함수 사용(예: WHERE lower(email) = $1), 이 경우 표현식 인덱스를 추가하지 않으면 스캔을 강제하기도 함플랜이 이상하고 추정이 크게 빗나간다면 통계가 오래되어 있을 가능성이 큽니다. ANALYZE를 실행하거나 autovacuum이 따라잡도록 하세요. 특히 대량 임포트 후나 새로운 엔드포인트가 빠르게 많은 데이터를 쓸 때 중요합니다.
인덱스는 API가 실제로 쿼리하는 방식에 맞을 때만 도움이 됩니다. 추측으로 인덱스를 만들면 쓰기 속도 저하, 저장 공간 증가, 거의 효과 없는 인덱스가 생깁니다.
현실적인 사고 방식: 인덱스는 특정 질문에 대한 지름길입니다. API가 다른 질문을 하면 Postgres는 그 지름길을 무시합니다.
엔드포인트가 account_id로 필터링하고 created_at DESC로 정렬한다면 하나의 복합 인덱스가 두 개의 별도 인덱스보다 낫습니다. Postgres가 적절한 행을 찾고 올바른 순서로 반환하는데 드는 작업을 줄여줍니다.
유지되는 경험칙:
예: GET /orders?status=paid가 있고 항상 최신순으로 보여준다면 (status, created_at DESC) 같은 인덱스가 적합합니다. 대부분의 쿼리가 고객으로도 필터링된다면 (customer_id, status, created_at)이 더 낫지만, 이는 실제 프로덕션에서 엔드포인트가 어떻게 동작하는지에 따라 다릅니다.
트래픽의 대부분이 좁은 행 집합을 치는 경우 partial index가 더 저렴하고 빠릅니다. 예: 대부분 읽기가 활성 행을 대상으로 한다면 WHERE active = true로만 인덱싱하면 인덱스가 작아져 메모리에 오래 머물고 더 빠릅니다.
인덱스가 도움이 되는지 확인하려면 빠른 점검을 하세요:
EXPLAIN(또는 안전한 환경에서 EXPLAIN ANALYZE)을 실행해 쿼리에 맞는 인덱스 스캔이 있는지 확인사용되지 않는 인덱스는 신중히 제거하세요. 인덱스 사용 통계(예: 스캔된 적이 있는지)를 확인하고 한 번에 하나씩 낮은 위험 시간에 드롭하세요. 되돌릴 계획을 항상 준비하세요. 사용되지 않는 인덱스도 쓰기 시마다 비용을 추가합니다.
페이지네이션은 데이터베이스가 건강해도 API가 느리게 느껴지는 부분입니다. 페이지네이션을 UI 세부사항이 아니라 쿼리 설계 문제로 취급하세요.
LIMIT/OFFSET는 단순해 보이지만 깊은 페이지는 비용이 더 듭니다. Postgres는 건너뛴 행을 지나쳐야 하고 종종 정렬도 수행해야 합니다. 페이지 1은 몇십 행만 건드리지만 페이지 500은 수만 행을 스캔하고 버려야 할 수 있습니다.
또한 요청 사이에 행이 삽입/삭제되면 결과가 불안정할 수 있습니다. 사용자는 중복을 보거나 항목을 놓칠 수 있습니다.
키셋 페이지네이션은 "내가 마지막으로 본 행 이후의 다음 20개를 달라"는 질문을 합니다. 이렇게 하면 DB는 항상 작고 일관된 부분만 작업합니다.
간단한 버전은 증가하는 id를 사용합니다:
SELECT id, created_at, title
FROM posts
WHERE id > $1
ORDER BY id
LIMIT 20;
API는 페이지의 마지막 id를 next_cursor로 반환합니다. 다음 요청은 그 값을 $1로 사용합니다.
시간 기반 정렬의 경우 안정적인 순서와 동점 끊기 규칙을 사용하세요. created_at만으로는 두 행이 같은 타임스탬프를 가질 수 있으므로 복합 커서를 사용합니다:
WHERE (created_at, id) < ($1, $2)
ORDER BY created_at DESC, id DESC
LIMIT 20;
중복과 누락을 방지하는 몇 가지 규칙:
ORDER BY에 고유한 tie-breaker(보통 id) 포함created_at과 id를 함께 인코딩)의외로 API가 느리게 느껴지는 흔한 이유는 DB가 아니라 응답 자체입니다. 큰 JSON은 생성, 전송, 파싱에 시간이 더 들고, 따라서 가장 빠른 개선은 반환 데이터를 줄이는 것입니다.
SELECT부터 시작하세요. 엔드포인트에 id, name, status만 필요하면 그 컬럼들만 요청하세요. SELECT *는 테이블에 긴 텍스트, JSON 블롭, 감사 컬럼이 추가되며 조용히 무거워집니다.
또 다른 흔한 느려짐은 N+1 응답 생성입니다: 50개 항목 리스트를 가져오고 각 항목에 대해 50개의 추가 쿼리를 실행하는 식입니다. 테스트를 통과하다가 실제 트래픽에서 무너집니다. 가능한 한 한 번의 쿼리(주의 깊은 조인)로 필요한 것을 반환하거나 ID로 배치하는 두 번째 쿼리를 사용하세요.
페이로드를 작게 유지하면서도 클라이언트를 깨지지 않게 만드는 방법:
include= 플래그(또는 fields=)를 사용해 리스트 응답은 가볍게 유지하고 디테일 응답은 추가 필드를 선택적으로 포함둘 다 빠를 수 있습니다. 무엇을 최적화할지에 따라 선택하세요.
Postgres의 JSON 함수(jsonb_build_object, json_agg)는 왕복을 줄이고 한 쿼리에서 예측 가능한 형태로 반환할 때 유용합니다. Go에서 구조체를 사용해 조립하는 것은 조건부 로직, 구조체 재사용, SQL 가독성 유지 관점에서 유리합니다. SQL로 JSON 빌드가 복잡해지면 튜닝도 어려워집니다.
좋은 규칙은: Postgres로 필터, 정렬, 집계를 하고 Go로 최종 표현을 처리하는 것입니다.
AI로 빠르게 API를 생성한다면(예: Koder.ai 사용 시) 초기에 include 플래그를 추가해 엔드포인트가 시간이 지나며 부풀어 오르는 것을 피하세요. 또한 필드를 추가할 때 모든 응답을 무겁게 만들지 않는 안전한 방법을 제공합니다.
큰 테스트 실험실이 없어도 대부분의 성능 문제를 잡을 수 있습니다. 짧고 반복 가능한 패스가 트래픽이 생길 때 아웃리지를 유발할 문제들을 드러냅니다. 특히 시작점이 생성된 코드라면 더더욱 그렇습니다.
무엇이든 바꾸기 전에 작은 기준선을 적어두세요:
작게 시작하고 한 번에 하나씩 바꾸며 각 변경 후 재테스트하세요.
실제 사용과 비슷한 10~15분짜리 부하 테스트를 실행하세요. 초기 사용자가 사용할 엔드포인트(로그인, 리스트, 검색, 생성)를 타겟으로 하세요. 그런 다음 라우트를 p95 지연과 총 시간으로 정렬하세요.
SQL 튜닝 전에 연결 압력을 확인하세요. 풀이 너무 크면 Postgres를 압박합니다. 풀이 너무 작으면 긴 대기가 생깁니다. 획득 대기 시간이 올라가고 연결 수가 버스트 중에 스파이크하는지 확인하세요. 먼저 풀과 idle 한계를 조정한 뒤 동일한 부하로 재실행하세요.
상위 느린 쿼리에 대해 EXPLAIN을 실행하고 가장 큰 적신호를 고치세요. 일반적 원인은 큰 테이블의 전체 스캔, 큰 결과 집합에서의 정렬, 폭발적으로 증가하는 조인입니다. 최악의 쿼리 하나를 고르고 지루하게 만드세요.
인덱스를 하나 추가하거나 조정한 뒤 재테스트하세요. 인덱스는 WHERE와 ORDER BY에 맞을 때 도움이 됩니다. 한 번에 다섯 개를 추가하지 마세요. 예: "사용자별 주문을 생성 시간으로 정렬하는 리스트"라면 (user_id, created_at) 같은 복합 인덱스 하나가 즉각적인 차이를 만들 수 있습니다.
응답과 페이지네이션을 간결하게 만들고 다시 테스트하세요. 엔드포인트가 큰 JSON 블롭 50개를 반환하면 DB, 네트워크, 클라이언트가 모두 비용을 지불합니다. UI에 필요한 필드만 반환하고 테이블이 커져도 느려지지 않는 페이지네이션을 선호하세요.
단순한 변경 로그를 유지하세요: 무엇을 바꿨고, 왜 바꿨고, p95가 어떻게 변했는지. 변경이 기준선을 개선하지 않으면 되돌리고 다음으로 넘어가세요.
대부분의 Go + Postgres 성능 문제는 자체 유발입니다. 좋은 소식은 몇 가지 점검으로 대부분을 출시 전에 잡을 수 있다는 것입니다.
고전적인 함정은 풀 크기를 속도 조절 다이얼처럼 다루는 것입니다. "가능한 한 크게" 설정하면 대부분 더 느려집니다. Postgres는 세션, 메모리, 락을 관리하는 데 더 많은 시간을 쓰고 앱은 파도처럼 타임아웃을 맞습니다. 안정적이고 예측 가능한 작은 풀과 적절한 동시성 제어가 보통 더 낫습니다.
또 다른 실수는 "모든 것 인덱싱"입니다. 인덱스가 읽기에는 도움이 되지만 쓰기를 느리게 하고 쿼리 플랜을 예기치 않게 바꿀 수 있습니다. 인덱스를 추가하기 전후를 측정하고, 인덱스를 추가한 후 플랜을 다시 확인하세요.
페이지네이션 부채는 조용히 쌓입니다. 오프셋 페이지네이션은 초반에 괜찮아 보이지만 테이블이 커지면 p95가 서서히 올라갑니다.
JSON 페이로드 크기도 숨은 비용입니다. 압축은 대역폭을 줄이지만 큰 객체를 생성하고 할당하고 파싱하는 비용은 사라지지 않습니다. 필드를 줄이고 깊은 중첩을 피하며 화면에 필요한 것만 반환하세요.
평균 응답 시간만 보면 실제 사용자 고통 지점을 놓칩니다. p95(때때로 p99)가 풀 포화, 락 대기, 느린 플랜이 먼저 드러나는 곳입니다.
간단한 사전 출시 셀프 체크 목록:
EXPLAIN을 다시 실행하세요.실제 사용자가 오기 전에 API가 스트레스 상황에서 예측 가능하게 유지된다는 증거가 필요합니다. 목표는 완벽한 수치를 얻는 것이 아니라 타임아웃, 스파이크, 또는 DB가 새로운 작업을 받아들이지 못하게 하는 몇 가지 문제를 찾아내는 것입니다.
프로덕션과 비슷한 스테이징 환경(비슷한 DB 크기 범위, 동일한 인덱스, 동일한 풀 설정)에서 확인하세요: 주요 엔드포인트별 p95 지연을 측정하고, 총 시간 기준 상위 느린 쿼리를 캡처하고, 풀 대기 시간을 관찰하고, 최악 쿼리에 대해 EXPLAIN (ANALYZE, BUFFERS)를 실행해 예상대로 인덱스를 사용하는지 확인하고, 가장 바쁜 라우트의 페이로드 크기를 점검하세요.
그런 다음 제품이 깨지는 방식 하나를 가장 나쁘게 시뮬레이션해 보세요: 깊은 페이지 요청, 가장 광범위한 필터 적용, 콜드 스타트(API를 재시작하고 같은 요청을 처음으로 호출) 등. 깊은 페이지네이션이 페이지를 넘어갈수록 더 느려지면 출시 전에 커서 기반 페이지네이션으로 전환하세요.
팀이 일관된 선택을 하도록 기본값을 문서화하세요: 풀 제한 및 타임아웃, 페이지네이션 규칙(최대 페이지 크기, 오프셋 사용 허용 여부, 커서 형식), 쿼리 규칙(필요한 컬럼만 선택, SELECT * 금지, 비용 큰 필터 제한), 로깅 규칙(느린 쿼리 임계값, 샘플 보관 기간, 엔드포인트 라벨링 방식).
Koder.ai로 Go + Postgres 서비스를 생성하고 내보낸다면, 배포 전에 짧은 계획 패스를 거쳐 필터, 페이지네이션, 응답 형태를 의도적으로 설계하면 도움이 됩니다. 인덱스와 쿼리 형태를 튜닝하기 시작하면 스냅샷과 롤백이 한 엔드포인트에는 도움이 되지만 다른 엔드포인트에는 해를 끼칠 수 있는 “수정”을 되돌리기 쉽게 만듭니다. 워크플로우를 한 곳에서 반복하려면 Koder.ai(도메인 koder.ai)는 채팅으로 서비스를 생성하고 개선한 뒤 준비되면 소스 코드를 내보내도록 설계되어 있습니다.
DB 대기 시간과 애플리케이션 작업 시간을 분리하는 것부터 시작하세요.
“연결 획득 대기”와 “쿼리 실행”에 대한 간단한 타이밍을 추가해 어느 쪽이 지배적인지 확인하세요.
반복 가능한 작은 기준선을 만드세요:
예: “50 동시 사용자에서 p95가 200ms 미만이고 오류율은 0.5% 미만.” 같은 명확한 목표를 정하세요. 그런 다음 한 번에 하나씩만 바꾸고 동일한 요청 믹스로 재측정합니다.
사전 출시 테스트에서 낮은 임계값(예: 100–200ms)으로 느린 쿼리 로깅을 켜고 전체 문장을 남겨 SQL 클라이언트로 복사해 실행할 수 있게 하세요.
임시로 사용하세요:
최악의 쿼리를 찾은 뒤에는 샘플링으로 전환하거나 임계값을 올리세요.
실무적 기본값은 API 인스턴스 당 CPU 코어의 작은 배수입니다. 보통 최대 5–20개의 open connection, 유사한 수의 idle connection 유지, 연결을 30–60분 주기로 재활용하는 것이 안전한 출발점입니다.
두 가지 일반적 실패 양상:
풀은 인스턴스 수와 곱해진다는 점을 기억하세요(20 × 10 = 200).
DB 호출을 두 부분으로 시간 측정하세요:
대부분이 풀 대기라면 풀 크기, 타임아웃, 인스턴스 수를 조정하세요. 대부분이 쿼리 실행이라면 EXPLAIN과 인덱스에 집중해야 합니다.
또한 항상 rows를 닫아 연결이 풀로 즉시 반환되도록 확인하세요.
EXPLAIN (ANALYZE, BUFFERS)를 실제 API가 보내는 정확한 SQL로 실행하고 다음을 확인하세요:
ORDER BY와 함께 Sort가 시간을 많이 쓰는 경우가장 큰 문제부터 고치세요; 한 번에 모든 것을 튜닝하지 마세요.
엔드포인트가 실제로 하는 것(필터 + 정렬)에 맞춰 인덱스를 만들어야 합니다.
기본 접근법:
WHERE + ORDER BY 패턴에 대한 복합 인덱스를 만드세요.예: user_id로 필터링하고 최신순 정렬을 자주 한다면 (user_id, created_at DESC) 같은 인덱스가 p95를 안정시키는 차이가 됩니다.
대부분 트래픽이 예측 가능한 부분 집합에 몰리면 partial index가 유용합니다.
예: 대부분이 active = true인 행을 읽는다면 ... WHERE active = true 같은 partial index는 인덱스를 작게 유지해 메모리에 더 잘 들어가고 전체 인덱싱보다 쓰기 오버헤드가 적습니다.
항상 EXPLAIN으로 Postgres가 실제로 해당 쿼리에 인덱스를 사용하는지 확인하세요.
LIMIT/OFFSET는 깊은 페이지에서 비용이 급격히 증가합니다. Postgres는 건너뛴 행을 여전히 지나쳐야 하므로 페이지가 깊어질수록 더 많은 행을 검토하거나 정렬해야 합니다.
대신 키셋(커서) 페이지네이션을 사용하세요:
id) 사용ORDER BY를 동일하게 유지(created_at, id) 같은 복합 값을 커서로 인코딩이렇게 하면 테이블이 커져도 각 페이지의 비용이 거의 일정합니다.
대부분의 경우 리스트 엔드포인트에서 JSON 페이로드를 줄이는 것이 정답입니다. 보내지 않는 응답이 가장 빠릅니다.
실무적 방법:
include= 또는 fields=를 제공하세요.페이로드를 줄이면 Go CPU, 메모리 압박, 꼬리 지연을 크게 낮출 수 있습니다.