Performance on many Users

We’ve had similar talks with pages, and thus i have been wondering if i were to have alot of users, wouldn’t that draw on performance? as we don’t even have a way to categorize them. we can’t just sort them in several subfolders to make the collection smaller.

or what’s the best strategy on the long run?

What is many users? Are those users users with Panel access?

Just theoretical question before the actual coding.

  • No Panel Access for all except the admin
  • let’s add about 100-200 users a year.

where as a user is actually only tied to login frontend to verify certain things.

That makes it 1000 to 2000 users in 10 years, doesn’t sound like a lot.

Why don’t you just generate 5000 users programmatically for testing?

i’m not sure if my local testing machine is the best performance validation machine :disappointed_relieved: but i might as well give it a shot :wink:

I don’t think that 5000 to 10000 users will be a problem, as long as you don’t add lots of images, then it might be a problem with listing those users in the Panel.

nah. no images. the user account would only

  • tie other subpages via the user field
  • be used to log in frontend

it’s running 5000 creations right now. does it work similar to pages when getting a collection or filtering? or is it using less performance since it’s not always indexing siblings and whatsoever?

what would require more performance?
finding the user to validate a login?
i think i don’t need to create a list of all users though.

I haven’t tested users yet. But I once did a test in Kirby 2 with 10000 or so text only subpages in a single folder and that ran really fast, even with filtering.

<?php foreach($kirby->users()->sortBy('name','asc') as $user): ?>
    <li><?php echo $user->name() ?></li>
<?php endforeach ?>

5000 Users via local machine
This process used 313 ms for its computations It spent 796 ms in system calls
9200 Users
This process used 625 ms for its computations It spent 1610 ms in system calls

What if you don’t echo the username, but just loop through it? That eliminates the HTTP transfer time from the equation:

<?php foreach($kirby->users()->sortBy('name','asc') as $user): ?>
<?php endforeach ?>

if you take the idea from autoid plugin and give each user an unique id, update its value using the user hooks and setup a lookup-table to quickly find the user.
if you use the sha1 (not md5 since it might be public at some point) of the users email plus a secret token (sha1(user->email().’tokenxzy’)) you should be able to get to every user object quickly. if using a cache not a db, make 5000 files not an list with 5000 entries – that should be faster.
you could use sqlite or plugin with memcached to speed up the index even more.

the email could allready be used as an id internally but you can not use it for frontend code since all emails would be public then.

maybe i can add that to autoid plugin but i do not know yet when i find the time to do so.

This process used 656 ms for its computations It spent 1641 ms in system calls.

That’s without echoing anything.

the time measurements are the index() crawling all the user files, right?

do you really need a loop over all users? this can be avoided using an id (see above) and eased with some aggressive caching.

the panel also uses pagination for users. so i think it should be fine there.

i am not sure about the exact requirements, i am just collecting ideas to grasp the best way of managing if having users of this size.

usually the tasks which are involved are

  • create a user programmically (check if username / email exists - so i have to run though all users??)
  • login / logout - as an user identifies using email adresses - somewhat similar to “find()”
  • lookup usernames field in pages.

the test with 5000 to 10.000 users is also just somewhat a peak test to get a clue.
the pagination in users was ok for indexing. backend is not of concern if it takes more than a second.

it’s just like let’s say our controller is creating a user, but has to run though all users to check if there’s an existing one already, that this process takes too long or F-Up the performance…

if i could use a subpage in replacement to a user (e.g. having email + password field) and combine it with being able to login, then i could just seperate everything in subfolders to draw out more performance.

since i will need a page in addition to user, i might as well have a place where it saves everything together. (user for me is just the idea of having a login). Maybe writing a session when a user/key pair is correct (which is saved within a page) could be an alternative?