New to Craft, and unsure how it works under the hood. In terms of overall performance, I'm curious to know which of the following scenarios is the most performant approach in terms of DB queries and server strain.

SETUP: I'm building a sort of blog/forum hybrid with user-generated posts. But in this case, comments are not an afterthought tacked onto the main post (like most blogs). Instead, comments are a central part of the overall content. Sort of like StackExchange or Reddit.

SCALABILITY: Let's prepare for a site that grows to a million+ Posts... and millions more Comments.

IDEA 1: Build a traditional BlogPost/Comment system where each new Post requires users to upload a single image and a rich-text description. Then Comments are tacked on as usual.

IDEA 2: Build each BlogPost with a Matrix Row featuring only 2 fields [ image | rich-text ], and instead of tacking on traditional comments, simply append additional rows to the post's Matrix Field via front-end editor form.

While Idea 1 is well-tested and proven, I think Idea 2 might save a lot of computational power on page delivery.

If I understand correctly, Idea 1 must make at least 2 (and probably several) loops through the database, first the Blog and then the Comments...

But Idea 2 needs only one loop through the Post/Matrix to grab everything. And then even little things would become easier, (e.g. Comment count = how many rows in the Matrix. AND Image count = how many images in the entire Matrix field. AND most recently updated post = most recent Post/Matrix update, not most recent Comment).... all without doing additional queries on a Comments table.

QUESTION 1: Is my understanding flawed, or does Idea 2 make more sense in terms of fewer queries and server load?

QUESTION 2: With Craft, is it possible for a Matrix field to be appended row by row from a front-end form?

1 Answer 1


Regarding performance:

If you look at the database structure of Craft, you'll see that Matrix content is stored across multiple tables, with each block having its own record, just like entries do. I've never compared calculations, but I'd bet there's no significant difference in the DB performance between your two ideas. Using eager loading you could retrieve a BlogPost entry and all Comment entries related to it in three DB queries.

If you want to run a quick exercise to test your theory of performance, model out both options. Create one entry that has 10 "comment" Matrix blocks, and one entry that has 10 related "comment" entries. Don't even worry about a front end, just create two empty templates—one for each approach—that get the respective entry and its comments. Use the Yii front-end profiler (activated under your user account's Preferences tab) to check out the performance difference. This will suggest what kind of performance difference there might be.

Also keep in mind that once you layer on your page caching strategy, performance differences might be a moot point.

Regarding usability:

From a management standpoint, idea 1 sounds much easier to work with, as you're utilizing Craft's content structure in a natural way (as you said, idea 1 is a well-tested and proven approach to this use case). Craft already exposes a very streamlined API for creating, editing, deleting, and querying entries. Doing the same for a Matrix field on an entry is certainly possible, but you'll probably end up writing your own interface if you plan on doing that at scale.

Also consider the interface within Craft for you to manage things. A Comment entry type already has a dedicated admin section for you to browse, search, sort, and manage comments. Trying to do any sort of query across Matrix blocks distributed among BlogPost entries is not built in to Craft's interface; you'd have to write a whole plugin to add that functionality yourself.

I'd go with idea 1 for sure.

  • Ha. Beautiful answer. You confirmed what I feared.... I'm overthinking stuff again. thanks, Evan.
    – JJ.
    Apr 17, 2020 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.