Use Kirby for big page

I’m considering using Kirby for a website where users (around 30,000) can register in the frontend and create and maintain their own content there. The question is, should I store everything in a database? And if so, can I also display and maintain the data from the database in the panel?

Storing content as separate files is generally acceptable unless you plan to load everything simultaneously. For efficient searching, consider using an external service such as MeiliSearch, Algolia, or Loupe-PHP to maintain performance.

Having 30,000 users loaded from files could significantly slow down Kirby when trying to access user data. You can find more information at How many (front-end user) accounts can Kirby handle!? - #2 by Manuel.
It may be necessary to virtualize the users, load them from a database, or utilize an external authentication service.

1 Like

Okay, but if I store all the data in a database, can I still maintain it via the panel?

Content

Based on the use case you described I do not think you need to store the content in a database. Kirby will be fast enough as long as you put the user created content into “grouped” folders to keep it fast. If you do not “group” the folders then Kirby will load many when accessing children of the parent or siblings of a current page.

SLOW: 30k user content folders all in one parent folder

content/user-00001/
....
content/user-30000/

FASTER: grouped at managable size in folders

content/00/user-00001/
...
content/00/user-00999/
content/01/user-01000/
...
content/01/user-01999/
....
content/29/user-29000/
content/29/user-29999/

The same logic is applies by the kirby UUID cache in case you want to take a look at the folders created. see site/cache/{HOST}/uuid/…

Keep in mind that this in only the content folder structure. Using custom routing you can still have clean, user facing URLS.

https://example.com/user/027012
pattern => user/(:any)

then get the first to chars of the id and make the page id

return [
  'routes' => [
    [
      'pattern' => 'user/(:any)',
      'action'  => function ($id) {
          if ($page = page(substr($id, 0, 2)."/user-".$id)) {
               return site()->visit($page);
          }
          go('/');
      }
    ],
  ]
];

Users

Users from a database have been discussed in this thread but you might need a bit more advanced version to delay the loading of all users. The problem here is that with Kirbys default it will load 3 files per User. With the db setup it will make a single query (which you can optimize on the db with a cached view etc).

And yes. The users will still appear in the panel. To make them editable you will need to overwrite the user models storage methods to setting email and credentials. I have done that before but with the upcoming release of K5 that code would not work anymore so I wont share it.