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:
| Pendekatan | Lemah karena |
|---|---|
| Filename | Bisa beda nama |
| File size | Bisa sama tapi beda konten |
| Time window | Heuristik, tidak pasti |
| UI lock | Bisa di-bypass |
| SHA | Berdasarkan konten asli |
Pendekatan ini dikenal sebagai:
Content-based deduplication
Dan dipakai luas di sistem besar (Git, Docker layer, CAS storage).
Contoh Flow Dedup Upload
User upload file
Backend membaca file stream
Hitung SHA (misalnya SHA-256)
Cek ke database:
- Apakah SHA sudah ada?
Jika ada:
- Tolak upload atau
- Reuse file lama
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.