워드프레스는 요청이 시작될 때 wp_options 에서 autoload 로 표시된 행을 한 번에 전부 읽어 메모리에 올립니다. 옵션 조회가 빠른 이유가 이것입니다 — 대부분의 옵션은 이미 거기 있습니다.
이 설계의 대가는 명확합니다. 어떤 플러그인이 큰 값을 autoload 로 넣으면 그 페이지를 쓰지 않는 요청에서도 그 값이 읽히고 역직렬화됩니다. 화면 어디에도 표시되지 않고, 특정 기능이 느린 것도 아니어서, “전체적으로 조금씩 무겁다” 는 형태로만 드러납니다.
목록을 뽑습니다
추측하지 않고 잽니다. WP-CLI 로 총량과 상위 항목을 각각 확인합니다.
# autoload 전체 크기
wp option list --autoload=on --format=total_bytes
# 큰 것부터 20개
wp option list --autoload=on --fields=option_name,size_bytes
--orderby=size_bytes --order=desc --format=table | head -20
CLI 를 쓸 수 없는 환경이라면 같은 답을 SQL 로 얻습니다.
SELECT option_name, LENGTH(option_value) AS bytes
FROM wp_options
WHERE autoload IN ( 'yes', 'on', 'auto-on', 'auto' )
ORDER BY bytes DESC
LIMIT 20;
최근 코어는 autoload 값을 yes/no 두 가지가 아니라 명시 지정과 자동 판정으로 나눠 저장합니다. 크기가 임계를 넘는 옵션은 코어가 알아서 자동 로드에서 빼 주지만, 플러그인이 명시적으로 지정한 값에는 그 판정이 적용되지 않습니다. 그래서 감시는 여전히 필요합니다.
상위 목록에서 무엇을 보나
여기서 오브젝트 캐시가 해결해 준다는 기대는 접습니다. Redis 가 있으면 전체 옵션 묶음이 캐시되긴 하지만, 그 묶음 자체가 커지면 요청마다 큰 값을 가져와 역직렬화하는 비용은 그대로입니다. 캐시가 위치를 옮겼을 뿐 크기를 줄이지 않았습니다.
고치는 순서 — 지우기 전에 확인합니다
범인을 찾았다고 바로 삭제하지 않습니다. 그 값을 쓰는 코드가 있으면 다음 요청에 다시 만들어지고, 원인은 그대로 남습니다.
출처는 옵션 이름으로 코드베이스를 검색하면 대개 바로 나옵니다. 쓰이지 않는 잔재라면 삭제하고, 쓰이지만 매 요청에 필요하지는 않다면 값은 두고 autoload 만 내립니다.
# 값은 그대로, 자동 로드만 해제 (최근 코어)
wp eval "wp_set_option_autoload( 'acme_big_blob', false );"
# 그 이전 코어라면 세 번째 인자를 false 로 다시 저장
wp eval "update_option( 'acme_big_blob', get_option( 'acme_big_blob' ), false );"
플러그인이 계속 autoload 로 다시 쓴다면 그것은 플러그인 쪽 결함입니다. 제작자에게 보고하고, 답이 없다면 그 플러그인을 계속 쓸지 판단할 근거가 하나 생긴 셈입니다.
마지막으로 이 확인을 정기 항목으로 만듭니다. autoload 총량은 한 번 정리해도 플러그인이 늘면 다시 자랍니다. 사이트 상태를 주기적으로 점검하는 구성은 InfraGuard 이용권에서 다루고, 관련 글은 성능 최적화 아카이브에 모여 있습니다.
다음 회차
서버 쪽 비용을 정리했으니 마지막은 브라우저 쪽입니다. 다음 회차는 프론트엔드 예산 — 자산 크기에 상한을 정하고 실제로 지키는 방법입니다.