Lompat ke konten
← Semua tulisan

Celery: Memindahkan Pekerjaan Berat ke Belakang Layar

N Nicholaus Verdhy Putranto 09 Juli 2026 · 2 menit baca · 9 dilihat

Aturan sederhana: kalau sebuah pekerjaan butuh lebih dari dua atau tiga detik, jangan kerjakan di dalam permintaan HTTP.

Kirim email, olah gambar, buat laporan, panggil LLM — semuanya masuk kategori ini.

Kenapa penting

Permintaan HTTP yang lama menahan worker server. Kalau semua worker tertahan, situsmu berhenti melayani siapa pun. Browser juga punya batas waktu sendiri — pengguna melihat error meski pekerjaannya sebenarnya berhasil.

Menyiapkan Celery

pip install celery redis

config/celery.py:

import os
from celery import Celery

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")

app = Celery("config")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()

config/__init__.py:

from .celery import app as celery_app

__all__ = ("celery_app",)

settings.py:

CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/1"
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_TASK_ACKS_LATE = True

Tugas pertama

from celery import shared_task

@shared_task(bind=True, max_retries=3)
def kirim_laporan(self, pengguna_id):
    try:
        pengguna = Pengguna.objects.get(pk=pengguna_id)
        berkas = susun_laporan(pengguna)
        kirim_email(pengguna.email, berkas)
    except Exception as exc:
        raise self.retry(exc=exc, countdown=60)

Memanggilnya dari view:

def minta_laporan(request):
    kirim_laporan.delay(request.user.pk)
    return JsonResponse({"pesan": "Laporan sedang dibuat, kami kabari lewat email."})

View-nya membalas seketika. Pekerjaannya jalan di belakang layar.

Tiga aturan yang saya pegang

1. Kirim ID, bukan objek.

kirim_laporan.delay(pengguna.pk)      # benar
kirim_laporan.delay(pengguna)         # salah — objek harus diserialisasi

Objek yang diserialisasi bisa jadi basi sebelum tugasnya jalan.

2. Buat tugasnya aman diulang. Celery bisa menjalankan ulang tugas yang gagal. Kalau tugasmu mengirim email, pastikan tidak mengirim dua kali.

3. Selalu pasang batas waktu. Tanpa itu, satu tugas yang macet bisa menahan worker selamanya.

Tugas terjadwal

from celery.schedules import crontab

app.conf.beat_schedule = {
    "bersihkan-sesi-harian": {
        "task": "core.tasks.bersihkan_sesi",
        "schedule": crontab(hour=3, minute=0),
    },
}

Alternatif yang lebih ringan

Celery butuh Redis atau RabbitMQ, plus proses worker terpisah. Untuk kebutuhan sederhana, itu berlebihan.

Kalau tugasmu sedikit dan tidak kritis, django-q2 atau huey lebih ringan. Kalau cuma butuh satu hal jalan tiap malam, cron biasa memanggil manage.py sudah cukup — tidak semua hal butuh antrean.

Bagikan ke WhatsApp Bagikan ke X

Komentar (0)

Belum ada komentar. Jadilah yang pertama!

Tinggalkan Komentar

Komentar akan tampil setelah disetujui.

Baca Juga