Clojure FOR BI PROS Tableau
When to avoid Tableau REST API: single vs multithread vs database
August 3, 2015
, , , ,

Tableau Server REST API is a relatively new feature in Tableau Server. It has must-have functions for publishing data sources and workbooks in addition to the usual CRUD functionality like getting users, groups and projects. However, like every new thing it has its own limitations: it’s terribly slow when you need to obtain information for individual objects like users or groups. In these cases it’s better to fall back to direct repository connection – which isn’t the best option for multi-tenant installation for obvious security reasons. In the following post I will show you where the API needs to be improved, how it can be used and what alternate ways are available to workaround these issues.

First of all let’s start from a real life use case.

The use case

Tableau 9.0 has a new web UI. The old was ugly and too 90’s but at it least it was ergonomic. The new looks are cool but from and administrative perspective it’s an ergonomic nightmare.

On a larger environment we usually have 5-600 groups and if I want to check my group memberships then it takes forever.

I need to scroll 30-40 pages and memorize my groups. Baaaaaad.

I need to scroll 30-40 pages and memorize my groups. Baaaaaad.

On this panel I cannot sort by “groups where I have access”, frankly sayin’ I have no way to sort things at all. I need to scroll down hundreds of groups while memorizing them. Bad, bad Tableau 9 admin UI.

No issues, let’s write a small app which takes users as parameters and prints their groups.

Version 1.0 with clj-tableau

I made a small library (clj-tableau) which partially implements the Tableau Server REST API. You can find it on github or on clojars. The first issue with our program is

The REST API does not have any function which returns a user’s group memberships.

This will lead to some sad consequences, discussed later. As an alternate solution we can:

  • Query all groups
  • List all users in these groups
  • Filter for our target users

Based on that this is the initial version of our “get the groups for the users” app:

Just for the record:

  • with-tableau-rest-api  logs in to the server
  • get-groups-on-site  gets the group ids and names for the tableau server groups
  • get-filtered-users-in-group  iterates on all groups and filters our users
  • build-map-with-user-group  prints the output

When I execute it shows:

What? 345 seconds? Like six minutes? For getting two user’s group information? Well, this is a big NO for version 1.0.

Version 2.0 – Multi-threading

We are living in 2015, thus, we do not use single threaded programs anymore. Period. If you are not using all of your resources (CPU cores) you are doing it wrong. Fortunately with modern programming languages you do not have to care about locking, threading or semaphoring. Everything is done by the language. Clojure is not an exception, thus, we need to change only one character to execute our application on multiple threads.

Please note that we changed map to pmap in line 28. Since in clojure you do not have variables and everything is immutable you don’t have to care about multi-threading issues. Everything will be okay.

After execution it shows:

The execute time went done from ~6 minutes to ~2 minutes. This is way better (thank you multi-threading and clojure) but still slow.

Version 3.0 – Forget REST API, use repository

Moment of truth: when I execute the query to get users and their groups :

Less than a second. Fast. Or maybe super-fast.


As we see there are some use cases where Tableau Server REST API is just not fast enough. For publishing and managing sites it’s okay but if you need to query user, group or project information for a few objects it’s always faster to use Tableau Server direct repository connection.

On the other hand direct connection allows you to access the complete data set for all sites – which is probably a no-go for multi-tenant deployments.

If you are looking for a good way to interact with Tableau Server REST API you can use my clj-tableau clojure library. Since it follows the functional programming paradigm you can make parallel multi-threaded programs with almost zero efforts.

And yes, Tableau, please please please fix the group selection UI to make the administration as easy as it was in 8.x.

Tamás Földi

Related items

/ You may check this items as well

sync frelard

Tableau Extensions Addons Introduction: Synchronized Scrollbars

At this year’s Tableau Conference, I tried t...

Read more

Tableau External Services API: Adding Haskell Expressions as Calculations

We all have our own Tableau Conference habits.  M...

Read more
Scaling Tableau Image

Scaling out Tableau Extracts – Building a distributed, multi-node MPP Hyper Cluster

Tableau Hyper Database (“Extract”) is ...

Read more