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.