whereBinary(): Case-Sensitive MySQL Queries in Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. whereBinary(): How to Run Case-Sensitive MySQL Queries in Laravel 13.27

   [Laravel](https://www.msaied.com/public/articles?category=laravel) [Tips &amp; Tricks](https://www.msaied.com/public/articles?category=tips-tricks) 

 whereBinary(): How to Run Case-Sensitive MySQL Queries in Laravel 13.27
========================================================================

 Laravel 13.27 adds whereBinary(), orWhereBinary(), whereNotBinary(), and orWhereNotBinary() — clean query-builder methods for byte-exact MySQL comparisons without dropping down to whereRaw().

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 26 Aug 2026 · Updated 27 Aug 2026 · 4 min read

ShareCopy linkCopied

 ![whereBinary(): How to Run Case-Sensitive MySQL Queries in Laravel 13.27](https://cdn.msaied.com/600/0c7655400b43d3b85d1d1e9d0f4c8094.png) 

  On this page +1. [The Problem with Laravel's Default MySQL Collation](#the-problem-with-laravels-default-mysql-collation)
2. [Introducing whereBinary() in Laravel 13.27](#introducing-wherebinary-in-laravel-1327)
3. [What "Binary" Actually Changes](#what-quotbinaryquot-actually-changes)
4. [Engine Support and Test-Suite Implications](#engine-support-and-test-suite-implications)
5. [The Index Caveat — and How to Handle It](#the-index-caveat-and-how-to-handle-it)
6. [Related: Case-Sensitive LIKE](#related-case-sensitive-like)
7. [Key Takeaways](#key-takeaways)

 The Problem with Laravel's Default MySQL Collation
--------------------------------------------------

MySQL string comparisons in Laravel run through the default `utf8mb4_unicode_ci` collation, which treats several differences as irrelevant: case, accents, trailing whitespace, and some Unicode normalization variants. That is exactly what you want for a display-name search, and exactly what you do not want for a token, a slug, or any value where the bytes themselves are the identity.

This query silently matches `A7f3B9`, `a7f3b9`, `A7F3B9`, and even `A7f3B9 ` (note the trailing space):

```php
DB::table('invites')->where('token', $request->token)->first();

```

The traditional escape hatch was `whereRaw()`:

```php
DB::table('invites')->whereRaw('token = BINARY ?', [$request->token])->first();

```

That works, but it steps outside the query builder, making the clause harder to compose with scopes, `when()` calls, and other conditions.

Introducing whereBinary() in Laravel 13.27
------------------------------------------

Laravel 13.27 ships four new query-builder methods that wrap the `BINARY` cast cleanly:

```php
// Exact equality
DB::table('invites')->whereBinary('token', $request->token)->first();
// select * from `invites` where `token` = binary ?

// Negation
DB::table('users')->whereNotBinary('username', $username)->get();
// select * from `users` where `username` != binary ?

// OR variants
DB::table('users')
    ->where('id', $id)
    ->orWhereBinary('username', $username)
    ->get();
// select * from `users` where `id` = ? or `username` = binary ?

```

Values are still bound as parameters, so parameterization is identical to the `whereRaw()` approach. The difference is that the clause stays inside the builder and composes naturally with everything else.

Eloquent models work the same way:

```php
$invite = Invite::query()
    ->whereBinary('token', $request->token)
    ->where('expires_at', '>', now())
    ->firstOrFail();

```

What "Binary" Actually Changes
------------------------------

The `BINARY` keyword casts the operand to a binary string, forcing a byte-for-byte comparison. Four categories of difference start mattering:

- **Case** — `Ada` no longer equals `ada`.
- **Accents** — `resume` no longer matches `résumé`.
- **Trailing whitespace** — `'ada'` and `'ada '` are different byte lengths and no longer compare equal.
- **Unicode normalization** — `é` as one code point versus `e` plus a combining accent are distinct byte sequences.

The trailing-whitespace and normalization cases are the ones most likely to cause silent bugs, because they produce false positives rather than obvious failures.

Engine Support and Test-Suite Implications
------------------------------------------

MySQL and MariaDB support `whereBinary()`. Every other engine throws:

```yaml
RuntimeException: This database engine does not support binary comparison operations.

```

This is intentional. PostgreSQL and SQLite already compare strings case-sensitively by default, so a `BINARY` cast would either be a no-op or make a promise the driver cannot keep. If your test suite runs on SQLite but production runs on MySQL, any test covering a `whereBinary()` clause needs a MySQL-backed connection.

The Index Caveat — and How to Handle It
---------------------------------------

An index built on a `_ci` column cannot be used to satisfy a `BINARY` comparison, because the collations differ. On large tables, the recommended pattern is to let the index narrow the result set first, then apply the binary filter:

```php
DB::table('invites')
    ->where('token', $request->token)        // uses the index
    ->whereBinary('token', $request->token)  // filters to byte-exact matches
    ->first();

```

The better long-term fix for columns that should always be compared byte-exactly is to declare the right collation in the migration:

```php
$table->string('token')->collation('utf8mb4_bin')->unique();

```

This also solves something `whereBinary()` cannot: a unique index on a `_ci` column will reject `Ada` when `ada` already exists regardless of how you query. `whereBinary()` is a read-side tool; uniqueness enforcement is determined by the column's collation.

Related: Case-Sensitive LIKE
----------------------------

For pattern matching with wildcards, `whereLike()` already accepts a `caseSensitive` argument that compiles to `like binary` on MySQL:

```php
DB::table('users')->whereLike('username', 'ada%', caseSensitive: true);

```

Use `whereBinary()` for equality checks and `whereLike(..., caseSensitive: true)` for pattern matching — the query planner has more optimization options for `=` than for `LIKE`.

Key Takeaways
-------------

- `whereBinary()` was added in Laravel 13.27 alongside `orWhereBinary()`, `whereNotBinary()`, and `orWhereNotBinary()`.
- It replaces `whereRaw('column = BINARY ?', [...])` while keeping the query fully composable.
- Only MySQL and MariaDB are supported; other engines throw a `RuntimeException`.
- Binary comparisons bypass column indexes — use the double-condition pattern on large tables or set the column collation to `utf8mb4_bin`.
- `whereBinary()` is a read-side tool; unique constraint enforcement still depends on the column's collation.

*Source: [whereBinary(): Case-Sensitive MySQL Queries in Laravel — Laravel News](https://laravel-news.com/laravel-where-binary)*

- [Laravel](https://www.msaied.com/public/articles?search=Laravel)
- [MySQL](https://www.msaied.com/public/articles?search=MySQL)
- [Query Builder](https://www.msaied.com/public/articles?search=Query%20Builder)
- [Laravel 13](https://www.msaied.com/public/articles?search=Laravel%2013)
- [Eloquent](https://www.msaied.com/public/articles?search=Eloquent)

 Frequently asked questions 
---------------------------

  Does whereBinary() work with Eloquent models, or only the DB facade?It works with both. You can call whereBinary() on an Eloquent query builder just as you would on a DB::table() query, and it composes with other conditions like where(), when(), and query scopes.

   Will whereBinary() use my existing index on the column?Generally no. An index built under a \_ci collation cannot satisfy a BINARY comparison. On large tables, chain a regular where() first to let the index narrow the rows, then add whereBinary() to filter to byte-exact matches. For columns that are always compared byte-exactly, setting the column collation to utf8mb4\_bin in the migration is the better permanent fix.

   What happens if I use whereBinary() with a SQLite or PostgreSQL test database?Laravel throws a RuntimeException because those engines are not supported. If your test suite runs on SQLite but production uses MySQL, any test that exercises a whereBinary() clause needs to run against a MySQL-backed connection.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleCompile PHP to Native Binaries with TypePHP](https://www.msaied.com/public/articles/compile-php-to-native-binaries-with-typephp) [Next articleMask Query Bindings in Laravel Exception Messages](https://www.msaied.com/public/articles/mask-query-bindings-in-laravel-exception-messages)  

   On this page
-------------

1. [The Problem with Laravel's Default MySQL Collation](#the-problem-with-laravels-default-mysql-collation)
2. [Introducing whereBinary() in Laravel 13.27](#introducing-wherebinary-in-laravel-1327)
3. [What "Binary" Actually Changes](#what-quotbinaryquot-actually-changes)
4. [Engine Support and Test-Suite Implications](#engine-support-and-test-suite-implications)
5. [The Index Caveat — and How to Handle It](#the-index-caveat-and-how-to-handle-it)
6. [Related: Case-Sensitive LIKE](#related-case-sensitive-like)
7. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
