PHPackages                             laramint/queryguard - 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. [Testing &amp; Quality](/categories/testing)
4. /
5. laramint/queryguard

ActiveLibrary[Testing &amp; Quality](/categories/testing)

laramint/queryguard
===================

Zero-config CI gate for Laravel: auto-instruments your test suite, baselines query counts, and fails PRs that introduce N+1s or query regressions.

v0.1.0(3w ago)19MITPHPPHP ^8.2CI passing

Since May 19Pushed 3w agoCompare

[ Source](https://github.com/laramint/queryguard)[ Packagist](https://packagist.org/packages/laramint/queryguard)[ RSS](/packages/laramint-queryguard/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (8)Versions (3)Used By (0)

 [![QueryGuard](art/queryguard-logo.png)](art/queryguard-logo.png)

 **Zero-config CI gate for Laravel query regressions.**
 Baseline query counts per test, surface N+1 patterns, and fail builds when tests drift — without manual per-test assertions.

 [![Laravel](https://camo.githubusercontent.com/0474b77dc144caf650d9ff3c367cd2c832c74450aacd78cb2f4364ab570fde4f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3925323025374325323031302532302537432532303131253230253743253230313225323025374325323031332d7265643f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c)](https://camo.githubusercontent.com/0474b77dc144caf650d9ff3c367cd2c832c74450aacd78cb2f4364ab570fde4f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d3925323025374325323031302532302537432532303131253230253743253230313225323025374325323031332d7265643f7374796c653d666c61742d737175617265266c6f676f3d6c61726176656c) [![PHP](https://camo.githubusercontent.com/b62a93fb4f213eea83a8e52bb4c5461696e4a6b91d7452ce2487abfd70659c7b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870)](https://camo.githubusercontent.com/b62a93fb4f213eea83a8e52bb4c5461696e4a6b91d7452ce2487abfd70659c7b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d3737374242343f7374796c653d666c61742d737175617265266c6f676f3d706870) [![License](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265) [![Sponsor](https://camo.githubusercontent.com/3e47708dc2aa829eb49a90d2f92907ff3d54743907debef18ac1061bb02a082b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53706f6e736f722d4769744875622d4541344141413f7374796c653d666c61742d737175617265266c6f676f3d6769746875622d73706f6e736f7273)](https://camo.githubusercontent.com/3e47708dc2aa829eb49a90d2f92907ff3d54743907debef18ac1061bb02a082b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53706f6e736f722d4769744875622d4541344141413f7374796c653d666c61742d737175617265266c6f676f3d6769746875622d73706f6e736f7273)

 [![Buy Me a Coffee](https://camo.githubusercontent.com/fbc0d58eeb26312165d87448dbc704659f68c6b9fee054c24177388b17f5b3a9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4275792532304d6525323061253230436f666665652d4d724d617263684f6e652d4646444430303f7374796c653d666c61742d737175617265266c6f676f3d6275792d6d652d612d636f66666565266c6f676f436f6c6f723d626c61636b)](https://www.buymeacoffee.com/MrMarchOne)

QueryGuard
==========

[](#queryguard)

> **Zero-config CI gate for Laravel.** Auto-instruments your test suite, baselines query counts per test, and fails PRs that introduce N+1s or query regressions — without you adding a single assertion.

Existing Laravel query tools either run only in dev mode (`beyondcode/laravel-query-detector`, Debugbar) or require devs to opt-in per test with manual assertions (`mattiasgeniar/phpunit-query-count-assertions`). Neither catches regressions automatically in CI on an existing suite.

QueryGuard does. Install, baseline once, and from then on every PR that pushes a test's query count past its baseline (or introduces a new N+1 pattern) fails the build with a precise diff.

Install
-------

[](#install)

```
composer require --dev laramint/queryguard
```

Register the PHPUnit extension in `phpunit.xml`:

```

```

Usage
-----

[](#usage)

```
# Record the baseline (do this once, commit the file).
php artisan queryguard:baseline

# In CI, this exits non-zero on regression:
php artisan queryguard:check

# Or run phpunit directly with the env var:
QUERYGUARD_MODE=check vendor/bin/phpunit
```

Commit `tests/.queryguard-baseline.json` to git — PR diffs naturally show *"this test went from 4 to 17 queries."*

Per-test budgets (optional)
---------------------------

[](#per-test-budgets-optional)

```
use QueryGuard\Attributes\QueryBudget;

#[QueryBudget(max: 5)]
public function test_index_is_fast(): void { /* ... */ }
```

GitHub Actions
--------------

[](#github-actions)

```
- name: QueryGuard
  run: |
    php artisan queryguard:check --markdown > queryguard.md || EXIT=$?
    gh pr comment "$PR_NUMBER" --body-file queryguard.md
    exit ${EXIT:-0}
  env:
    PR_NUMBER: ${{ github.event.pull_request.number }}
    GH_TOKEN: ${{ github.token }}
```

Configuration
-------------

[](#configuration)

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

Then edit `config/queryguard.php` for tolerances, ignore patterns, slow-query threshold, and N+1 detection threshold.

How it works
------------

[](#how-it-works)

1. The PHPUnit extension hooks `testPrepared` / `testFinished` and registers a `DB::listen` callback that records every query per-test.
2. Each query's SQL is normalized into a stable signature (literals stripped, `IN (?,?,?)` collapsed, keywords lowercased) so the same logical query matches across runs.
3. At end of run, the recorded profiles are either written to `tests/.queryguard-baseline.json` (in `baseline` mode) or diffed against it (in `check` mode).
4. Any of the following exits the run non-zero:
    - A test's query count exceeds `baseline + tolerance`
    - The same query signature is executed more than `n_plus_one.threshold` times in a single test
    - A `#[QueryBudget]` is exceeded

Slow queries and new query signatures are reported as warnings (non-fatal) by default.

License
-------

[](#license)

MIT.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance95

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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

Every ~0 days

Total

2

Last Release

22d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/23707114?v=4)[Abdelrahman Muhammed](/maintainers/mrmarchone)[@mrmarchone](https://github.com/mrmarchone)

---

Top Contributors

[![mrmarchone](https://avatars.githubusercontent.com/u/23707114?v=4)](https://github.com/mrmarchone "mrmarchone (10 commits)")

---

Tags

laramintlaravelopen-sourcephpphpunitpestlaravelperformancequerycin-plus-one

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/laramint-queryguard/health.svg)

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

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k51.0M7.4k](/packages/larastan-larastan)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[spatie/laravel-health

Monitor the health of a Laravel application

88011.3M149](/packages/spatie-laravel-health)[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.7M64](/packages/spatie-laravel-responsecache)[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15104.9k4](/packages/calebdw-larastan)

PHPackages © 2026

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