It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

How to Query for licensed users when have over 900 active licenses

I asked this on someone else's question: but never got a response, so I'm re-asking it as it's own question now.

When we were under 500 users the below macro worked perfectly for me; however, now that we are over 900 users - the system times out. Is there a better way to get all Confluence users name and last login for audit purposes? 

## Macro title: Last Login
## Macro has a body: N
## Body processing: Selected body processing option
## Output: Selected output option
## Developed by: Andrew Frayling
## Date created: 11/02/2012
## Installed by: <your name>
## Macro to display the last login date of users who have access to the current space
## @noparams
#set($containerManagerClass = $content.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod = $containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager = $getInstanceMethod.invoke(null,null))
#set($containerContext = $containerManager.containerContext)
#set($loginManager = $containerContext.getComponent('loginManager'))
#set($users = $userAccessor.getUsers())

<table class="confluenceTable">
    <th class="confluenceTh">User</th>
    <th class="confluenceTh">Last Successful Login</th>
#foreach($user in $users)
  ## list the last login date of users who can view the current space
      <td class="confluenceTd">#usernameLink($</td>
    #if (!$loginManager.getLoginInfo($user).lastSuccessfulLoginDate)
      <td class="confluenceTd" style="background-color:#ff0000"><strong>NEVER</strong></td>
      <td class="confluenceTd">$action.dateFormatter.formatDateTime($loginManager.getLoginInfo($user).lastSuccessfulLoginDate)</td>


1 answer

1 accepted

Hi @mary.moore,

it looks like you've reached the limit of what can be reasonably achieved with User Macros. You might be able to find some short-term workarounds but sooner or later you'll hit the same or similar problems as this solution obviously doesn't scale.

A better approach would be to directly query the Confluence database for this kind of data. There's an official Atlassian article that presents some example Queries for this. Using SQL queries you are so much more flexible and it's much more performant.

To get the exact same data that your User Macro currently generates you could use this SQL:

SELECT cu.user_name,
FROM cwd_user cu
JOIN user_mapping um ON um.username = cu.user_name
LEFT JOIN logininfo li ON li.username = um.user_key
ORDER BY li.successdate;

If you want to display your data in Confluence you could simply use PocketQuery to do so. With a few modifications to the standard PocketQuery template you can even get the same representation as from your User Macro:


This is the PocketQuery Template code I've used:

<table class="aui confluenceTable pocketquery-table">
<th class="confluenceTh">User</th>
<th class="confluenceTh">Last Successful Login</th>

#foreach ($user in $result)
<td class="confluenceTd">#usernameLink($user.user_name)</td>
<td class="confluenceTd">$dateFormatter.formatDateTime($user.successdate)</td>
<td class="confluenceTd" style="background-color:#ff0000"><strong>NEVER</strong></td>

So what's the difference between row 2 (PocketQuery) and 3 (User Macro) in the image now?

  • PocketQuery uses a SQL query which is a lot faster.
  • SQL is much more flexible so once you reach 100.000 users and run into performance problems again you could easily add a line like "WHERE successdate < xxx" or "LIMIT 1000" to the statement.
  • PocketQuery has a macro option that is called "load dynamically" so even if you run into performance problems this allows you to decouple the querying process from the macro rendering / page rendering process. The page will render normally (no timeout!) and PocketQuery will execute your query in the background. Once the result is ready PocketQuery will insert it into the page. This will even work if the query took an incredible amount of time like 10 minutes or more. But that probably shouldn't even happen.

I hope this helps! :)

Best regards,

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted in Confluence

How is your team having fun and bonding, remotely, utilizing Confluence?

Thanks everyone for answering last week’s question. The winner of the random drawing from those who commented is: @LarryBrock I’ll contact you separately with your prize details. This wee...

327 views 9 7
Join discussion

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you