Gemini Batch
Queue-driven batch processing for the Google Gemini API in Laravel. Send hundreds of AI requests as a single batch job at 50% cost — with optional PrismPHP integration.
use ObayesShelton\GeminiBatch\Facades\GeminiBatch;
$batch = GeminiBatch::create('gemini-2.0-flash')
->name('product-descriptions')
->onEachResult(ProductCopyHandler::class)
->then(NotifyAdmin::class);
foreach ($products as $product) {
$batch->addTextRequest(
request: Prism::text()
->using(Provider::Gemini, 'gemini-2.0-flash')
->withPrompt("Write a short product description for: {$product->name}"),
key: "product-{$product->id}",
meta: ['product_id' => $product->id],
);
}
$batch->dispatch(); // Queue handles submit → poll → process- 50% cost reduction via the Gemini Batch API
- Queue-driven pipeline — submit, poll with exponential backoff, process results
- Fluent API — create, add requests, dispatch
- PrismPHP integration —
addTextRequest()andaddStructuredRequest()(optional) - Per-request callbacks and batch completion handlers
- Auto-detection of inline vs file mode based on payload size
- Artisan commands —
gemini-batch:list,status,cancel,prune - Token tracking — prompt, completion, and thought tokens per request
composer require obayesshelton/gemini-batch
php artisan vendor:publish --tag=gemini-batch-migrations
php artisan migrateAdd your Gemini API key to .env — same key as PrismPHP, no extra credentials:
GEMINI_API_KEY=your-api-key- Getting Started — Installation and your first batch
- Adding Requests — Raw payloads or Prism
- Result Handlers — Processing results with per-request callbacks
- Configuration — Polling intervals, queues, input modes
- Artisan Commands — Monitor and manage batches from the CLI
The package works standalone or with PrismPHP. Without Prism, use raw Gemini payloads:
GeminiBatch::create('gemini-2.0-flash')
->addRawRequest(
request: ['contents' => [['role' => 'user', 'parts' => [['text' => 'Describe the process of photosynthesis.']]]]],
key: 'photosynthesis',
)
->addRawRequest(
request: ['contents' => [['role' => 'user', 'parts' => [['text' => 'What are the main ingredients in a Margherita pizza?']]]]],
key: 'pizza-ingredients',
)
->dispatch();Three integration layers — use whichever fits your stack:
| Method | Requires | Use Case |
|---|---|---|
addRawRequest() |
Nothing | Direct Gemini API payloads |
addTextRequest() |
echolabsdev/prism |
Prism text generation |
addStructuredRequest() |
echolabsdev/prism |
Prism structured JSON output |
Implement ResultHandler to process each result as it arrives:
use ObayesShelton\GeminiBatch\Contracts\ResultHandler;
class ProductCopyHandler implements ResultHandler
{
public function __invoke(GeminiBatchRequest $request, BatchResult $result): void
{
Product::find($request->meta['product_id'])
->update(['description' => $result->text()]);
}
}Publish the config with php artisan vendor:publish --tag=gemini-batch-config. Key options:
| Option | Default | Description |
|---|---|---|
polling.interval |
30 |
Seconds between status polls |
polling.max_interval |
120 |
Max backoff cap |
queue |
default |
Queue for batch jobs |
input_mode |
auto |
auto, inline, or file |
php artisan gemini-batch:list # List all batches
php artisan gemini-batch:status {id} # Detailed batch status
php artisan gemini-batch:cancel {id} # Cancel a running batch
php artisan gemini-batch:prune # Clean up old batchesContributions are welcome! Please submit a pull request.
MIT License. See LICENSE for details.