개인 개발 바이크 사이트의 Google 코어 업데이트로 인한 DAU 폭락 및 4개월간의 회복 기록
요약
개인 개발 바이크 사이트가 Google March 2026 Core Update 이후 DAU가 420에서 150으로 급락한 경험을 기록하고, 폭락 후 4개월간의 회복 과정을 공유합니다. 주요 원인은 콘텐츠의 깊이 부족(재고 테이블만 나열), 약한 도메인 파워, 품절 페이지 처리 미흡, 크롤링 예산 낭비 등 네 가지로 분석했습니다. 이후 품절 페이지 개선 및 SEO 기반 수정 작업을 통해 트래픽을 회복하는 과정을 다룹니다.
핵심 포인트
- Google Core Update는 사이트의 콘텐츠 깊이와 사용자 경험(helpful content)에 매우 민감하게 반응한다.
- 대량으로 생성된 얇은 콘텐츠(thin content)는 좋은 페이지까지 끌어내릴 수 있으므로, 모든 페이지에 충분한 가치를 부여해야 한다.
- 품절 차량 페이지를 단순히 '품절'로 처리하는 대신, 대체 정보나 유사 차종 제안을 제공하여 사용자 경험을 개선하고 SEO적으로 관리해야 한다.
- 사이트의 구조적 문제(예: 크롤링 예산 낭비)부터 해결하며 점진적인 회복 전략을 세우는 것이 중요하다.
서론
이전 기사에서 「개인 개발 바이크 사이트를 3개월 만에 DAU 420까지 성장시킨 이야기」를 작성했습니다.
그로부터 1개월 후인 2026년 3월 27일. Google March 2026 Core Update가 시작되었습니다.
4월 초순, Google Search Console을 열었을 때의 충격은 지금도 잊을 수 없습니다.
DAU 420 → 150.
노출수는 절반 이하, 클릭수는 3분의 1. 쌓아온 것들이 순식간에 무너지는 기분이었습니다.
이 기사에서는 폭락한 후 4개월 동안 무엇을 했고, DAU 200까지 회복했는지에 대한 모든 기록을 작성합니다. 「회복했습니다!」라는 깔끔한 이야기가 아니라, 아직 420에는 도달하지 못한 현재 진행형의 리얼한 기록입니다.
무슨 일이 일어났는가 — 숫자로 보는 폭락
Before (3월 26일 시점)
| 지표 | 수치 |
|---|---|
| DAU | 420 |
| ... |
After (4월 둘째 주)
| 지표 | 수치 | 변화 |
|---|---|---|
| DAU | 150 | -64% |
| 월간 노출수 | 약 52,000 | -57% |
| 월간 클릭수 | 약 800 | -75% |
| 평균 게재 순위 | 38위 | +12위 악화 |
특히 심각했던 것은 차종 모델 페이지 (/bikes/catalog/{slug})와 숍 페이지 (/shops/{slug})였습니다. 이 두 카테고리만으로 전체 트래픽의 7할을 차지하고 있었기에, 이곳이 떨어지면 전체가 붕괴합니다.
하락한 페이지의 특징
하락한 페이지의 공통점은 "숫자의 나열일 뿐, 읽을 가치가 없다"는 것이었습니다.
차종 페이지의 예:
- 재고 목록 테이블만 있음
- 차종의 역사나 특징에 대한 설명이 제로(0)
- FAQ 없음, 관련 콘텐츠 없음
- 사용자가 "흐음" 하고 떠나버릴 뿐인 페이지
Google이 말하는 "helpful content (도움이 되는 콘텐츠)"와 정반대였습니다.
원인 분석 — 4가지 문제
폭락 후, 1주일에 걸쳐 원인을 분석했습니다.
문제 1: 페이지 품질이 낮음 (가장 큰 원인)
4,569개 차종 × 47개 도도부현 = 약 21만 페이지를 생성하고 있었으나, 내용은 재고 테이블과 기본 스펙뿐이었습니다. 콘텐츠의 "두께"가 제로(0)였습니다.
Google의 helpful content system (도움이 되는 콘텐츠 시스템)은 사이트 전체의 품질을 평가합니다. 얇은 페이지가 대량으로 있으면 좋은 페이지까지 함께 끌려 내려갑니다.
문제 2: 도메인 파워가 약함
외부로부터의 백링크는 약 10건. 개인 개발 사이트이기에 당연하지만, 코어 업데이트에서는 E-E-A-T (경험·전문성·권위성·신뢰성)가 중시됩니다. 도메인 파워가 약한 사이트는 영향을 받기 쉽습니다.
문제 3: 품절 페이지 처리
품절된 차량 페이지(수만 페이지)를 200 OK로 반환하면서, 내용은 "이 차량은 품절되었습니다"라는 한 문장뿐이었습니다. 이것이 대량의 저품질 페이지로 평가되었을 가능성이 있습니다.
문제 4: 크롤링 예산 (Crawl Budget)의 낭비
검색 결과 페이지 (/bikes/search?...)에 noindex를 설정하지 않았던 시기가 있어, 파라미터가 다른 대량의 페이지가 인덱싱되어 있었습니다.
실행한 내용 ① — SEO 기반 수정 (4월 전반기)
패닉에 빠지지 않고, 우선 기반부터 고쳤습니다.
품절 페이지 개선
Before: "품절되었습니다" 텍스트만 있음
After: 동일 차종의 재고 목록 · 유사 차종 제안 · 시세 정보 표시
품절 → 404가 아닌 200으로 반환
단, 재고 0대의 차종 페이지 → noindex 추가
재고가 있는 차종의 품절된 개별 페이지는 200으로 반환하고 대체 정보를 충실히 제공합니다. 재고가 완전히 0인 차종 페이지에 대해서만 noindex를 적용합니다. 이 판단이 정답이었습니다.
검색 결과 페이지에 noindex 적용
// 모든 search 결과 페이지에 noindex
<meta name="robots" content="noindex, follow">
이것만으로도 Google이 크롤링해야 할 페이지가 명확해집니다.
JSON-LD 구조화 데이터 대량 추가
12종류의 JSON-LD 컴포넌트를 작성:
Website— 사이트 전체Product— 개별 차량LocalBusiness— 바이크 숍FAQPage— FAQ (후술할 AI 생성)BreadcrumbList— 브레드크럼 (Breadcrumb List)
— 브레드크럼 리스트 (6가지 패턴) -
BlogPosting
— 블로그 게시물 -
ParkingFacility
— 주차 시설
resources/views/components/jsonld/
├── website.blade.php
├── product.blade.php
...
IndexNow 설정
사이트맵(Sitemap)을 생성할 때마다 IndexNow를 통해 Bing/Yandex에 알리도록 설정했습니다. Google은 지원하지 않지만, Bing으로부터 오는 트래픽도 무시할 수 없습니다.
// GenerateSitemap.php 의 마지막 부분
$this->info('IndexNow에 알리는 중...');
// 사이트맵 URL을 IndexNow API로 전송
실행 내용 ② — AI를 활용하여 콘텐츠를 단번에 보강하기 (4월 후반)
여기서부터가 승부처였습니다. 4,569종의 차종 페이지를 수동으로 충실하게 만드는 것은 물리적으로 불가능합니다. AI를 사용합니다.
Claude Sonnet 4로 콘텐츠 자동 생성
두 가지 Artisan 명령어를 생성했습니다:
# 차종의 특징·매력·고르는 법 생성
php artisan bike:generate-content --chunk=50
# 차종의 역사·계보 생성
...
메커니즘:
- 차종명·배기량·카테고리·재고 수량·가격대를 프롬프트(Prompt)에 포함
- Claude Sonnet 4 (
claude-sonnet-4-20250514)로 500~800자 분량의 콘텐츠 생성 enriched_content컬럼 (JSON)에 저장- 재고가 5대 이상인 차종을 우선 처리
2,000종의 차종을 처리했습니다. API 비용은 약 ¥12,000.
사람이 작성했다면 몇 달이 걸렸을 작업을 3일 만에 완료했습니다.
FAQ 자동 생성 + FAQPage JSON-LD
AI가 생성한 콘텐츠에서 FAQ를 추출하여 구조화 데이터(Structured Data)로 출력합니다:
// enriched_content가 있는 경우 AI 생성 FAQ
// 없는 경우 템플릿 FAQ
@if($model->enriched_content)
...
이를 통해 검색 결과에 FAQ 리치 스니펫(Rich Snippet)이 표시되기 시작했습니다. CTR(클릭률)이 눈에 띄게 개선되었습니다.
YouTube 영상 임베딩
php artisan youtube:fetch --limit=500
YouTube Data API로 차종명을 검색하여 리뷰 영상을 DB에 캐시(7일 TTL)합니다. 차종 페이지에 영상 섹션을 추가했습니다.
체류 시간이 늘어남 → 페이지 품질(Page Quality) 시그널 개선.
차종 페이지 UI 대폭 개편
Before: 스펙 표 + 재고 목록 (2개 섹션)
After: 6개 탭 구성
- 재고 목록 (기존)
- 시세 분석 — 연식별·주행 거리별 가격 차트
- 스펙 — 레이더 차트로 시각화
- 리뷰 — 사용자 리뷰
- 영상 — YouTube 임베딩
- FAQ — AI 생성 FAQ
Chart.js 차트는 지연 로딩(Lazy Loading) + 폴링(Polling) 방식으로 렌더링합니다:
// Chart.js 로딩을 기다리는 폴링 (10초 타임아웃)
var attempts = 0;
var timer = setInterval(function() {
...
왜 폴링인가?
Chart.js를 <script defer>로 로드하고 있지만, DOMContentLoaded 타이밍과 Chart.js 로딩 완료 시점이 일치하지 않는 문제로 세 번이나 고생했습니다. IntersectionObserver + DOMContentLoaded + 콜백 등록 조합을 모두 시도해 보았으나 실패했습니다. 결국 단순한 setInterval이 가장 확실했습니다.
실행 내용 ③ — 콘텐츠의 범위를 넓히기 (4월~5월)
SEO 기반이 갖춰진 후에는 콘텐츠의 "면"을 넓힙니다.
블로그 기능을 Laravel로 풀 스크래치(Full Scratch) 구현
WordPress를 사용하지 않고, Laravel 내부에 블로그 시스템을 구축했습니다.
왜 풀 스크래치인가?
- 동일한 도메인·동일한 디자인으로 통일감을 주고 싶음
- 내부 링크(Internal Link)를 자유롭게 걸고 싶음
- BlogPost → BikeModel의 관계(Relation)를 활용하고 싶음
- Markdown 기반으로 GitHub에서 관리하고 싶음
구현 규모:
| 카테고리 | 파일 수 |
|---|---|
| Model (BlogPost, BlogSeries, BlogTag) | 5 |
| ... | 합계 |
| 약 30개 파일 |
주요 기능:
- Markdown → HTML 렌더링 (Rendering)
- 시리즈 및 태그 관리
- OGP 이미지 동적 생성 (Intervention Image)
- RSS/Atom 피드
- 완독 시간 자동 계산 (일본어 기준: 500자/분)
[riders-map]숏코드(Shortcode)로 지도 임베딩 - 초안/공개/예약 발행
현재 18개의 기사를 공개. 모두 실제 판매 데이터에 기반한 데이터 드리븐 (Data-driven) 기사입니다.
투어링 스폿 · 미치노에키(道の駅) 페이지 생성
touring_spots: 279건 (전국의 투어링 스폿)
roadside_stations: 124건 (미치노에키)
47개 도도부현별 인덱스 페이지 + 각 스폿의 상세 페이지. 사이트맵(Sitemap)에도 추가하고, 내부 링크(Internal Link)로 메인 콘텐츠와 연결.
라이더스 맵 (POI 4.9만 건)
주차장 3,569건, 역 9,032건, 미치노에키 124건, 기타 POI를 포함하여 약 4.9만 건의 위치 정보를 맵에 표시. Google Maps API 기반의 인터랙티브 맵 (Interactive Map)입니다.
이것만으로는 SEO 효과가 제한적이지만, 사이트 체류 시간과 페이지 순회율에 효과가 있습니다.
카테고리 LP 16페이지
프로그래매틱 SEO (Programmatic SEO):
배기량별: 50cc / 125cc / 250cc / 400cc / 대형 / 리터
타입별: 네이키드 / 스포츠 / 아메리칸 / 오프로드 /
스쿠터 / 어드벤처 / 클래식 / 투어러 /
...
각 페이지에 KPI 6개 항목(재고 수, 평균 가격, 최저가, 인기 차종 등), 가격 분포 차트, 인기 차종 랭킹을 자동 생성.
뉴스 페이지 완전 구현
바이크 업계의 뉴스를 자동 수집·표시하는 페이지:
php artisan news:fetch # 뉴스 자동 취득
php artisan news:thumbnails # 썸네일 취득
php artisan news:ranking # 랭킹 뉴스 생성
현재 518건의 뉴스를 게재. 모델별 뉴스 필터링, 댓글 기능, '좋아요' 기능도 구현. 뉴스 페이지 자체는 직접적인 SEO 효과가 낮지만, 사이트의 '신선함'을 Google에 전달하는 시그널 (Signal)이 됩니다.
에리어 LP 품질 향상
기존의 /bikes/area/{pref}/{slug} 페이지 (도도부현 × 차종)를 대폭 개선:
- 타이틀 개선 ("{현}의 {차종} 중고차" → "{현}의 {차종} 재고 {N}대 | 평균 ¥XX만~")
- KPI 6개 항목 추가
- 가격 분포 · 연식 분포 차트
- 관련 에리어로의 내부 링크
- JSON-LD 강화
했던 일 ④ — SEO 이외의 DAU 시책
Google에만 의존하는 것은 위험하다는 것을 뼈저리게 느꼈기에, 다른 채널도 개척.
Yahoo! 지혜주머니 (Yahoo! 知恵袋)
바이크 관련 질문에 매일 2~3건 답변. 프로필에 MotoHub 링크를 설치.
포인트:
- "중고 바이크 시세", "250cc 추천" 계열의 질문을 공략
- 답변 마지막에 "자세한 시세 데이터는 이쪽으로"라며 링크 삽입
- 베스트 답변을 다수 획득 → 도메인 파워 (Domain Power)의 미세한 증가
X (Twitter) 답글 (Reply)
바이크 구매를 검토 중인 사람의 포스트에 매일 10건 답글. 봇 (Bot)이 아닌 수동으로, 정말 도움이 되는 정보를 곁들여서.
Twitter/X Bot (자동 게시)도 가동 중:
# 7개의 Artisan Command
php artisan tweet:new-stock # 신착 재고
php artisan tweet:price-drop # 가격 하락
...
Google Discover 대응
블로그 기사를 Discover에 노출시키기 위해:
<!-- layout.blade.php -->
<meta name="robots" content="max-image-preview:large, max-snippet:-1, max-video-preview:-1">
- 1200×630px의 OGP 이미지를 모든 기사에 설정
- Article JSON-LD의
image필드를 반드시 출력 - 감정을 움직이는 타이틀 ("22만 대의 데이터로 밝혀진~")
LINE 푸시 알림 (Push Notification)
즐겨찾기 차종의 가격 인하를 LINE Messaging API로 알림:
// Flex Message로 리치 카드(Rich Card) 전송
$service = new LineNotificationService();
$service->sendPriceDropAlert($user, $listing, $priceDiff);
해낸 일 ⑤ — 인프라 개선
VPS 4GB → 8GB
페이지 표시 속도가 SEO에 영향을 미치기 때문에 메모리를 두 배로 증설. 특히 Meilisearch가 메모리를 많이 사용하기 때문.
Redis AOF 영속화 (Persistence)
캐시가 사라지면 랭킹 페이지 등이 일시적으로 에러가 발생하는 문제가 있었기에, AOF 영속화를 설정.
Meilisearch 차분 동기화 (Incremental Sync)
전체 데이터 동기화에서 needs_reindex 플래그 방식으로 변경. 16만 건의 전체 동기화는 너무 무거웠음.
4개월간의 커밋 로그 (Commit Log)
숫자로 되돌아보면:
| 기간 | 커밋 수 | 주요 내용 |
|---|---|---|
| 4월 전반기 | 약 80 | SEO 기반 수정, noindex, JSON-LD |
| ... | 합계 | 약 300 |
760개 커밋 중 300개 커밋이 이 4개월에 집중됨. 하루 평균 6개 커밋. 일을 하면서 진행하는 개인 개발로서는 상당한 페이스.
기술 스택 (Tech Stack) 전체 모습
최종적으로 다음과 같이 구성되었습니다:
Backend: Laravel 12 (PHP 8.3)
Frontend: Blade + Alpine.js + Tailwind CSS v3
React (Quiz/Game용 Island Architecture)
...
| 항목 | 수치 |
|---|---|
| PHP 파일 (app/) | 302 |
| ... |
현재 위치 (2026년 5월)
GSC(Google Search Console) 수치
| 지표 | 폭락 전 | 최저치 | 현재 |
|---|---|---|---|
| DAU | 420 | 150 | 200 |
| ... |
평균 순위는 26위 → 10.7위로 대폭 개선. 하지만 DAU는 아직 420의 절반 이하.
이것은 무엇을 의미하는가?
노출 횟수가 돌아오지 않았다. 즉, Google에 인덱싱(Indexing)된 페이지의 '평가'는 올라갔지만, '게재되는 쿼리(Query)의 폭'이 돌아오지 않았다. 코어 업데이트(Core Update)의 영향은 아직 남아 있습니다.
DB 현재 값
| 데이터 | 건수 |
|---|---|
| 차종 마스터 | 4,569 |
| ... |
배운 점
1. Google에 의존하는 리스크
DAU 420 시점에 "순조롭다!"라고 생각했던 자신이 안일했다. Google 검색이 유일한 트래픽 소스였기에, 코어 업데이트 한 번에 거의 전멸.
교훈: 트래픽 소스를 분산할 것. SNS, 지식인(Chiebukuro), 푸시 알림, 뉴스레터. 하나의 채널에 7할 이상 의존해서는 안 된다.
2. 얇은 콘텐츠(Thin Content) 페이지는 부채가 된다
프로그래매틱 SEO (Programmatic SEO)로 대량의 페이지를 만드는 것은 쉽다. 하지만 내용이 없다면 Google에서 평가받지 못할 뿐만 아니라, 사이트 전체의 평가를 떨어뜨린다.
교훈: 페이지를 만들기 전에 "이 페이지에 온 사람이 만족할 것인가?"를 자문할 것. 아니라면 noindex 처리하거나 Not Found 처리할 것.
3. 개인 개발이라도 데이터는 무기가 된다
16만 대의 재고 데이터는 대형 미디어에는 없는 무기. "22만 대의 데이터 분석"이라는 접근 방식은 사용자에게도 Google에게도 먹힌다.
중고 바이크의 평균 판매 일수가 41일이라거나, 1~2만 km가 가장 가성비가 좋다는 등의 데이터는 실제로 플랫폼을 운영하고 있지 않으면 내놓을 수 없다.
4. Claude Code가 개발 속도를 바꾸었다
4개월 동안 300 커밋이라는 비정상적인 페이스는, Claude Code 없이는 불가능했습니다.
구체적인 예:
- 블로그 기사 데이터 수집 (DB 쿼리 6개) → 기사 생성 (Anthropic API) → 차트 이미지 생성 (QuickChart) → BlogPost 저장. 이 일련의 작업을 기사 1개당 15분 만에 완료
- JSON-LD 컴포넌트 12종 구현에 반나절
- 카테고리 LP 16페이지 생성 로직에 2시간
- 차종 페이지 UI 개편 (6개 탭화)에 1일
"AI에게 일자리를 빼앗긴다"가 아니라, "AI로 한 사람이 10인분의 구현을 할 수 있다"가 정확한 표현.
5. "앞으로 나아가는 느낌이 들지 않는" 시기를 극복하는 법
4월 중순부터 5월 초순까지가 가장 괴로운 시기였습니다. 매일 코드를 작성하고 있음에도 DAU (Daily Active Users)가 150에서 움직이지 않았습니다.
GSC (Google Search Console) 데이터는 2~3일 늦게 반영되고, Google의 재평가에는 수 주가 걸립니다. 이 '효과가 보이지 않는 기간'을 어떻게 보내느냐가 분수령입니다.
저의 경우 커밋(Commit) 수를 지표로 삼았습니다. DAU가 아니라 '오늘은 무엇을 개선했는가'에 초점을 맞췄습니다. 하루 6번의 커밋을 지속하면, 언젠가 Google도 인정해 줄 것이라고 믿으면서 말이죠.
향후 계획
단기 (5~6월): DAU 300 목표
- 블로그 포스팅을 30개로 증대 (현재 18개)
- Google Discover를 통한 트래픽 확보
- 지혜주(Chiebukuro)·X를 통한 백링크 (Backlink) 증가
중기 (7~9월): DAU 500 목표
- 사용자 생성 콘텐츠 (UGC: 리뷰·투어링 리포트)
- 뉴스레터 (Email Magazine)
- LINE 공식 계정 팔로워 확보
장기 (연말): DAU 1,000 목표
- ASP 제휴 (바이크 매입·보험)를 통한 수익화 (Monetization)
- AdSense + 제휴 마케팅 (Affiliate)으로 월 5만 엔 달성
- 트래픽 소스: 검색 40% / SNS 30% / Direct 20% / 기타 10%
마치며
코어 업데이트 (Core Update)로 인해 지표가 폭락하면 솔직히 엄청나게 낙담하게 됩니다. 3개월 동안 쌓아 올린 것이 단 1주일 만에 무너지는 것이니까요.
하지만 되돌아보면, 폭락이 없었다면 이 정도로 진심을 다해 품질 개선에 매진하지 않았을 것입니다. '숫자의 나열뿐인 페이지를 양산하고 있었다'라는 문제를 깨달을 수 있었던 것은 업데이트 덕분입니다.
DAU 200은 아직 지나가는 과정일 뿐입니다. 420을 넘어 500, 1,000으로 늘려가는 과정도 다시 글로 남기겠습니다.
개인 개발로 바이크 사이트를 운영하는 사람은 아마 저뿐일지도 모르지만, 'Google 코어 업데이트에 직격탄을 맞은 개인 개발자'는 산더미처럼 많을 것입니다. 이 글이 누군가에게 참고가 된다면 기쁘겠습니다.
MotoHub: https://motohub.jp
GitHub: ausssxi/MotoHub
X: @motohub_jp
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기