Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Production reference architecture for Kling AI video generation platforms. Use when designing scalable systems. Trigger with phrases like 'klingai architecture', 'kling ai system design', 'video platform architecture', 'klingai production setup'.
.claude/skills/jeremylongshore-klingai-reference-architecture/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 9% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 27% | 0% |
| case-13 | ✗→✓ | ▲ Improved | -22% | 0% |
| case-16 | ✗→✓ | ▲ Improved | -10% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 235% | 0% |
Production architecture for video generation platforms built on Kling AI. Covers API gateway, job queue, worker pool, storage, and monitoring layers.
User Request
|
[API Gateway / Load Balancer]
|
[Application Server]
|--- validate prompt & estimate cost
|--- enqueue job to Redis/SQS
|
[Job Queue (Redis / SQS / Pub/Sub)]
|
[Worker Pool (N workers)]
|--- generate JWT token
|--- POST https://api.klingai.com/v1/videos/text2video
|--- receive task_id
|--- register callback_url OR poll
|
[Webhook Receiver / Poller]
|--- receive completion callback
|--- download video from Kling CDN
|--- upload to S3/GCS
|--- update job status in DB
|--- notify user
|
[Object Storage (S3 / GCS)]
|
[CDN (CloudFront / Cloud CDN)]
|
User views videopythonfrom fastapi import FastAPI, HTTPException from pydantic import BaseModel app = FastAPI() class VideoRequest(BaseModel): prompt: str model: str = "kling-v2-master" duration: int = 5 mode: str = "standard" @app.post("/api/videos") async def create_video(req: VideoRequest): # 1. Validate if len(req.prompt) > 2500: raise HTTPException(400, "Prompt exceeds 2500 chars") # 2. Estimate cost credits = estimate_credits(req.duration, req.mode) if not budget_guard.check(credits): raise HTTPException(402, "Budget exceeded") # 3. Enqueue job_id = await queue.enqueue({ "prompt": req.prompt, "model": req.model, "duration": str(req.duration), "mode": req.mode, }) return {"job_id": job_id, "status": "queued", "estimated_credits": credits}
pythonimport redis import json class VideoWorker: def __init__(self, kling_client, storage_client, redis_url="redis://localhost"): self.kling = kling_client self.storage = storage_client self.redis = redis.Redis.from_url(redis_url) def process_loop(self): while True: raw = self.redis.brpop("kling:jobs:pending", timeout=5) if not raw: continue job = json.loads(raw[1]) try: # Submit to Kling API result = self.kling.text_to_video( job["prompt"], model=job["model"], duration=int(job["duration"]), mode=job["mode"], callback_url=os.environ.get("WEBHOOK_URL"), ) # If using polling (no callback) if isinstance(result, dict) and "videos" in result: video_url = result["videos"][0]["url"] stored_url = self.storage.download_and_upload(video_url, job["id"]) self.redis.publish("kling:events", json.dumps({ "type": "completed", "job_id": job["id"], "video_url": stored_url, })) except Exception as e: self.redis.lpush("kling:jobs:failed", json.dumps({ **job, "error": str(e) }))
| Component | Scaling Strategy | |-----------|-----------------| | Workers | Scale by queue depth (1 worker per 3 concurrent API tasks) | | API servers | Horizontal, behind load balancer | | Redis | Single instance for <1K jobs/day, cluster for more | | Storage | S3/GCS scales automatically | | CDN | CloudFront/Cloud CDN for global delivery |
| Tier | Max Concurrent Tasks | Workers Needed | |------|---------------------|----------------| | Free | 1 | 1 | | Standard | 3 | 1 | | Pro | 5 | 2 | | Enterprise | 10+ | 3-4 |
yaml# docker-compose.yml services: api: build: ./api ports: ["8000:8000"] environment: - REDIS_URL=redis://redis:6379 - KLING_ACCESS_KEY=${KLING_ACCESS_KEY} - KLING_SECRET_KEY=${KLING_SECRET_KEY} worker: build: ./worker deploy: replicas: 2 environment: - REDIS_URL=redis://redis:6379 - KLING_ACCESS_KEY=${KLING_ACCESS_KEY} - KLING_SECRET_KEY=${KLING_SECRET_KEY} - S3_BUCKET=${S3_BUCKET} webhook: build: ./webhook ports: ["8001:8001"] environment: - REDIS_URL=redis://redis:6379 redis: image: redis:7-alpine volumes: ["redis-data:/data"] volumes: redis-data:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 20,791 | 18,851 | -9% | 1 | 1 | 0% | 4,355 | 4,256 | -2% | 0 | 0 | — |
case-02 | fail→fail | 52,671 | 16,300 | -69% | 1 | 1 | 0% | 3,209 | 3,236 | +1% | 0 | 0 | — |
case-03 | fail→fail | 19,911 | 25,598 | +29% | 1 | 1 | 0% | 4,021 | 5,427 | +35% | 0 | 0 | — |
case-04 | fail→fail | 10,580 | 8,812 | -17% | 1 | 1 | 0% | 1,937 | 3,113 | +61% | 0 | 0 | — |
case-05 | pass→fail | 26,928 | 26,360 | -2% | 1 | 1 | 0% | 4,204 | 5,458 | +30% | 0 | 0 | — |
case-06 | pass→pass | 16,081 | 21,813 | +36% | 1 | 1 | 0% | 3,101 | 4,598 | +48% | 0 | 0 | — |
case-07 | pass→fail | 11,584 | 11,234 | -3% | 1 | 1 | 0% | 1,836 | 2,466 | +34% | 0 | 0 | — |
case-08 | fail→fail | 17,590 | 10,401 | -41% | 1 | 1 | 0% | 2,175 | 3,342 | +54% | 0 | 0 | — |
case-09 | fail→pass | 14,799 | 7,957 | -46% | 1 | 1 | 0% | 1,654 | 1,804 | +9% | 0 | 0 | — |
case-10 | pass→pass | 19,176 | 10,907 | -43% | 1 | 1 | 0% | 2,218 | 3,105 | +40% | 0 | 0 | — |
case-11 | pass→pass | 11,641 | 8,611 | -26% | 1 | 1 | 0% | 948 | 1,855 | +96% | 0 | 0 | — |
case-12 | fail→pass | 18,751 | 10,290 | -45% | 1 | 1 | 0% | 2,640 | 3,359 | +27% | 0 | 0 | — |
case-13 | fail→pass | 20,962 | 9,237 | -56% | 1 | 1 | 0% | 2,744 | 2,128 | -22% | 0 | 0 | — |
case-14 | fail→fail | 21,807 | 18,704 | -14% | 1 | 1 | 0% | 2,722 | 4,442 | +63% | 0 | 0 | — |
case-15 | pass→pass | 17,198 | 8,410 | -51% | 1 | 1 | 0% | 2,133 | 1,992 | -7% | 0 | 0 | — |
case-16 | fail→pass | 13,316 | 7,869 | -41% | 1 | 1 | 0% | 1,891 | 1,711 | -10% | 0 | 0 | — |
case-17 | fail→fail | 11,058 | 11,910 | +8% | 1 | 1 | 0% | 1,494 | 2,539 | +70% | 0 | 0 | — |
case-18 | fail→pass | 8,536 | 7,274 | -15% | 1 | 1 | 0% | 516 | 1,730 | +235% | 0 | 0 | — |
case-19 | pass→pass | 22,063 | 16,662 | -24% | 1 | 1 | 0% | 2,738 | 4,119 | +50% | 0 | 0 | — |
case-20 | pass→pass | 23,310 | 20,792 | -11% | 1 | 1 | 0% | 2,804 | 3,909 | +39% | 0 | 0 | — |
case-21 | fail→pass | 19,982 | 9,624 | -52% | 1 | 1 | 0% | 2,164 | 3,079 | +42% | 0 | 0 | — |
case-22 | pass→fail | 26,743 | 12,356 | -54% | 1 | 1 | 0% | 3,167 | 3,540 | +12% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases. 3 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.