Dedup Upload File dengan SHA: Solusi Paling Masuk Akal untuk Double Upload
3 min read

Dedup Upload File dengan SHA: Solusi Paling Masuk Akal untuk Double Upload

Dalam sistem yang memiliki fitur upload file, kasus double upload hampir pasti akan terjadi. Bukan selalu karena race condition atau bug backend, tapi sering kali karena faktor manusia dan UI:

  • User lupa sudah meng-upload file
  • Admin membuka tab baru dan upload ulang
  • UI tidak memberi feedback jelas
  • Retry manual setelah koneksi lambat

Masalahnya: file yang di-upload benar-benar sama, hanya berbeda waktu. Jika tidak ditangani, dampaknya bisa serius:

  • Storage membengkak
  • Data redundant
  • Biaya meningkat
  • Relasi data jadi ambigu

Artikel ini membahas solusi yang paling tepat dan robust untuk kasus tersebut: deduplikasi berbasis SHA (content-based deduplication).


Masalah Utama: Logical Duplicate, Bukan Race Condition

Penting untuk membedakan dua jenis masalah:

  • Race condition: dua request bersamaan
  • Logical duplicate: request terpisah waktu, tapi konten sama

Pada logical duplicate:

  • Locking tidak membantu
  • Debounce UI tidak cukup
  • Time window check tidak reliable

Yang dibutuhkan adalah cara menjawab pertanyaan:

“Apakah file ini secara fisik sama dengan yang pernah di-upload sebelumnya?”


Apa Itu File SHA?

SHA (Secure Hash Algorithm) adalah fungsi hash kriptografis yang menghasilkan fingerprint unik dari konten file.

Yang di-hash:

  • ✔️ Raw byte content dari file

Yang tidak ikut di-hash:

  • ❌ Nama file
  • ❌ Extension
  • ❌ Waktu upload
  • ❌ User
  • ❌ Path penyimpanan

Secara sederhana:

SHA(file) = hash(byte[0] + byte[1] + ... + byte[N])

Konsekuensi Penting dari File SHA

File identik → SHA identik

Jika dua file:

  • Byte demi byte sama
  • Urutan sama

➡️ SHA pasti sama

Beda 1 byte saja → SHA berubah

SHA sangat sensitif. Contoh perubahan kecil yang menyebabkan SHA berbeda:

  • Metadata PDF berubah
  • EXIF timestamp image berbeda
  • Line ending LF vs CRLF
  • File di-save ulang oleh editor

Walaupun secara visual terlihat sama, SHA bisa berbeda.


Kenapa SHA adalah Solusi yang Tepat untuk Double Upload

Karena SHA menjawab masalah di level yang benar:

PendekatanLemah karena
FilenameBisa beda nama
File sizeBisa sama tapi beda konten
Time windowHeuristik, tidak pasti
UI lockBisa di-bypass
SHABerdasarkan konten asli

Pendekatan ini dikenal sebagai:

Content-based deduplication

Dan dipakai luas di sistem besar (Git, Docker layer, CAS storage).


Contoh Flow Dedup Upload

  1. User upload file

  2. Backend membaca file stream

  3. Hitung SHA (misalnya SHA-256)

  4. Cek ke database:

    • Apakah SHA sudah ada?
  5. Jika ada:

    • Tolak upload atau
    • Reuse file lama
  6. Jika tidak ada:

    • Simpan file
    • Simpan SHA ke DB

Contoh Implementasi di Golang

Hitung SHA-256 dari File (Streaming)

func ComputeSHA256(r io.Reader) (string, error) {
    hash := sha256.New()

    if _, err := io.Copy(hash, r); err != nil {
        return "", err
    }

    sum := hash.Sum(nil)
    return hex.EncodeToString(sum), nil
}

Contoh Penggunaan di Handler Upload

file, _, err := r.FormFile("file")
if err != nil {
    return err
}
defer file.Close()

sha, err := ComputeSHA256(file)
if err != nil {
    return err
}

exists := repo.ExistsBySHA(sha)
if exists {
    return errors.New("file already uploaded")
}

// reset reader jika perlu simpan ulang
file.Seek(0, io.SeekStart)
saveFile(file)
repo.SaveSHA(sha)

Catatan: Untuk file besar, hashing sambil streaming sangat disarankan agar hemat memory.


Best Practice Wajib

Hash dihitung di server

Jangan percaya SHA dari client.

Gunakan Unique Index di Database

CREATE UNIQUE INDEX uniq_file_sha ON uploaded_files (sha256);

Ini memberi:

  • Atomic guarantee
  • Perlindungan dari race condition masa depan

Simpan File Size

Untuk validasi tambahan dan debugging.

Tentukan Scope Dedup

Apakah dedup berlaku:

  • Global?
  • Per user?
  • Per tenant?

Contoh:

UNIQUE (tenant_id, sha256)

Tentukan Behavior Saat Duplicate

Pilihan umum:

  • Reject upload
  • Return reference file lama
  • Attach file lama ke entity baru
  • Log saja (soft dedup)

Tergantung kebutuhan bisnis.


Kapan SHA Tidak Cukup?

File “logically sama” tapi binary beda

Contoh:

  • Image sama, EXIF beda
  • PDF sama, metadata beda

Solusi lanjutan (opsional):

  • Strip metadata
  • Canonicalization
  • Perceptual hash (pHash untuk image)

⚠️ Ini level lanjut dan tidak selalu diperlukan.


Kesimpulan

  • File SHA adalah fingerprint konten file
  • SHA-based dedup adalah solusi paling tepat untuk double upload non-race
  • Robust terhadap waktu, user, dan device
  • Mudah diimplementasikan dan scalable

Jika kamu pernah mengalami kasus upload ulang dengan file yang sama, maka:

Dedup berbasis SHA bukan hanya solusi yang benar, tapi solusi yang matang.