PHPackages                             mojahed/multiquery - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. mojahed/multiquery

ActiveLibrary[Database &amp; ORM](/categories/database)

mojahed/multiquery
==================

Parallel MySQL query execution for Laravel projects - Run multiple MySQL queries in parallel for efficient execution.

1.0.0(2mo ago)08MITPHPPHP ^8.1

Since May 17Pushed 2mo agoCompare

[ Source](https://github.com/md-mojahed/laravel-multiquery)[ Packagist](https://packagist.org/packages/mojahed/multiquery)[ RSS](/packages/mojahed-multiquery/feed)WikiDiscussions master Synced 3w ago

READMEChangelogDependenciesVersions (2)Used By (0)

Mojahed MultiQuery — Laravel Package
====================================

[](#mojahed-multiquery--laravel-package)

Fire multiple MySQL queries in parallel using a binary. Dashboard stats that took 500ms now take 50ms.

Requirements
------------

[](#requirements)

- PHP 8.1+
- Laravel 10, 11, or 12
- `msquery` binary installed on server

Installation
------------

[](#installation)

```
composer require mojahed/multiquery
```

Auto-discovery registers everything. No manual setup needed.

Binary Setup
------------

[](#binary-setup)

Install the `msquery` binary on your server:

```
cp msquery-linux-amd64 /usr/local/bin/msquery
chmod +x /usr/local/bin/msquery
```

Add to `.env`:

```
MULTIQUERY_BIN=/usr/local/bin/msquery
MULTIQUERY_TIMEOUT=30
```

Publish Config (Optional)
-------------------------

[](#publish-config-optional)

```
php artisan vendor:publish --tag=multiquery-config
```

---

Usage
-----

[](#usage)

### Basic — Raw SQL

[](#basic--raw-sql)

```
use Mojahed\Facades\MultiQuery;

[$users, $orders, $revenue] = MultiQuery::run([
    "SELECT COUNT(*) as total FROM users",
    "SELECT COUNT(*) as total FROM orders",
    "SELECT SUM(amount) as total FROM payments",
]);
```

### Eloquent Builder with mq()

[](#eloquent-builder-with-mq)

```
// mq() replaces terminal methods like get(), first(), count()
[$users, $orders] = MultiQuery::run([
    User::where('active', 1)->mq('get'),
    Order::where('status', 'pending')->mq('get'),
]);
```

### All Supported Modes

[](#all-supported-modes)

```
[$users, $user, $count, $sum, $avg, $min, $max, $names, $email, $exists] = MultiQuery::run([
    User::where('active', 1)->mq('get'),             // Collection of Users
    User::where('id', 1)->mq('first'),               // single User instance or null
    Order::mq('count'),                              // integer
    Order::mq('sum', 'amount'),                      // float
    Order::mq('avg', 'amount'),                      // float
    Order::mq('min', 'amount'),                      // mixed (smallest value)
    Order::mq('max', 'amount'),                      // mixed (largest value)
    User::where('active', 1)->mq('pluck', 'name'),   // ['Mojahed', 'Rahim']
    User::where('id', 1)->mq('value', 'email'),      // single scalar value
    Order::where('status', 'pending')->mq('exists'), // boolean
]);
```

> **Note:** `count`, `sum`, `avg`, `min`, and `max` modes automatically rewrite the query to use the proper SQL aggregate function. You don't need to write `selectRaw('COUNT(*)')` yourself — just pass the mode and column.

### Aggregates with GROUP BY

[](#aggregates-with-group-by)

When using `groupBy`, don't use aggregate modes like `mq('count')` — they rewrite the SELECT and won't give you grouped results. Instead, write the aggregate yourself and use `mq('get')`:

```
// ❌ Wrong — mq('count') with groupBy only returns first row
Order::groupBy('status')->mq('count')

// ✅ Correct — write the aggregate, use mq('get')
Order::selectRaw('status, COUNT(*) as total')
    ->groupBy('status')
    ->mq('get')
```

This applies to any query where you need grouped aggregates or custom aggregate expressions.

### Eager Loading (with) Not Supported

[](#eager-loading-with-not-supported)

Eloquent's `with()` eager loading does **not** work with `mq()`. Eager loading fires separate queries behind the scenes after the main query — since `mq()` extracts raw SQL and sends it to the Go binary, Laravel never gets a chance to run those follow-up queries.

```
// ❌ Won't load relations — with() is ignored
User::with('orders')->mq('get')

// ✅ Use join instead
User::select('users.*', 'orders.amount')
    ->join('orders', 'orders.user_id', '=', 'users.id')
    ->mq('get')

// ✅ Or run relations as separate parallel queries
MultiQuery::run([
    'users'  => User::mq('get'),
    'orders' => Order::whereIn('user_id', [1, 2, 3])->mq('get'),
]);
```

### Named Keys

[](#named-keys)

```
$results = MultiQuery::run([
    'users'   => User::where('active', 1)->mq('get'),
    'pending' => Order::where('status', 'pending')->mq('count'),
    'revenue' => Payment::mq('sum', 'amount'),
]);

$results['users']    // Collection of User
$results['pending']  // integer
$results['revenue']  // float
```

### Different DB Connection

[](#different-db-connection)

```
// all queries on reporting connection
MultiQuery::connection('reporting')->run([
    User::mq('get'),
    Order::mq('count'),
]);
```

### Manual Model Mapping (for DB::table queries)

[](#manual-model-mapping-for-dbtable-queries)

```
// DB::table has no model context — provide map
[$users] = MultiQuery::run(
    queries: [
        DB::table('users')->where('active', 1)->mq('get'),
    ],
    map: [
        0 => User::class,
    ]
);

// named key mapping
$results = MultiQuery::run(
    queries: [
        'users' => DB::table('users')->mq('get'),
    ],
    map: [
        'users' => User::class,
    ]
);
```

### Manual Convert

[](#manual-convert)

```
// convert after run
[$rawUsers] = MultiQuery::run([
    DB::table('users')->mq('get'),
]);

$users = MultiQuery::convert($rawUsers, User::class);

// or collection macro
$users = collect($rawUsers)->fromMq(User::class);
```

### Mixed — Raw SQL + Builder

[](#mixed--raw-sql--builder)

```
[$stats, $users] = MultiQuery::run([
    "SELECT COUNT(*) as total FROM legacy_table",
    User::where('active', 1)->mq('get'),
]);
```

---

Error Handling
--------------

[](#error-handling)

```
use Mojahed\Exceptions\MultiQueryException;

try {
    [$users, $orders] = MultiQuery::run([
        User::mq('get'),
        Order::mq('get'),
    ]);
} catch (MultiQueryException $e) {
    $e->getFailedIndex();   // which query failed (0-based)
    $e->getErrorString();   // MySQL error message
    $e->getResults();       // all results including successful ones
}
```

Disable throw in `config/multiquery.php`:

```
'throw' => false,
// failed queries return null instead of throwing
```

---

Real Dashboard Example
----------------------

[](#real-dashboard-example)

```
$stats = MultiQuery::run([
    'total_users'     => User::mq('count'),
    'active_users'    => User::where('active', 1)->mq('count'),
    'total_orders'    => Order::mq('count'),
    'pending_orders'  => Order::where('status', 'pending')->mq('count'),
    'total_revenue'   => Payment::where('status', 'paid')->mq('sum', 'amount'),
    'today_revenue'   => Payment::whereDate('created_at', today())->mq('sum', 'amount'),
    'max_order'       => Order::mq('max', 'amount'),
    'min_order'       => Order::mq('min', 'amount'),
    'recent_orders'   => Order::latest()->take(10)->mq('get'),
    'top_products'    => DB::table('order_items')
                           ->select('product_id', DB::raw('SUM(qty) as sold'))
                           ->groupBy('product_id')
                           ->orderByDesc('sold')
                           ->take(5)
                           ->mq('get'),
]);

// all 8 queries fired simultaneously
// total time = slowest single query
// instead of sum of all queries
```

---

Config Reference
----------------

[](#config-reference)

```
// config/multiquery.php
return [
    'binary'     => env('MULTIQUERY_BIN', '/usr/local/bin/msquery'),
    'connection' => env('DB_CONNECTION', 'mysql'),
    'timeout'    => env('MULTIQUERY_TIMEOUT', 30),
    'throw'      => true,
];
```

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance86

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

68d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/92214734?v=4)[Md Mojahedul Islam](/maintainers/md-mojahed)[@md-mojahed](https://github.com/md-mojahed)

---

Tags

laravelconcurrentdatabaseperformancemysqlparallelmultiquery

### Embed Badge

![Health badge](/badges/mojahed-multiquery/health.svg)

```
[![Health](https://phpackages.com/badges/mojahed-multiquery/health.svg)](https://phpackages.com/packages/mojahed-multiquery)
```

###  Alternatives

[codezero/laravel-unique-translation

Check if a translated value in a JSON column is unique in the database.

1881.0M8](/packages/codezero-laravel-unique-translation)[sarfraznawaz2005/indexer

Laravel package to monitor SELECT queries and offer best possible INDEX fields.

562.7k](/packages/sarfraznawaz2005-indexer)[awssat/laravel-sync-migration

Laravel tool helps to sync migrations without refreshing the database

10823.4k](/packages/awssat-laravel-sync-migration)[moharrum/laravel-adminer

Adminer database management tool for your Laravel application.

451.0k](/packages/moharrum-laravel-adminer)[vitalibr/laravel5-exporter

MySQL Workbench Schema Exporter for Laravel 5.0

161.0k](/packages/vitalibr-laravel5-exporter)[ramadan/easy-model

A Laravel package for enjoyably managing database queries.

111.6k](/packages/ramadan-easy-model)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
