I was surprised to discover that add_role() modifies the database and fails if the role already exists. There are two implications here, one first more serious than the other: 1) if you're in development and update your add_role code, you must first remove_role() 2) once you have it right, you should never have to run that code again.

So typically I have been putting my add_role() inside a wp_loaded action hook. And since I'm in development, I've also added a remove_role() before my add_role so I can be sure that if I modify my list of caps, it will actually take effect.

But clearly this is now being run every time a page of the blog is being accessed. Okay, I could put it in an admin-only action, or I could create a plugin page maybe under Users or Tools where this role can be created once. I guess I'm hoping there's a simpler, more elegant solution out there.

I don't imagine there's a run_once kind of action is there?

Or is the best practice just to add the role and then use add_cap() a bunch of times? And even then I imagine add_cap is accessing the db.

Just thinking in terms of the best way to reduce unncessary db access. What are your best practices?

  • Awesome! Thanks for this question..Just adding remove_role() function before add_role() helped me. May 10, 2013 at 2:06

1 Answer 1


The user roles and capabilities are saved in the database so once you have you have used add_role() its saved and then next load WordPress will know that role just like the built in roles.

Now if you look at the function add_role() more specifically at line 141 you will see that it only saves the role and capabilities in the database if the var $use_db is set to true (which he is by default) so you can simply change it before you call your add_role() function and the role won't be saved.


//globalize $wp_roles
global $wp_roles;
//set use_db to flase
$wp_roles->use_db = false;
//then add your role
$wp_roles->add_role( $role, $display_name, $capabilities );


If its in a test/development environment then i see no downside, but if you are on a live environment then you save the time it take to create that on role every load.

As for best practice run once, if in a plugin you should use register_activation_hook and for any thing else i use a simple custom made conditional function:

function run_once($key){
    $test_case = get_option('run_once');
    if (isset($test_case[$key]) && $test_case[$key]){
        return false;
        $test_case[$key] = true;
        return true;

if (run_once('add_user_role')){
    //do you stuff and it will only run once
  • Aw crap. I even knew about that too from some earlier rooting about the WP_Roles class. Can you think of any downside to NOT using the database for roles? And is there a WP best practice for doing something only once?
    – Tom Auger
    Aug 11, 2011 at 17:31
  • Thanks for the update - I like the simplicity of the update_option solution
    – Tom Auger
    Aug 16, 2011 at 9:32
  • Not really satisfying but it seems to be the best solution 👍
    – Blackbam
    Feb 4, 2019 at 14:22
  • This function run_once increasing too much read/write database operations on each page load. Please don't use this. Mar 11, 2020 at 18:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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