1인 팀 Typing Bears, Claude Code 자율 에이전트로 ISUCON2026 우승
1인 팀 Typing Bears가 2026년 10월 31일 열린 ISUCON2026에서 625,857점으로 우승했습니다. 참가자 Yoshinori Kawasaki는 Claude Code 에이전트를 대회 중 약 8시간 운용하면서 세션에 입력한 지시와 에이전트가 사람을 호출한 횟수가 모두 0회였고, 사전 3개월 동안 평가 문제를 100회 넘게 풀며 사용자 하네스를 개선했다고 밝혔습니다.

1인 팀 Typing Bears가 2026년 10월 31일 열린 ISUCON2026에서 625,857점으로 우승했습니다. 참가자 Yoshinori Kawasaki는 11월 2일 공개한 대회 당일 기록에서 Claude Code 에이전트를 약 8시간 운용했다고 밝혔습니다. 경기 중 참가자가 에이전트 세션에 입력한 지시와 에이전트가 사람을 호출한 횟수는 각각 0회였습니다. 공식 결과표도 Typing Bears의 우승과 최종 점수를 기록했습니다.
Kawasaki는 대회 전 3개월 동안 평가 환경에서 문제를 100회 넘게 풀게 하며 사용자 하네스를 개선했습니다. 하네스는 경기 조건을 에이전트에 전달하고 코드 수정과 부하 측정을 반복하게 하는 실행 도구입니다. 대회 당일에는 준비한 스킬로 에이전트를 띄우고, 조건 문서와 추가 지침을 읽힌 뒤 문제 해결을 맡겼습니다.
ISUCON은 정해진 규칙 안에서 주어진 웹 서비스의 성능을 높이고, 벤치마커가 부하를 줘 계산한 점수로 순위를 정하는 대회입니다. 2026년 문제 ISUReal은 여러 리전에 서버를 둔 사진 SNS였습니다. 초기 구성에서는 모든 애플리케이션 서버가 아시아 리전의 PostgreSQL에 접속했습니다. 리전 사이 왕복 지연은 약 100ms였고, 친구 게시물 목록의 평균 응답 시간은 아시아 서버(asia1)의 약 0.16초에 비해 유럽과 미주 서버에서 약 0.8초였습니다.
에이전트는 벤치마크를 실행해 이용자 수와 응답 시간을 살핀 뒤 데이터 접근 구조를 바꿨습니다. 읽기는 각 서버가 보유한 메모리 사본에서 처리하게 했습니다. 게시물 작성이나 친구 신청처럼 서버 간에 반영할 변경은 asia2가 순서를 정해 파일에 기록하고, 같은 순서로 다른 서버에 전파하도록 구성했습니다. 각 서버가 변경을 같은 순서로 적용해 메모리 사본을 맞추는 방식입니다. 과거 데이터는 바뀌지 않는다는 점을 이용해 읽기 전용 파일로 내보내고, 필요한 부분만 mmap으로 읽었습니다. 이미지 데이터만 13GB였던 반면 서버 메모리는 4GiB였습니다.
데이터 사본을 여러 리전에 두면 변경이 전파되기 전에 다른 서버에서 오래된 값이 보일 수 있습니다. 리전 간 편도 지연이 약 50ms인 점을 반영해, asia2는 쓰기 순서를 정한 시점부터 60ms 기다린 뒤 응답했습니다. 읽기를 맡은 서버는 사본이 ‘현재 시각에서 60ms 전’까지의 변경을 적용했는지 확인한 뒤 결과를 반환했습니다. 로그인과 로그아웃은 예외로, 요청을 받은 서버가 먼저 적용하고 asia2에 전달하되 응답을 기다리지 않았습니다.
앱을 다시 작성한 뒤 이미지 URL 서명 검증에서 벤치마크가 0점을 냈습니다. 기존 방식은 HMAC 계산을 1,000회 반복했는데, 에이전트가 이를 한 번으로 줄이자 벤치마커가 원래 방식으로 서명을 다시 검증하는 단계에서 실패했습니다. 에이전트는 만료 시각을 바꿔 가며 허용 범위를 시험한 뒤, 과거 이미지의 서명은 미리 계산해 조회하고 새 이미지의 서명은 등록 시 한 번 계산하도록 수정했습니다.
이후 에이전트는 nginx를 거치지 않고 Go 애플리케이션이 직접 요청을 받도록 했습니다. 서명 테이블 작성과 nginx 제거를 같은 부하 주행에 반영해 두 변경의 점수 효과를 따로 측정하지는 못했습니다. 프로파일에서는 asia1 CPU 시간의 약 86%가 JPEG 디코딩에 쓰였습니다. 원인은 에이전트가 새 이미지 검사와 기존 검사를 함께 실행해 결과를 비교하도록 둔 디버그 모드였습니다. 기존 검사는 JPEG 전체를 디코딩했지만, 새 검사는 헤더를 읽는 방식이었습니다. 기록에 남은 잘못된 이미지 두 종류에서는 두 검사 모두 거부 판정을 냈고, 에이전트가 디버그 모드를 끄자 점수가 올랐습니다. 다만 헤더가 정상이고 본문이 손상된 JPEG는 새 검사에서 통과할 수 있습니다. 이때 확인한 범위는 벤치마커가 보낸 이미지였습니다.
벤치마커가 확인한 활동 건수에 점수를 매길 때 유럽과 미주 이용자의 활동에는 아시아보다 1.5배의 가중치가 붙었습니다. Kawasaki는 접속 로그를 분석해 과거 게시물을 보는 Memories 활동이 전체 점수의 약 60%를 차지한다고 기록했습니다. 4대 서버의 요청 처리량이 초당 1만~1만1,000건에서 정체된 상황에서 유럽·미주 앱의 CPU 사용률은 20~30%였고 서버 내부 처리 시간도 거의 늘지 않았습니다. 에이전트는 벤치마커 쪽에 병목이 있을 것으로 추정했지만 원인을 확정하지는 못했습니다.
에이전트는 벤치마커의 처리 여력을 유럽과 미주 활동에 더 쓰게 할 수 있는지 시험했습니다. 4대 합계 요청이 초당 6,000건을 넘으면 아시아의 Memories 응답을 150ms 늦춘 실행에서는 유럽과 미주의 조회가 각각 약 2만 회에 이르렀고, 점수는 615,485점이었습니다.
같은 서버 구성으로 부하를 줘도 점수는 크게 달랐습니다. 기록된 12회 결과는 474,987점에서 629,638점까지 분포했고, 변동의 원인은 밝혀지지 않았습니다. 최종 점수는 경기 중 최고점이 아니라 마지막 부하 주행의 점수로 정해졌습니다. 에이전트는 남은 시간과 과거 점수로 더 실행할 수 있는 횟수를 계산하고, 실행을 멈출 기준을 정하는 도구를 사용했습니다. 마지막 주행이 기준을 넘으면 종료하고, 미달하면 한 번 더 실행하는 방식이었습니다. 경기 중 최고점은 629,638점이었으며, 마지막 주행에서 나온 625,857점이 공식 최종 점수로 기록됐습니다.