WordPress

    wp-content/uploads Diski Doldurdu: Küçük Resim Çarpanını Kırma ve Yetim Dosyaları Temizleme

    WordPress uploads klasörünü şişiren küçük resim çarpanını ölçme, gereksiz boyutları kapatma ve yetim dosyaları temizleme rehberi.

    11 dk okuma Güncellendi: 18 Ağustos 2026

    cPanel'in disk kullanımı ekranını açtınız ve tabloyu yukarıdan aşağı okurken bir sayı sizi durdurdu: public_html/wp-content/uploads tek başına 41 GB. Aynı sitenin Ortam ekranı ise 3.180 öğe gösteriyor. Yani görsel başına 13 MB düşüyor — hâlbuki bu siteye hiç kimse 13 MB'lık fotoğraf yüklemedi. Gece yedeği yine "kota aşıldı" diye durdu, eklenti güncellemesi yarıda kesildi, hosting firması da paket yükseltmenizi öneriyor.

    Paketi yükseltmeden önce bilmeniz gereken şey şu: bu 41 GB'ın büyük kısmı sizin yüklediğiniz dosyalar değil, WordPress'in sizin adınıza ürettiği kopyalardır. Tek bir görsel yüklediğinizde diske düşen dosya sayısı 1 değildir; çekirdeğin varsayılan boyutları, temanın add_image_size() ile kaydettiği boyutlar, WooCommerce'in üç ayrı ürün boyutu ve sayfa oluşturucunun kendi türevleri üst üste binince tek fotoğraf 8 ile 15 arasında dosyaya dönüşür. Bu çarpanı hesaplamadan yapılan her temizlik, birkaç ay sonra aynı ekranı yeniden görmenizle biter.

    Bu rehber düzenleme ya da sıkıştırma anlatmıyor; onlar için medya kütüphanesini düzenli tutma ve görsel optimizasyonu yazıları var. Burada dört işi sırayla yapacağız: çarpanı ölçmek, hangi boyutların gerçekten kullanıldığını tespit etmek, yeni yüklemeler için gereksizleri kapatmak, ve diskte duran ama veritabanında karşılığı olmayan yetim dosyaları silmeden önce kanıtlayarak temizlemek.

    Tek Görsel Neden 8-15 Dosyaya Dönüşüyor?#

    WordPress bir görseli yüklerken wp_generate_attachment_metadata() çağrısı içinde, o an kayıtlı olan her ara boyut için ayrı bir dosya üretir. Kayıt listesi birkaç kaynaktan birden beslenir:

    KaynakTipik boyutlarNot
    WordPress çekirdeğithumbnail, medium, medium_large, largemedium_large (768px) ayar ekranında görünmez
    Çekirdek (5.3+)1536x1536, 2048x2048Retina için eklendi, çoğu tema kullanmaz
    Temaadd_image_size() ile 2-8 adetSlider, kart, portfolyo, arşiv görselleri
    WooCommercewoocommerce_thumbnail, woocommerce_single, woocommerce_gallery_thumbnailÜrün başına üç ek dosya
    EklentilerSayfa oluşturucu, slider, galeriKimi eklenti kendi boyutunu sessizce ekler

    Buna bir de WordPress 5.3 ile gelen -scaled davranışı eklenir: 2560 pikselden geniş bir görsel yüklerseniz çekirdek orijinali diskte bırakır ve yanına küçültülmüş bir -scaled kopya üretir. Yani 8 MB'lık bir telefon fotoğrafı daha ilk saniyede iki büyük dosyaya dönüşür.

    Çarpan tehlikeli olan kısımdır, çünkü çarpımsal büyür. 3.000 görselli bir sitede boyut sayısını 14'ten 6'ya düşürmek, 24.000 dosyayı diskten kaldırmak demektir. Bu sadece gigabayt meselesi de değildir: paylaşımlı hostingte dosya sayısı limiti çoğu zaman disk limitinden önce dolar. İki limitin farkı için inode limiti doldu yazısına bakabilirsiniz.

    Kayıtlı Boyutları Listeleyip Çarpanınızı Hesaplama#

    Tahminle çalışmayın. WP-CLI kuruluysa kayıtlı boyutların tamamını tek komutla dökebilirsiniz:

    wp media image-size
    

    Bu komut ad, genişlik, yükseklik ve kırpma bilgisini tablo hâlinde verir. Daha ayrıntılı bir dökümü çekirdek fonksiyonuyla da alabilirsiniz:

    wp eval '
    foreach (wp_get_registered_image_subsizes() as $ad => $b) {
        printf("%-32s %5d x %-5d  kirpma:%s\n", $ad, $b["width"], $b["height"], $b["crop"] ? "evet" : "hayir");
    }'
    

    WP-CLI yoksa aynı listeyi geçici bir mu-plugin ile de yazdırabilirsiniz, ama komut satırı erişimini açmak uzun vadede çok daha rahattır; WP-CLI kullanımı yazısı bu kurulumu anlatıyor.

    Şimdi diskteki gerçek duruma bakalım. WordPress türevleri her zaman -GENİŞLİKxYÜKSEKLİK soneki taşır, bu yüzden onları saymak kolaydır:

    cd ~/public_html/wp-content/uploads
    
    # Toplam dosya sayisi
    find . -type f | wc -l
    
    # Kucuk resim (turev) sayisi
    find . -type f -regextype posix-extended \
      -regex '.*-[0-9]+x[0-9]+\.(jpe?g|png|gif|webp)$' | wc -l
    

    İkinci sayının birinciye oranı çarpanınızdır. Sağlıklı bir sitede türevler toplamın yüzde 70-80'ini oluşturur; yüzde 90'ı aştıysanız kayıtlı boyut listeniz şişmiş demektir.

    Asıl faydalı çıktı ise hangi boyutun ne kadar yer kapladığıdır:

    find . -type f -regextype posix-extended \
      -regex '.*-[0-9]+x[0-9]+\.(jpe?g|png|gif|webp)$' -printf '%s %f\n' \
    | awk '{
        match($2, /-[0-9]+x[0-9]+\./);
        k = substr($2, RSTART + 1, RLENGTH - 2);
        toplam[k] += $1; adet[k]++;
      }
      END {
        for (k in toplam) printf "%-14s %7d dosya %9.1f MB\n", k, adet[k], toplam[k] / 1048576;
      }' | sort -k4 -rn | head -25
    

    Bu tablo kararınızı tek başına verdirir. Uygulamada en sık görülen manzara şudur: listenin başındaki üç-dört satır 1536x1536, 2048x2048 ve temanın hiç kullanmadığı bir slider boyutudur; toplam uploads hacminin yarısını bunlar tutar.

    Hangi Boyutlar Gerçekten Kullanılıyor?#

    Bir boyutu kapatmadan önce sitenin onu çağırmadığından emin olmalısınız. Üç kontrol yeterlidir.

    1. Kod içinde arama. Tema ve eklenti dosyalarında boyut adını arayın:

    cd ~/public_html/wp-content
    grep -rn --include='*.php' -e "boyut-adi" themes/ plugins/ | head -20
    

    Sonuç boşsa o boyut PHP tarafından hiçbir yerde talep edilmiyor demektir.

    2. srcset çıktısına bakma. WordPress duyarlı görselleri srcset niteliğiyle yayınlar. Canlı bir yazının kaynağını çekip hangi genişliklerin gerçekten yayınlandığını görün:

    curl -s https://siteniz.com/ornek-yazi/ \
      | grep -o 'srcset="[^"]*"' | tr ',' '\n' | grep -o '[0-9]\+w' | sort -u
    

    Burada çıkan genişlikler tarayıcının seçebileceği gerçek adaylardır. Listede olmayan bir boyut ziyaretçiye hiç gönderilmiyordur.

    3. Kırpılmış boyutları ayrı değerlendirin. crop:evet olan boyutlar srcset'e girmez; WordPress yalnızca aynı en-boy oranındaki türevleri srcset'e koyar. Bu yüzden kırpılmış bir tema boyutu yukarıdaki listede görünmese bile tema tarafından the_post_thumbnail('boyut-adi') ile doğrudan çağrılıyor olabilir — birinci kontrol tam olarak bunun için var.

    Üç kontrolden de temiz çıkan boyut güvenle kapatılabilir.

    Yeni Yüklemeler İçin Gereksiz Boyutları Kapatma#

    Kapatma işini functions.php yerine bir mu-plugin dosyasına yazın ki tema güncellemesi veya tema değişikliği ayarınızı silmesin. wp-content/mu-plugins/gorsel-boyut-denetimi.php oluşturun:

    <?php
    /**
     * Plugin Name: Gorsel Boyut Denetimi
     * Description: Kullanilmayan ara boyutlarin uretilmesini engeller.
     */
    
    // Cekirdegin ve eklentilerin bildirdigi boyut listesinden istemediklerinizi cikarin.
    add_filter('intermediate_image_sizes_advanced', function (array $sizes) {
        unset(
            $sizes['medium_large'],
            $sizes['1536x1536'],
            $sizes['2048x2048']
        );
        return $sizes;
    });
    
    // Temanin add_image_size() ile kaydettigi boyutlari geri alin.
    add_action('init', function () {
        remove_image_size('tema-slider-buyuk');
        remove_image_size('tema-portfolyo-kare');
    }, 99);
    

    Üç ayrıntı burada belirleyicidir:

    • intermediate_image_sizes_advanced filtresi yalnızca yeni yüklemeleri etkiler. Diskte hâlihazırda duran dosyalara dokunmaz; onlar bir sonraki bölümün konusu.
    • remove_image_size() çağrısı init üzerinde ve geç önceliğe (99) bağlanmalıdır, çünkü tema kendi boyutlarını genellikle after_setup_theme içinde kaydeder. Erken çalışırsanız tema sizin sildiğinizi yeniden ekler.
    • Çekirdeğin thumbnail, medium ve large boyutlarını filtreden silmek yerine Ayarlar > Medya ekranından ölçüsünü 0 yapmak daha temizdir; WordPress genişliği ve yüksekliği sıfır olan boyutu üretmez.
    wp option update medium_large_size_w 0
    wp option update medium_large_size_h 0
    

    -scaled dosyalarını doğru anlamak#

    big_image_size_threshold filtresi çok sık yanlış kullanılıyor. __return_false ile kapatırsanız WordPress -scaled kopyayı üretmez — kulağa disk tasarrufu gibi gelir, ama o zaman sitede 8 MB'lık orijinal yayınlanmaya başlar ve sayfa ağırlığınız patlar. Doğru hamle eşiği kapatmak değil düşürmektir:

    add_filter('big_image_size_threshold', function () {
        return 1920; // 1920px ustu yuklemeler kucultulerek servis edilir
    });
    

    Kalıcı çözüm ise dosyayı yüklemeden önce küçültmektir; bu alışkanlık kurulduğunda çarpan sorunu baştan küçülür.

    Diskte Duran Eski Türevleri Toplu Silme#

    Boyutları kapattınız, ama diskteki eski kopyalar duruyor. Burada WP-CLI'nin doğrudan bu iş için yazılmış bayrağı devreye giriyor:

    # Yalnizca artik KAYITLI OLMAYAN boyutlarin turevlerini siler
    wp media regenerate --delete-unknown --yes
    

    --delete-unknown bayrağı yalnızca "eski, artık kayıtlı olmayan boyutların" küçük resimlerini siler. Sıralama bu yüzden kritiktir: önce mu-plugin ile boyutu kayıttan düşürürsünüz, sonra bu komutu çalıştırırsınız. Ters sırada çalıştırırsanız boyut hâlâ kayıtlı olduğu için hiçbir şey silinmez.

    Aynı komutun diğer bayrakları da işinize yarayabilir:

    BayrakNe yapar
    --delete-unknownYalnızca kayıtsız boyutların türevlerini siler
    --only-missingYalnızca eksik türevleri üretir, mevcutlara dokunmaz
    --skip-deleteYeniden üretirken eski türevleri silmez
    --image_size=BOYUTİşlemi tek bir boyutla sınırlar
    --yesOnay sorusunu atlar

    Büyük kütüphanelerde komut saatler sürebilir ve SSH oturumu kopunca yarıda kalır. nohup ile arka plana alın:

    nohup wp media regenerate --delete-unknown --yes > ~/regen.log 2>&1 &
    tail -f ~/regen.log
    

    --skip-delete bayrağının belgelerdeki açıklaması gerçek bir riski anlatıyor: türev dosyalarınıza kontrolünüz dışındaki kaynaklardan (eski bir e-bülten, bir pazaryeri listesi, harici bir site) doğrudan link verilmişse silinen dosya oralarda kırık görsele dönüşür. Ürün görsellerini pazaryerlerine URL ile bildiren mağazalarda bu ihtimali önceden değerlendirin.

    Veritabanında Karşılığı Olmayan Yetim Dosyaları Bulma#

    İkinci büyük yığın, medya kütüphanesinde kaydı olmadığı hâlde diskte duran dosyalardır: elle FTP ile atılmış görseller, silinmiş eklentilerin bıraktığı kalıntılar, yarıda kalmış içe aktarmalar. Bunları bulmanın güvenli yolu "diskte olanlar" ile "WordPress'in bildiği" listelerini karşılaştırmaktır.

    Önce WordPress'in bildiği bütün dosya yollarını üretin:

    cd ~/public_html
    
    wp eval '
    $base = wp_get_upload_dir()["basedir"];
    $ids  = get_posts([
        "post_type"      => "attachment",
        "post_status"    => "inherit",
        "posts_per_page" => -1,
        "fields"         => "ids",
    ]);
    foreach ($ids as $id) {
        $file = get_post_meta($id, "_wp_attached_file", true);
        if (!$file) { continue; }
        echo $base . "/" . $file . "\n";
        $meta = wp_get_attachment_metadata($id);
        if (empty($meta["sizes"])) { continue; }
        $dir = dirname($base . "/" . $file);
        foreach ($meta["sizes"] as $s) {
            echo $dir . "/" . $s["file"] . "\n";
        }
    }' | sort -u > ~/bilinen.txt
    
    wc -l ~/bilinen.txt
    

    Sonra diskteki gerçek listeyi çıkarın ve farkı alın:

    BASE=$(wp eval 'echo wp_get_upload_dir()["basedir"];')
    
    find "$BASE" -type f \
      \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \
         -o -iname '*.gif' -o -iname '*.webp' \) | sort -u > ~/diskte.txt
    
    comm -23 ~/diskte.txt ~/bilinen.txt > ~/yetim-adaylari.txt
    wc -l ~/yetim-adaylari.txt
    

    Dosyanın adına dikkat edin: bu bir aday listesidir, silinecekler listesi değil. İçinde meşru olarak bulunması gereken dosyalar vardır:

    • Optimizasyon eklentilerinin ürettiği .jpg.webp / .jpg.avif kopyaları
    • uploads/ewww/, uploads/shortpixel-backups/ gibi eklenti yedek klasörleri
    • uploads/woocommerce_uploads/ altındaki dijital ürün dosyaları
    • uploads/wc-logs/ ve yedekleme eklentilerinin çıktı klasörleri
    • Tema demolarının kendi klasörleri

    Bu yüzden aday listesini bir kez daha eleyeceğiz.

    Silmeden Önce: Adayları Veritabanına Karşı Doğrulama#

    Sayfa oluşturucular ve slider eklentileri görsel referanslarını post_content içinde değil, postmeta veya options tablosunda serileştirilmiş olarak tutar. _wp_attached_file taraması bu referansları görmez. Doğru elemeyi yapmak için sitenin metin içeriğini tek dosyaya döküp aday dosya adlarını orada arayın:

    PRE=$(wp db prefix)
    
    wp db query "SELECT post_content  FROM ${PRE}posts"    --skip-column-names >  ~/icerik.txt
    wp db query "SELECT meta_value    FROM ${PRE}postmeta" --skip-column-names >> ~/icerik.txt
    wp db query "SELECT option_value  FROM ${PRE}options"  --skip-column-names >> ~/icerik.txt
    wp db query "SELECT meta_value    FROM ${PRE}termmeta" --skip-column-names >> ~/icerik.txt
    
    while read -r f; do
      grep -qF "$(basename "$f")" ~/icerik.txt || echo "$f"
    done < ~/yetim-adaylari.txt > ~/silinecek.txt
    
    wc -l ~/silinecek.txt
    

    grep -qF sabit dize araması yapar, yani dosya adındaki nokta ve tire karakterleri düzenli ifade olarak yorumlanmaz. Bu döngü on binlerce dosyada yavaş çalışır; büyük sitelerde önce head -500 ile örnek alıp yöntemi doğrulayın.

    Bu aşamayı geçen dosyalar, hem medya kütüphanesinde kaydı olmayan hem de sitenin hiçbir tablosunda adı geçmeyen dosyalardır. Yine de doğrudan silmeyin — karantinaya taşıyın:

    mkdir -p ~/karantina
    while read -r f; do
      rel="${f#$BASE/}"
      mkdir -p "$HOME/karantina/$(dirname "$rel")"
      mv "$f" "$HOME/karantina/$rel"
    done < ~/silinecek.txt
    
    du -sh ~/karantina
    

    İki hafta boyunca siteyi gezin; ürün sayfalarını, sliderları ve kampanya sayfalarını kontrol edin. Bir görsel kaybolduysa mv ile geri alırsınız, sorun çıkmazsa karantina klasörünü silersiniz. Kotası zaten dolu bir hesapta karantina klasörünü sunucuda tutmak yerine indirip yerelde saklamak daha mantıklıdır.

    Bütün bu işlemlerden önce eksiksiz bir yedeğin alınmış olması pazarlık konusu değildir; WordPress yedekleme yazısındaki dosya + veritabanı ikilisini birlikte alın ve yedeği aynı sunucuda tutmayın. Ayrıca temizliği önce küçük bir klasörde (uploads/2019/03 gibi) deneyip yöntemin bu kurulumda beklendiği gibi çalıştığını görün.

    Tekrar Şişmemesi İçin Kalıcı Düzen#

    Temizlik bir kereye mahsustur; asıl kazanç düzeni kurmaktır.

    1. Kayıtlı boyut listesini sabitleyin. mu-plugin dosyanız yerinde kaldığı sürece yeni kurulan bir eklenti kendi boyutunu sessizce ekleyemez; eklediğini fark ettiğinizde filtreye bir unset satırı eklersiniz.
    2. Yükleme öncesi ölçüyü standartlaştırın. İçerik ekibine tek bir kural verin: blog görselleri en fazla 1600 piksel genişlik, ürün görselleri kare ve en fazla 1200 piksel.
    3. Çeyrekte bir ölçün. Yukarıdaki awk tablosunu üç ayda bir çalıştırın; listeye yeni bir boyut adı girdiyse hemen görürsünüz.
    4. Alarmı disk değil dosya sayısı üzerinden kurun. Paylaşımlı pakette limit çoğu zaman inode tarafından gelir; cPanel disk kullanımı ekranındaki dosya sayısı satırını düzenli izleyin.
    5. Eklenti yedek klasörlerini takip edin. Görsel optimizasyon eklentileri orijinalleri "geri alabilmek için" saklar; işiniz bittiğinde bu yedekleri eklentinin kendi ekranından temizleyin.

    Bu beş maddeyi uygulayan bir sitede uploads klasörü artık lineer büyür: yüklediğiniz kadar yer kaplar, katlanarak değil.

    Sıkça Sorulan Sorular#

    Küçük resimleri silersem sitede görseller bozulur mu?#

    Yalnızca kayıttan düşürdüğünüz boyutların türevleri silinir; o boyutlar zaten hiçbir yerden çağrılmıyorsa sitede hiçbir değişiklik olmaz. Riskli durum, dosyalara site dışından doğrudan link verilmiş olmasıdır: eski bir e-bültendeki veya pazaryeri listesindeki görsel adresi kırılabilir. Bu ihtimal varsa --skip-delete ile ilerleyin ve önce tek bir yıl klasöründe deneyin.

    wp media regenerate --delete-unknown çalıştırdım ama hiçbir şey silinmedi, neden?#

    Bu bayrak yalnızca artık kayıtlı olmayan boyutların dosyalarını siler. Boyutu hâlâ tema veya eklenti kaydediyorsa WordPress onu "bilinen" sayar ve dokunmaz. Doğru sıra önce mu-plugin ile remove_image_size() veya intermediate_image_sizes_advanced filtresini devreye almak, ardından komutu çalıştırmaktır. Filtrenin etkin olduğunu wp media image-size çıktısıyla doğrulayın.

    Yetim dosya taramasında sayfa oluşturucu görselleri neden çıkıyor?#

    Elementor, Divi ve benzeri araçlar görsel referanslarını serileştirilmiş veri içinde tutar ve bu referanslar _wp_attached_file taramasına yansımaz. Bu yüzden aday listesini doğrudan silmek yerine postmeta ve options tablolarının metin dökümüne karşı ikinci bir eleme yapmak gerekir. Kesinlik yine de yüzde yüz değildir; karantina adımı tam olarak bunun için vardır.

    Disk boş görünüyor ama hosting "dosya limiti doldu" diyor, aynı sorun mu?#

    Farklı limitlerdir. Disk gigabaytı ölçer, inode ise dosya ve klasör sayısını. Küçük resim çarpanı ikisini de büyütür ama inode tarafında etkisi çok daha serttir: 3.000 görsel, 14 boyutla birlikte 42.000 inode tüketir. Disk yüzde 30 dolu görünürken dosya limiti tükenebilir; teşhis ve temizlik için inode limiti yazısındaki adımları izleyin.

    Bu temizliği bir eklentiyle yapamaz mıyım?#

    Yapabilirsiniz, ancak bu kategorideki eklentiler "kullanılmıyor" kararını genellikle yalnızca post_content taramasına dayandırır ve serileştirilmiş referansları kaçırır. Eklenti kullanacaksanız sonucu doğrudan silme kipinde değil rapor kipinde alın, listeyi bu yazıdaki ikinci eleme yöntemiyle karşılaştırın. Karar mekanizmasını göremediğiniz bir toplu silme işleminin geri dönüşü yedekten başka bir şey değildir.

    WordPressDiskMedya

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.