Adding Veil2 to your database introduces 2
    specific overheads to  your database performance.
    
      In order to get a feel for the overheads associated with
      Veil2, we need some realistic volumes of
      data for roles, privileges, and accessors with their associated
      mappings.  The script, demo_bulk_data.sql,
      which can be found as described here provides a good starting point
      for this.
    
After creating a demo database (as described here) you can install this data using psql, eg:
marc:veil2$ psql -d vpd -f /usr/share/postgresql/12/veil2/demo_bulk_data.sql 
      
This will create around 8000 accessors, around 300 roles, and around 2000 privileges, which should be enough to exercise the privilege testing and session management functionality.
      The two biggest overheads in session management are the use of
      bcrypt() for authentication (which is
      CPU-intensive by intent), and the loading of session
      privileges.  In the following evaluation,
      bcrypt() is avoided. 
    
      Session privileges once loaded (from veil2.session_privileges_v
      are cached (in veil2.accessor_privileges_cache).
      This means that subsequent loading of privileges should be
      considerably faster than the initial one for each accessor.
    
      A simple performance checking script perf.sql
      is provided in the same directory as the bulk data loading
      script.  Assuming the same directory as the example above you
      would run it as follows:
      
marc:veil2$ psql -d vpd -f /usr/share/postgresql/12/veil2/perf.sql 
Creating sessions: elapsed = 16 milliseconds.
Opening sessions: elapsed = 54 milliseconds.
Re-opening sessions: elapsed = 61 milliseconds.
marc:veil2$ 
      
The script creates 6 sessions, opens each of them, and then re-opens them. The elapsed times shown are cumulative, in this case giving the time to open and initialize the sessions as being approximately 40 milliseconds (~7 milliseconds each), with the session reloads taking about 7 milliseconds (~1.2 milliseconds each).
This is on an aging desktop PC with the following CPU spec:
vendor_id	: GenuineIntel
cpu family	: 6
model		: 58
model name	: Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz
stepping	: 9
microcode	: 0xc
cpu MHz		: 3411.376
cache size	: 6144 KB
      
It may be possible to further improve the performance by implementing more of the session management functions in C, though initial experiments yielded only minor gains which, given the loss in flexibility resulting from a C implementation, were not felt to be worthwhile.
Until anyone claims otherwise, the author is going to claim that this is fast enough.
For testing the overhead of running privilege tests, you should load the performance evaluation data as described above.
      The script perf2.sql sets up 3 identical
      tables for performance testing, and runs some simple queries.
      The tables are:
      
x;
This table has no security policy.
y;
	    This table has a minimal security policy, calling veil2.always_true().
	  
z.
	    This table has a security policy using veil2.i_have_global_priv().
	  
Here is the transcript of a performance testing run:
marc:veil2$ psql -d vpd -f  /usr/share/postgresql/12/veil2/perf2.sql
Setting up tables...
connecting as Alice...
31|7argrXo++w024hrMnrRwUAnZwvb4i/DN8ZFbF0MMjcg=||t|
Time: 24.037 ms
running tests...
...on x (3 times)...
1995
Time: 0.521 ms
1995
Time: 0.292 ms
1995
Time: 0.265 ms
...on y (3 times)...
1995
Time: 0.520 ms
1995
Time: 0.292 ms
1995
Time: 0.283 ms
result_counts (to keep us honest):
0|0
Time: 0.131 ms
...on z (3 times)...
1995
Time: 0.499 ms
1995
Time: 0.341 ms
1995
Time: 0.302 ms
result_counts again:
0|5985
Time: 0.079 ms
marc:veil2$ 
      
What this shows is that queries for table z have little more overhead than table y, which has the smallest possible overhead for a table with a security policy. Based on all of this, the author is going to claim that this is pretty damn fast.
      Since these results look too good to be true, we perform a query
      of veil2.result_counts() which shows the
      number of false and true results from the privilege testing
      functions.  This should be seen as proof that the privilege
      tests were actually performed.  Obviously, you can repeat this
      yourself.
    
	The tests above only test
	veil2.i_have_global_priv(), which is the
	simplest of the privilege testing functions.  While this may
	seem to be a cheat, testing privileges in other scopes is
	just as fast as testing in the global scope.
      
That said, those functions that check for privileges in superior scopes, run a query to discover the appropriate superior scopes, and so incur more overhead. Experience suggests that this will still be easily dwarfed by any fetches from uncached rows.
If your application uses a lot of superior scope tests, or those queries are used on large numbers of records, you should run your own tests to ensure that performance is adequate. If not you may need to perform some denormalizations to record the appropriate superior scope in each row.
Even with this caveat though, the author is still going to claim that it's fast.