---
title: "Concurrent batch fetches — Git for Laravel | Roundly"
description: "Fan many reads out over one Http::pool() round trip and get a keyed BatchResult that separates successes from per-key failures."
url: https://roundly-consulting.com/open-source/docs/git-for-laravel/batch
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Git for Laravel](https://roundly-consulting.com/open-source/docs/git-for-laravel.md)

# Concurrent batch fetches

batch() fans a list of reads out over a single Http::pool() round trip and returns a keyed BatchResult that separates successes from per-key failures — no exception unless you ask for one:

```php
$github = Git::github();

$result = $github->batch()->languages(['acme/api', 'acme/web']); // BatchResult<array<string,int>>

$result->results();          // ['acme/api' => ['PHP' => 80, ...], ...]
$result->get('acme/api');    // one key's result, or null
$result->successful();       // true when no key failed
$result->failed();
count($result);              // successful keys

foreach ($result->errors() as $key => $error) {   // BatchError: key, status, message
    report("{$key} failed with {$error->status}");
}

$result->throwOnError();     // raises BatchRequestException if any key failed
```

## Available batches

```php
$github->batch()->repositories(['acme/api', 'acme/web']);            // BatchResult<Repository>
$github->batch()->contents('acme/api', ['README.md', 'composer.json']); // BatchResult<FileContent>, keyed by file
$github->batch()->contents('acme/api', ['README.md'], ref: 'develop');
$github->batch()->pullRequest(['main' => 'acme/api#7']);             // id => PullRequest, ref "path#number"
```

- repositories($paths) and languages($paths) — keyed by repository path.
- contents($path, $files, $ref) — files from one repository, keyed by file path. A path that names a directory fails only its own key (a BatchError with no status); the other files still come back.
- pullRequest($references) — your own keys mapped to path#number references. A reference that isn’t path#number with a number of 1 or more throws InvalidArgumentException naming it, before anything is sent.

Pooled requests carry the same authentication as single requests, including self-refreshing credentials, but bypass the ETag conditional cache. Inputs larger than batch.concurrency (25 by default) are split into sequential pools.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/git-for-laravel.md)
