Pernahkah kamu membuka sebuah situs lalu harus menunggu lama karena aplikasi sedang mengirim email, membuat laporan, atau memproses gambar? Pekerjaan berat seperti itu sebaiknya tidak dilakukan sambil membuat pengguna menunggu. Di sinilah Celery berperan: sebuah task queue untuk Python yang memungkinkanmu menjalankan pekerjaan berat di latar belakang secara asinkron. Dalam tutorial ini kamu akan belajar membangun background task dengan Celery dari nol — mulai dari instalasi, menjalankan worker, sampai menjadwalkan tugas otomatis.
Apa Itu Celery dan Mengapa Kamu Membutuhkannya?
Celery adalah pustaka Python untuk memproses task queue secara terdistribusi. Cara kerjanya sederhana: aplikasi kamu mengirim pesan berisi "pekerjaan" ke sebuah broker (antrian pesan), lalu proses terpisah bernama worker mengambil dan mengeksekusi pekerjaan itu di latar belakang. Karena eksekusi terjadi di proses lain, aplikasi utama tetap responsif dan bisa langsung membalas permintaan pengguna.
Contoh nyata kapan Celery dibutuhkan: mengirim email verifikasi setelah registrasi, membuat file laporan Excel atau PDF yang butuh waktu lama, memproses dan mengompresi gambar yang diunggah, atau memanggil API pihak ketiga yang lambat. Semua itu tidak perlu menghambat respons ke pengguna.
Perbedaan dengan asyncio: asyncio menjalankan kode secara konkuren di dalam satu proses untuk operasi I/O, sedangkan Celery mengeksekusi task di proses yang benar-benar terpisah (bahkan bisa di mesin/server lain). Untuk pekerjaan CPU-bound atau yang butuh isolasi penuh, Celery adalah pilihan yang lebih tepat.
Persiapan: Install Celery dan Redis
Celery membutuhkan sebuah broker untuk menampung antrian pesan. Broker yang paling populer dan mudah dipasang adalah Redis. Jika kamu belum mengenal Redis, artikel kami tentang Redis dengan Python bisa jadi pengantar yang bagus. Sekarang, install Celery dan client Redis-nya:
# Buat virtual environment (disarankan)
python -m venv venv
source venv/bin/activate
# Install Celery dan client Redis
pip install celery redis
Cara paling cepat menjalankan Redis adalah lewat Docker: cukup jalankan docker run -d -p 6379:6379 redis dan Redis langsung siap dipakai tanpa install manual. Pastikan Redis berjalan di localhost:6379 sebelum lanjut ke langkah berikutnya.
Membuat Aplikasi Celery Pertamamu
Buat sebuah file bernama tasks.py. Di dalamnya kita mendefinisikan objek Celery (aplikasi) serta beberapa task. Broker dan backend mengarah ke Redis di database nomor 0.
# tasks.py
from celery import Celery
# "tasks" adalah nama modul; broker & backend menunjuk ke Redis
app = Celery(
"tasks",
broker="redis://localhost:6379/0",
backend="redis://localhost:6379/0",
)
@app.task
def tambah(x, y):
return x + y
@app.task
def kirim_email(alamat, pesan):
# Simulasi pengiriman email (ganti dengan logika asli kamu)
print(f"Mengirim email ke {alamat}: {pesan}")
return f"Email terkirim ke {alamat}"
Menjalankan Worker Celery
Worker adalah proses yang benar-benar mengeksekusi task. Jalankan perintah berikut di terminal (pastikan berada di direktori yang sama dengan tasks.py):
celery -A tasks worker --loglevel=info
Jika semuanya berjalan normal, kamu akan melihat log worker yang menampilkan daftar task yang terdaftar (tambah dan kirim_email) serta pesan bahwa worker sudah siap menerima pekerjaan:
-------------- celery@hostname v5.4.0 (opalescent)
--- ***** -----
-- ******* ---- Linux-6.8.0-generic-x86_64-with-glibc2.39 2026-09-11
- *** --- * ---
- ** ---------- [config]
- ** ---------- .> app: tasks:0x7f...
- ** ---------- .> transport: redis://localhost:6379/0
- ** ---------- .> results: redis://localhost:6379/0
- *** --- * --- .> concurrency: 8 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor)
--- ***** -----
-------------- [queues]
.> celery exchange=celery(direct) key=celery
[tasks]
. kirim_email
. tambah
[2026-09-11 10:00:00,000: INFO/MainProcess] Connected to redis://localhost:6379/0
[2026-09-11 10:00:00,000: INFO/MainProcess] mingle: searching for neighbors
[2026-09-11 10:00:00,000: INFO/MainProcess] mingle: all alone
[2026-09-11 10:00:00,000: INFO/MainProcess] celery@hostname ready.
Memanggil Task dari Kode Python
Setelah worker berjalan, kamu bisa mengirim task dari shell Python atau file lain. Ada dua cara utama: delay() (paling sederhana) dan apply_async() (lebih fleksibel, misalnya untuk menjadwalkan eksekusi dengan jeda waktu).
# panggil_task.py (jalankan di shell/terminal terpisah)
from tasks import tambah, kirim_email
# delay() = cara paling sederhana mengirim task ke antrian
hasil = tambah.delay(4, 6)
print("Task ID:", hasil.id)
# apply_async() memberi kontrol lebih banyak (misal countdown)
kirim_email.apply_async(
args=["user@example.com", "Selamat datang di BengkelKode!"],
countdown=5, # tunggu 5 detik sebelum dieksekusi
)
# Ambil hasilnya (BLOKIR sampai selesai — jangan pakai di web request!)
print("Hasil tambah:", hasil.get(timeout=10))
Memantau Status dan Hasil Task
Setiap task mengembalikan objek AsyncResult yang bisa kamu gunakan untuk memantau status eksekusi tanpa harus memblokir aplikasi. Ini sangat berguna saat kamu membangun fitur seperti progress bar atau tombol "cek status".
# Memeriksa status tanpa memblokir
hasil = tambah.delay(10, 20)
print("Status awal:", hasil.state) # PENDING
# ... beberapa saat kemudian ...
print("Sudah selesai?", hasil.ready())
if hasil.ready():
print("Hasil:", hasil.result)
else:
print("Task masih berjalan, cek lagi nanti.")
Hindari memanggil hasil.get() langsung di dalam view/request web. Metode itu memblokir eksekusi sampai task selesai, yang justru menghilangkan manfaat Celery. Gunakan pola polling (cek ready() berkala) atau callback seperti apply_async(..., link=...).
Retry Otomatis dan Error Handling
Panggilan ke layanan eksternal (email, SMS, API) bisa gagal sewaktu-waktu. Celery punya mekanisme retry bawaan yang membuat task diulang otomatis dengan jeda waktu tertentu.
# tasks_retry.py
import random
from celery import Celery
app = Celery(
"tasks_retry",
broker="redis://localhost:6379/0",
backend="redis://localhost:6379/0",
)
@app.task(bind=True, max_retries=3, default_retry_delay=5)
def kirim_email_andal(self, alamat, pesan):
try:
# Simulasi layanan email yang kadang gagal
if random.random() < 0.7:
raise ConnectionError("Server email tidak merespons")
return f"Email terkirim ke {alamat}"
except ConnectionError as exc:
# Coba lagi maksimal 3 kali, jeda 5 detik antar percobaan
raise self.retry(exc=exc, countdown=5)
Karena bind=True, parameter pertama task adalah self (instance task) yang punya method retry(). Jika setelah 3 percobaan masih gagal, Celery akan menandai task sebagai FAILURE dan kamu bisa menangkapnya lewat monitoring.
Menjadwalkan Tugas dengan Celery Beat
Selain task yang dipicu manual, Celery punya Beat — penjadwal yang menjalankan task secara berkala, mirip cron. Cocok untuk laporan harian, backup, atau membersihkan data lama.
# tasks_beat.py
from celery import Celery
from celery.schedules import crontab
app = Celery(
"tasks_beat",
broker="redis://localhost:6379/0",
backend="redis://localhost:6379/0",
)
app.conf.beat_schedule = {
"laporan-harian-pukul-7": {
"task": "tasks_beat.buat_laporan_harian",
"schedule": crontab(hour=7, minute=0),
},
"bersihkan-cache-tiap-30-detik": {
"task": "tasks_beat.bersihkan_cache",
"schedule": 30.0,
},
}
@app.task
def buat_laporan_harian():
return "Laporan harian berhasil dibuat"
@app.task
def bersihkan_cache():
return "Cache berhasil dibersihkan"
# Jalankan beat di terminal terpisah (worker tetap harus berjalan)
celery -A tasks_beat beat --loglevel=info
Penting: Beat hanya bertugas menjadwalkan dan mengirim task ke antrian. Worker tetap harus berjalan di proses lain untuk mengeksekusinya. Di lingkungan produksi, jalankan keduanya sebagai service terpisah (misalnya lewat systemd atau supervisor).
Mengintegrasikan Celery dengan Web Framework
Celery paling sering dipakai bersama web framework seperti Django, Flask, atau FastAPI. Pola umumnya: view menerima permintaan, langsung membalas ke pengguna, lalu menyerahkan pekerjaan berat ke task Celery. Berikut contoh sederhana dengan Flask:
# app.py (contoh integrasi Celery dengan Flask)
from flask import Flask, jsonify
from tasks import kirim_email
app = Flask(__name__)
@app.route("/daftar", methods=["POST"])
def daftar():
# Langsung balas ke pengguna; kirim email di latar belakang
kirim_email.delay("user@example.com", "Selamat datang!")
return jsonify({"pesan": "Pendaftaran berhasil, email sedang dikirim"})
if __name__ == "__main__":
app.run(debug=True)
Kesimpulan
Celery adalah solusi standar untuk memproses pekerjaan berat di latar belakang dengan Python. Kamu sudah belajar memasang Redis sebagai broker, mendefinisikan task, menjalankan worker, memantau hasil, melakukan retry otomatis, menjadwalkan tugas berkala dengan Beat, sampai mengintegrasikannya dengan web framework. Langkah selanjutnya: coba terapkan di proyekmu sendiri, pelajari Redis lebih dalam untuk broker dan result backend yang lebih andal, atau perdalam pemahamanmu tentang concurrency lewat artikel asyncio kami. Selamat mencoba!