Skip to content

Conversation

@Michael-Stokoe
Copy link

Problem

When using collection tags in Antlers templates, entries with taxonomy fields triggered individual database queries for each taxonomy term, causing major N+1 query performance issues.

Solution

Implemented proper Eloquent relationships between entries and taxonomy terms using a pivot table, enabling eager loading to eliminate N+1 queries.

Performance Impact

  • Before: Actual query equation: 1 + (N entries × M taxonomy fields) queries
  • After: 2 queries total
  • Example: 10 entries with 2 taxonomy fields: 21 queries → 2 queries (90% reduction)

Changes

  • Added entry_term pivot table for entry-taxonomy relationships
  • Enhanced Entry models with taxonomy relationships and auto-eager loading
  • Added SyncTaxonomyRelationships command for existing data migration
  • Maintains full backward compatibility - no template changes required

Migration

php artisan vendor:publish --tag=statamic-eloquent-entry-term-pivot
php artisan migrate
php please eloquent:sync-taxonomy-relationships

Backward Compatibility

✅ Existing templates work unchanged
✅ API responses remain identical
✅ No breaking changes

Before and afters captured on a local site with real, live data

Before:
image

After:
image


Before:
CleanShot 2025-11-24 at 15 06 44@2x

After:
CleanShot 2025-11-24 at 15 07 10@2x

@Michael-Stokoe Michael-Stokoe changed the title Fix outrages query counts when using Eloquent driver and querying terms on entries Fix outragous query counts when using Eloquent driver and querying terms on entries Nov 24, 2025
@Michael-Stokoe Michael-Stokoe changed the title Fix outragous query counts when using Eloquent driver and querying terms on entries Fix outrageous query counts when using Eloquent driver and querying terms on entries Nov 24, 2025
@Michael-Stokoe
Copy link
Author

My bad - fixing those test failures now.

@duncanmcclean duncanmcclean linked an issue Nov 24, 2025 that may be closed by this pull request
@ryanmitchell
Copy link
Contributor

Thanks for this PR and all the work on it, it's definitely something I'm keen to solve as well. The question for me is whether we solve it in this driver or we wait for core to handle pivots - I want to avoid us choosing an approach that makes switching later more difficult.

I'm going to leave this for @jasonvarga to make a call on when he has time.

@Michael-Stokoe
Copy link
Author

Michael-Stokoe commented Nov 24, 2025

Thanks for this PR and all the work on it, it's definitely something I'm keen to solve as well. The question for me is whether we solve it in this driver or we wait for core to handle pivots - I want to avoid us choosing an approach that makes switching later more difficult.

I'm going to leave this for @jasonvarga to make a call on when he has time.

Well whatever you guys decide, I've fixed regressions in existing tests and added a couple of extras for the work I've carried out. Also ran Pint on all the files I changed so there should be no checks failing now.

Looking forward to seeing what you guys do with this - it's been a major bug-bear for us. :)

@FrittenKeeZ
Copy link
Contributor

We're also experiencing this issue, which has actually caused our comwell.com site to crash due to the database being overloaded, so this is the highest priority for us right now.

@ryanmitchell
Copy link
Contributor

You can patch this PR in or even use the code here in your own repositories in the mean time - the driver makes these kind of changes quite configurable.

@JesperFiltenborg
Copy link

@Michael-Stokoe I've attempted to implement this patch into my application.
An Exception is thrown when calling the \Statamic\Facades\Term::query() function.

I've found the issue in our code when calling the value method on a Statamic\Fields\Value

@Michael-Stokoe
Copy link
Author

@Michael-Stokoe I've attempted to implement this patch into my application. An Exception is thrown when calling the \Statamic\Facades\Term::query() function.

I've found the issue in our code when calling the value method on a Statamic\Fields\Value

Are you able to provide a code example so I can test and implement a fix in my PR?

@JesperFiltenborg
Copy link

We call the following
Nav::find('*****')->in($locale)->pages()->all()->map->toAugmentedArray();
Then we loop over the data set and resolve the values.
When one of the values have the fieldtype Statamic\Fieldtypes\Terms the error happens when calling resolve.
Unfortunately I'm not able to send you a full code example.

But you can just run tinker and call \Statamic\Facades\Term::query() and see the exception.

@Michael-Stokoe
Copy link
Author

Awesome. I'll take a look as soon as I'm back at my laptop :)

@Michael-Stokoe
Copy link
Author

Right. Here are my findings:

Tinkerwell is doing some serialisation which is causing PHP Memory Limit exceptions. Bizarre, but ok (Especially with memory_limit=-1).

CleanShot 2025-11-25 at 20 21 19@2x

So let's use tinker via the command line...

CleanShot 2025-11-25 at 20 22 23@2x

Well that's odd. 🤔

Let's try serialising that now...

Ahh. Memory limits and xdebug warning about stack depths of 512 frames. Doesn't matter how I attempt to serialise it, it's just a lot of data when we're talking about complex navigation structures. For each Nav entry, it's getting UuidEntryModel, as well as the augmentable entry, and well, everything related to the Entry if the nav item is an entry. Who knows how large they could get?

I'm starting to see why Statamic devs push the flat-file content driver now to be honest. (But that can be problematic when you introduce load balancers and hitting file descriptor limits on our linux-based servers 😬).

I think it's safe to disregard this PR for now. There's too many open questions and I don't want to touch Statamic Core in an attempt to resolve issues with Eloquent.

@FrittenKeeZ
Copy link
Contributor

Would it be possible to have terms repository use Stache as if it was a file driver, but instead pull all terms from the database?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix taxonomy term query counts

5 participants