whereBinary(): Case-Sensitive MySQL Queries in Laravel | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    whereBinary(): How to Run Case-Sensitive MySQL Queries in Laravel 13.27        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)

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

 [  Laravel ](https://msaied.com/articles?category=laravel) [  Tips &amp; Tricks ](https://msaied.com/articles?category=tips-tricks)  #Laravel   #MySQL   #Query Builder   #Laravel 13   #Eloquent  

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

     26 Aug 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

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

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fwherebinary-how-to-run-case-sensitive-mysql-queries-in-laravel-1327&text=whereBinary%28%29%3A+How+to+Run+Case-Sensitive+MySQL+Queries+in+Laravel+13.27) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fwherebinary-how-to-run-case-sensitive-mysql-queries-in-laravel-1327) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  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. 

      Q02  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. 

      Q03  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. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Compile PHP to Native Binaries with TypePHP](https://cdn.msaied.com/599/a0eb0516fcca2a7c2e83f4aabf206988.png) TypePHP AOT Compiler PHP Performance 

### Compile PHP to Native Binaries with TypePHP

The Swoole team has open-sourced TypePHP, an Ahead-Of-Time (AOT) compiler that translates PHP source code into...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 26 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/compile-php-to-native-binaries-with-typephp) [ ![Multi-Tenant SaaS with Laravel: Isolating Tenant Data Using Row-Level Scoping](https://cdn.msaied.com/594/c38a3d613735b3f43e77683aeb0cce84.png) laravel multi-tenancy saas 

### Multi-Tenant SaaS with Laravel: Isolating Tenant Data Using Row-Level Scoping

Row-level multi-tenancy keeps your schema simple but demands discipline. Learn how to enforce tenant isolation...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 26 Aug 2026     3 min read  

  Read    

 ](https://msaied.com/articles/multi-tenant-saas-with-laravel-isolating-tenant-data-using-row-level-scoping) [ ![Query Binding Masking and whereBinary() in Laravel 13.27](https://cdn.msaied.com/597/bd82bbbaee7d7826a7a3a2f4e8b77330.png) Laravel 13.27 Eloquent Query Builder 

### Query Binding Masking and whereBinary() in Laravel 13.27

Laravel 13.27 ships query binding masking for safer exception messages, a whereBinary() family for byte-exact...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 26 Aug 2026     4 min read  

  Read    

 ](https://msaied.com/articles/query-binding-masking-and-wherebinary-in-laravel-1327) 

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

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
