Lambda — response streaming
Streaming memperbaiki time-to-first-byte dan menaikkan batas payload dari 6 MB ke 200 MB. Tapi dukungan runtime-nya tidak merata, dan itu menentukan arsitekturmu.
Intisari
- Streaming menurunkan TTFB — pengguna melihat kata pertama tanpa menunggu jawaban selesai.
- Batas payload naik dari 6 MB (buffered) jadi 200 MB (streaming).
- Jebakan: runtime terkelola yang mendukungnya adalah Node.js. Untuk Python butuh custom runtime atau Lambda Web Adapter.
- Bisa dipakai lewat Function URL,
InvokeWithResponseStream, atau integrasi proxy API Gateway. - Kamu tetap ditagih durasi penuh walau klien memutus koneksi — hati-hati dengan timeout panjang.
Kenapa ini penting untuk aplikasi LLM
Jawaban model butuh beberapa detik untuk selesai. Tanpa streaming, pengguna menatap layar kosong selama itu, lalu seluruh jawaban muncul sekaligus. Dengan streaming, kata pertama muncul dalam ratusan milidetik. Perbedaan yang dirasakan pengguna jauh lebih besar daripada perbedaan waktu total.
| Buffered (default) | Streaming | |
|---|---|---|
| Time to first byte | Setelah seluruh jawaban jadi | Segera setelah token pertama |
| Batas payload | 6 MB | 200 MB |
| Memori yang dibutuhkan | Seluruh respons harus muat | Cukup potongan yang sedang dikirim |
| Bandwidth | — | 6 MB pertama tanpa batas, sisanya maksimum 2 MB/detik |
Jebakan runtime — baca ini sebelum menggambar arsitektur. Lambda mendukung response streaming pada runtime terkelola Node.js. Untuk Python, kamu perlu custom runtime dengan integrasi Runtime API sendiri, atau memakai Lambda Web Adapter — yang membuatmu bisa menjalankan aplikasi FastAPI apa adanya di dalam Lambda. Karena roadmap ini berbahasa Python, Lambda Web Adapter adalah jalur yang paling masuk akal.
Tiga cara memanggilnya
| Jalur | Cocok untuk | Catatan |
|---|---|---|
| Function URL | Prototipe, endpoint internal | Paling sederhana; auth cuma IAM atau terbuka |
InvokeWithResponseStream | Dipanggil dari backend lain lewat SDK | Kontrol penuh, tanpa HTTP publik |
| API Gateway proxy | API publik | Dapat authorizer, throttling, dan custom domain |
Pola FastAPI + Lambda Web Adapter
Kalau kamu datang dari learn-python, ini terasa akrab: kode SSE-nya persis sama dengan yang
kamu tulis di FastAPI, dan adapter yang menjembatankannya ke Lambda.
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import boto3
app = FastAPI()
bedrock = boto3.client("bedrock-runtime")
@app.post("/tanya")
def tanya(pertanyaan: str):
def potongan():
resp = bedrock.converse_stream(
modelId=MODEL_ID,
messages=[{"role": "user", "content": [{"text": pertanyaan}]}],
)
for peristiwa in resp["stream"]:
if "contentBlockDelta" in peristiwa:
teks = peristiwa["contentBlockDelta"]["delta"]["text"]
yield f"data: {teks}\n\n"
yield "data: [SELESAI]\n\n"
return StreamingResponse(potongan(), media_type="text/event-stream")
Biaya dan timeout
Dua hal yang mudah menyakitkan. Pertama, respons yang sedang di-stream tidak dihentikan ketika klien memutus koneksi — fungsimu tetap jalan sampai selesai, dan kamu dibayar penuh. Kedua, karena streaming mengundang timeout yang panjang, satu bug loop bisa berarti 15 menit pemanggilan Bedrock yang tak seorang pun membacanya.
Penawarnya: pasang timeout sekonservatif mungkin (misalnya 60–120 detik untuk endpoint chat), dan batasi
maxTokens di sisi Bedrock. Jangan andalkan klien untuk menghentikan apa pun.
Latihan: jelaskan dalam dua kalimat kenapa fungsi Python biasa yang mengembalikan generator tidak otomatis jadi streaming di Lambda, lalu gambarkan alur permintaan chat yang streaming dari browser sampai Bedrock — sebutkan setiap komponen yang dilewati. Implementasinya menyusul di capstone Fase 8.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.