{"course":{"slug":"ai-video","title":"Video with AI","url":"https://addaly.com/learn/ai-video","level":"intermediate","track":"create"},"lesson":{"slug":"batching-and-apis","title":"Queue everything, then judge it together","url":"https://addaly.com/learn/ai-video/batching-and-apis","position":63,"of":66,"minutes":9,"answer":"Generating one clip at a time invites the just-one-more loop that destroys budgets, while queueing a batch and reviewing the results together produces better decisions and a countable spend.","keyIdea":"Generating one clip at a time invites the just-one-more loop that destroys budgets, while queueing a batch and reviewing the results together produces better decisions and a countable spend."},"body":{"format":"markdown","text":"## Why one at a time is expensive\n\nWatching a single generation render creates a specific behaviour. It finishes, it is nearly right, you adjust one word, you press generate, you watch again. An afternoon disappears and the spend is invisible because it arrived in small pieces.\n\nBatching breaks the loop mechanically. Queue eight shots, walk away, come back to eight results, and judge them together.\n\nThe decisions are also better. Comparing eight results side by side tells you which are good; watching one at a time tells you only whether each is better than the one before it, which is a much weaker judgement.\n\n## Batching without an API\n\nMost hosted tools let you queue several generations. Use it even when the interface makes it awkward:\n\n- Write all your prompts and stills first, as a batch of work, before opening the tool.\n- Submit them all.\n- Close the tab.\n- Come back later and download everything.\n\nThat last step matters more than it sounds. Staying on the page is what re-creates the loop.\n\n## When an API is worth it\n\nIf you are producing regularly, driving generation from a script is a different way of working and it is not difficult.\n\n**fal.ai** and **Replicate** both expose most current models behind a single API with pay-as-you-go billing, which means one account rather than six. The platforms' own APIs exist too, with their own SDKs.\n\nA minimal loop over a shot list:\n\n```python\nimport json, pathlib, fal_client   # or replicate\n\nshots = json.load(open(\"shots.json\"))   # [{id, image, prompt, seconds}, ...]\nout = pathlib.Path(\"takes\"); out.mkdir(exist_ok=True)\n\nfor s in shots:\n    for take in range(3):\n        r = fal_client.run(\"MODEL-SLUG\", arguments={\n            \"image_url\": s[\"image\"],\n            \"prompt\": s[\"prompt\"],\n            \"duration\": s[\"seconds\"],\n            \"seed\": 1000 + take,\n        })\n        (out / f'{s[\"id\"]}_t{take}.json').write_text(json.dumps(r))\n        print(s[\"id\"], take, r.get(\"video\", {}).get(\"url\"))\n```\n\nWhat this buys, beyond speed:\n\n- **Every parameter is recorded**, because it is in the script. Your provenance problem is solved as a side effect.\n- **Seeds are explicit and varied deliberately**, so three takes are three known draws rather than three unknown ones.\n- **Repeatable runs.** Re-running the script with one changed field is an experiment, not a session.\n- **Spend is countable.** Shots times takes times price, known before you run it.\n\n## Rate limits, failures and refunds\n\nThings that will happen and should not surprise you:\n\n- **Rate limits.** Providers cap concurrent jobs. Handle it with a small delay and a retry rather than by hammering.\n- **Failed generations.** A job returns an error or a black clip. Most providers do not charge for a hard failure, and some charge for a completed-but-bad one. Check your usage page against your expected spend after the first batch.\n- **Content filter refusals.** Hosted models occasionally decline legitimate work with no explanation. Budget for it and keep an open-weights fallback for anything the filters are awkward about.\n- **Silent model updates.** Pin a version string in the call if the provider supports it.\n\nAlways write the response to disk, including the failures. A log of what failed and why is what tells you whether a shot is unlucky or impossible.\n\n## Local batching\n\nIf you run models yourself, batching is the default rather than a feature. ComfyUI queues as many jobs as you give it and works through them, and the marginal cost of a fourth take is electricity.\n\nThat changes the economics of experimentation completely, and it is the strongest practical argument for a local setup even if your final renders happen on a hosted model.\n\n## The habit that survives any tool\n\nPrepare work in batches, submit, leave, review together, decide. It applies to a scripted API run, a hosted queue, or a free tier where you submit three jobs a day and collect them tomorrow.\n\nThe tool changes; the loop that wastes money does not.\n\n---\n\nToday: prepare eight shots fully before opening your tool, submit all eight, close the tab, and review them together an hour later."},"check":{"question":"Beyond throughput, what is the main decision-quality benefit of queueing eight generations and reviewing them together?","options":[{"text":"Batch submission uses a shared seed sequence, so the eight results are comparable in a way independently submitted jobs are not.","correct":false,"tempting":"Batching does not impose a shared seed, and eight shots with different stills would not be comparable even if it did."},{"text":"Reviewing results in a group lets you judge which are genuinely good, rather than only whether each is better than the one before it.","correct":true},{"text":"Queued jobs are processed at the same model version, eliminating the risk that a silent update changes the output partway through a session.","correct":false,"tempting":"A real provenance concern that batching does not actually protect against over a long queue."},{"text":"Batch pricing is typically lower per second than interactive generation, so the same review can be done across more takes for the same spend.","correct":false,"tempting":"Asserts a batch discount that these services generally do not offer."}]},"prev":{"slug":"draft-passes-and-quality-ladders","title":"Test the idea at a tenth of the price","url":"https://addaly.com/learn/ai-video/draft-passes-and-quality-ladders"},"next":{"slug":"subscription-or-top-up","title":"The arithmetic nobody does before subscribing","url":"https://addaly.com/learn/ai-video/subscription-or-top-up"},"authorship":"Founder and series editor: Dr Mustafa Mun. Written by AI models to a written standard. Exam keys checked blind by a second model: 3,665 of 3,666 agreed. Academic review invited.","review":{"status":"Draft, open for academic review"},"cite":"Addaly (2026) 'Queue everything, then judge it together', in Video with AI. Edited by M. Mun. Addaly. Available at: https://addaly.com/learn/ai-video/batching-and-apis (Accessed: 13 October 2026).","licence":{"name":"CC BY-NC-SA 4.0","url":"https://creativecommons.org/licenses/by-nc-sa/4.0/"},"reader":{"schema":1,"title":"Queue everything, then judge it together","courseTitle":"Video with AI","module":{"index":7,"slug":"running-the-job","title":"Money, clients and running the job"},"answer":null,"keyIdea":"Generating one clip at a time invites the just-one-more loop that destroys budgets, while queueing a batch and reviewing the results together produces better decisions and a countable spend.","hero":{"kind":"plate","image":null,"alt":null,"caption":null},"blocks":[{"t":"h2","id":"why-one-at-a-time-is-expensive","runs":[{"text":"Why one at a time is expensive"}]},{"t":"p","runs":[{"text":"Watching a single generation render creates a specific behaviour. It finishes, it is nearly right, you adjust one word, you press generate, you watch again. An afternoon disappears and the spend is invisible because it arrived in small pieces."}]},{"t":"p","runs":[{"text":"Batching breaks the loop mechanically. Queue eight shots, walk away, come back to eight results, and judge them together."}]},{"t":"p","runs":[{"text":"The decisions are also better. Comparing eight results side by side tells you which are good; watching one at a time tells you only whether each is better than the one before it, which is a much weaker judgement."}]},{"t":"h2","id":"batching-without-an-api","runs":[{"text":"Batching without an API"}]},{"t":"p","runs":[{"text":"Most hosted tools let you queue several generations. Use it even when the interface makes it awkward:"}]},{"t":"ul","items":[[{"text":"Write all your prompts and stills first, as a batch of work, before opening the tool."}],[{"text":"Submit them all."}],[{"text":"Close the tab."}],[{"text":"Come back later and download everything."}]]},{"t":"p","runs":[{"text":"That last step matters more than it sounds. Staying on the page is what re-creates the loop."}]},{"t":"h2","id":"when-an-api-is-worth-it","runs":[{"text":"When an API is worth it"}]},{"t":"p","runs":[{"text":"If you are producing regularly, driving generation from a script is a different way of working and it is not difficult."}]},{"t":"p","runs":[{"text":"fal.ai","b":true},{"text":" and "},{"text":"Replicate","b":true},{"text":" both expose most current models behind a single API with pay-as-you-go billing, which means one account rather than six. The platforms’ own APIs exist too, with their own SDKs."}]},{"t":"p","runs":[{"text":"A minimal loop over a shot list:"}]},{"t":"code","lang":"python","label":"Python","text":"import json, pathlib, fal_client   # or replicate\n\nshots = json.load(open(\"shots.json\"))   # [{id, image, prompt, seconds}, ...]\nout = pathlib.Path(\"takes\"); out.mkdir(exist_ok=True)\n\nfor s in shots:\n    for take in range(3):\n        r = fal_client.run(\"MODEL-SLUG\", arguments={\n            \"image_url\": s[\"image\"],\n            \"prompt\": s[\"prompt\"],\n            \"duration\": s[\"seconds\"],\n            \"seed\": 1000 + take,\n        })\n        (out / f'{s[\"id\"]}_t{take}.json').write_text(json.dumps(r))\n        print(s[\"id\"], take, r.get(\"video\", {}).get(\"url\"))"},{"t":"p","runs":[{"text":"What this buys, beyond speed:"}]},{"t":"ul","items":[[{"text":"Every parameter is recorded","b":true},{"text":", because it is in the script. Your provenance problem is solved as a side effect."}],[{"text":"Seeds are explicit and varied deliberately","b":true},{"text":", so three takes are three known draws rather than three unknown ones."}],[{"text":"Repeatable runs.","b":true},{"text":" Re-running the script with one changed field is an experiment, not a session."}],[{"text":"Spend is countable.","b":true},{"text":" Shots times takes times price, known before you run it."}]]},{"t":"h2","id":"rate-limits-failures-and-refunds","runs":[{"text":"Rate limits, failures and refunds"}]},{"t":"p","runs":[{"text":"Things that will happen and should not surprise you:"}]},{"t":"ul","items":[[{"text":"Rate limits.","b":true},{"text":" Providers cap concurrent jobs. Handle it with a small delay and a retry rather than by hammering."}],[{"text":"Failed generations.","b":true},{"text":" A job returns an error or a black clip. Most providers do not charge for a hard failure, and some charge for a completed-but-bad one. Check your usage page against your expected spend after the first batch."}],[{"text":"Content filter refusals.","b":true},{"text":" Hosted models occasionally decline legitimate work with no explanation. Budget for it and keep an open-weights fallback for anything the filters are awkward about."}],[{"text":"Silent model updates.","b":true},{"text":" Pin a version string in the call if the provider supports it."}]]},{"t":"p","runs":[{"text":"Always write the response to disk, including the failures. A log of what failed and why is what tells you whether a shot is unlucky or impossible."}]},{"t":"h2","id":"local-batching","runs":[{"text":"Local batching"}]},{"t":"p","runs":[{"text":"If you run models yourself, batching is the default rather than a feature. ComfyUI queues as many jobs as you give it and works through them, and the marginal cost of a fourth take is electricity."}]},{"t":"p","runs":[{"text":"That changes the economics of experimentation completely, and it is the strongest practical argument for a local setup even if your final renders happen on a hosted model."}]},{"t":"h2","id":"the-habit-that-survives-any-tool","runs":[{"text":"The habit that survives any tool"}]},{"t":"p","runs":[{"text":"Prepare work in batches, submit, leave, review together, decide. It applies to a scripted API run, a hosted queue, or a free tier where you submit three jobs a day and collect them tomorrow."}]},{"t":"p","runs":[{"text":"The tool changes; the loop that wastes money does not."}]},{"t":"rule"},{"t":"p","runs":[{"text":"Today: prepare eight shots fully before opening your tool, submit all eight, close the tab, and review them together an hour later."}]}],"check":{"question":[{"text":"Beyond throughput, what is the main decision-quality benefit of queueing eight generations and reviewing them together?"}],"options":[{"text":[{"text":"Batch submission uses a shared seed sequence, so the eight results are comparable in a way independently submitted jobs are not."}],"correct":false,"tempting":[{"text":"Batching does not impose a shared seed, and eight shots with different stills would not be comparable even if it did."}]},{"text":[{"text":"Reviewing results in a group lets you judge which are genuinely good, rather than only whether each is better than the one before it."}],"correct":true,"tempting":null},{"text":[{"text":"Queued jobs are processed at the same model version, eliminating the risk that a silent update changes the output partway through a session."}],"correct":false,"tempting":[{"text":"A real provenance concern that batching does not actually protect against over a long queue."}]},{"text":[{"text":"Batch pricing is typically lower per second than interactive generation, so the same review can be done across more takes for the same spend."}],"correct":false,"tempting":[{"text":"Asserts a batch discount that these services generally do not offer."}]}],"order":[0,3,2,1],"why":null},"prev":{"slug":"draft-passes-and-quality-ladders","title":"Test the idea at a tenth of the price","minutes":8},"next":{"slug":"subscription-or-top-up","title":"The arithmetic nobody does before subscribing","minutes":8}}}