FameFlower Test Results

Table of Contents

...

In this workflow we are checking the performance of the loading items on instance record (in holdings accordion) workflow running in the Fameflower release.  We will test it with 1, 5, 8, and 20 virtual users for 30 minutes.  A longevity test will also be executed to see if there were memory issues.

...

  1. Overall load items workflow time in seconds


    Average (seconds)50th %tile (seconds)75th %tile (seconds)95th %tile  (seconds)





    1 user1.0150.9614.67 s1.322
    5 users1.2361.1561.4641.704
    8 users1.5121.4031.7412.02
    20 users1.6491.5351.8962.252


  2. Slow APIs taking more than 100 ms to return

    API1 user (75th %tile)5 users (75th %tile)8 users (75th %tile)20 Users (75th %tile)
    GET source-storage/formattedRecords/{id}5.32 s19.92 s34.83 s1.46 min

    GET inventory/instances keyword all "aba"

    355.60 ms753.86 ms909.02 ms2.87 s
    POST circulation/check-out-by-barcode679.72 ms1.04 s1.11 s1.45 s
    GET inventory/items164.45 ms251.71 ms286.87 ms405.85 ms
    GET inventory/instances/{id}119.93 ms115.98 ms123.88 ms131.89 ms
    GET circulation/loans221.95 ms254.08 ms251.45 ms256.18 ms
    GET locations221.09 ms142.89 ms152.26 ms205.71 ms
    GET circulation/requests81.77 ms212.38 ms257.80 ms443.79 ms


  3. Excess logging of missing indexes - 64K lines in  45 minutes run. Logging level could be reduced to WARNING or INFO, but at the cost of having less data to work with should there be a need to troubleshoot.


  4. JVM profiling shows JSON de/serialization operations one of the slowest operations.

...

Test

Virtual Users

Duration

OKAPI log level

Profiled

Ramp up (total time

in seconds)

1. 

1

30 min

INFO

No

1

2. 

5

30 min

INFO

No

50

3. 

8

30 min

INFO

No

80

4. 

20

30 min

INFO

No

200

5. 

1

30 min

INFO

Yes

1

6. 

5

30 min

INFO

Yes

50

7. 

8

30 min

INFO

Yes

80

8. 

20

30 min

INFO

Yes

200

...

  • Overall slow methods (between the modules profiled: okapi, mod-inventory, mod-inventory-storage, mod-circulation, mod-circulation-storage)


...

There aren't any WARNING statements of missing indexes in mod-inventory-storage, mod-source-record-storage modules.

The following WARNING statements of missing indexes were generated during a test run and logged by mod-circulation-storage:

...

Slowest queries which took the most of execution time were initiated by the mod_source_record_storage, mod-inventory-storage and mod_circulation_storage services presented in the following table:


Percent of total time

Average Time,ms

Calls

Module

Query

52%20,855 ms 1,325mod_source_record_storage

select get_record_by_external_id($1, $2)

Examples:

EXPLAINANALYZEselect get_record_by_external_id('89a7ec1c-608f-4d24-90b6-57da21557874', 'instanceId')

EXPLAIN ANALYZE select get_record_by_external_id('1abdfd67-a4c3-46ba-a66b-82619f633e9a', 'instanceId')

EXPLAIN ANALYZE select get_record_by_external_id('ff2f06c1-caf7-427a-9544-d8716eda90a6', 'instanceId')

0.8%669 ms658mod_inventory_storageWITH headrecords AS ( SELECT jsonb, lower(f_unaccent(jsonb->>$1)) AS title FROM fs09000000_mod_inventory_storage.instance WHERE (to_tsvector($2, f_unaccent(concat_space_sql(instance.jsonb->>$3 , concat_array_object_values(instance.jsonb->$4,$5) , concat_array_object_values(instance.jsonb->$6,$7)))) @@ (to_tsquery($8, f_unaccent($9)))) ANDleft(lower(f_unaccent(jsonb->>$10)),$11) < ( SELECTleft(lower(f_unaccent(jsonb->>$12)),$13) FROM fs09000000_mod_inventory_storage.instance ORDERBYleft(lower(f_unaccent(jsonb->>'title')),600) OFFSET $14LIMIT $15 ) ORDERBYleft(lower(f_unaccent(jsonb->>$16)),$17) LIMIT $18OFFSET $19 ), allrecords AS ( SELECT jsonb, lower(f_unaccent(jsonb->>$20)) AS title FROM fs09000000_mod_inventory_storage.instance WHERE (to_tsvector($21, f_unaccent(concat_space_sql(instance.jsonb->>$22 , concat_array_object_values(instance.jsonb->$23,$24) , concat_array_object_values(instance.jsonb->$25,$26)))) @@ (to_tsquery($27, f_unaccent($28)))) AND (SELECTCOUNT(*) FROM headrecords) < $29 ) SELECT jsonb, title, $30AScountFROM headrecords WHERE (SELECTCOUNT(*) FROM headrecords) >= $31UNION (SELECT jsonb, title, (SELECTCOUNT(*) FROM allrecords) AScountFROM allrecords ORDERBY title LIMIT $32OFFSET $33 ) ORDERBY title
0.8%214 ms1,918mod_circulation_storageSELECT COUNT(*) FROM (SELECT jsonb,id FROM fs09000000_mod_circulation_storage.request WHERE (to_tsvector($1, f_unaccent(request.jsonb->>$2)) @@ replace((to_tsquery($3, f_unaccent($4)))::text, $5, $6)::tsquery) AND (to_tsvector($7, f_unaccent(request.jsonb->>$8)) @@ replace((to_tsquery($9, f_unaccent($10)))::text, $11, $12)::tsquery) LIMIT $13) x
0.6%177 ms1,914mod_inventory_storageSELECTCOUNT(*) FROM (SELECT jsonb,idFROM fs09000000_mod_inventory_storage.item WHERElower(f_unaccent(item.jsonb->>$1)) LIKElower(f_unaccent($2)) LIMIT $3) x
0.6%165 ms1,914mod_inventory_storageSELECT jsonb,idFROM fs09000000_mod_inventory_storage.item WHERElower(f_unaccent(item.jsonb->>$1)) LIKElower(f_unaccent($2)) LIMIT $3OFFSET $4
0.4%1,299 ms159mod_inventory_storageEXPLAINANALYZEWITH headrecords AS ( SELECT jsonb, lower(f_unaccent(jsonb->>'title')) AS title FROM fs09000000_mod_inventory_storage.instance WHERE (to_tsvector('simple', f_unaccent(concat_space_sql(instance.jsonb->>'title' , concat_array_object_values(instance.jsonb->'contributors','name') , concat_array_object_values(instance.jsonb->'identifiers','value')))) @@ (to_tsquery('simple', f_unaccent('''aba''')))) ANDleft(lower(f_unaccent(jsonb->>'title')),600) < ( SELECTleft(lower(f_unaccent(jsonb->>'title')),600) FROM fs09000000_mod_inventory_storage.instance ORDERBYleft(lower(f_unaccent(jsonb->>'title')),600) OFFSET10000LIMIT1 ) ORDERBYleft(lower(f_unaccent(jsonb->>'title')),600) LIMIT100OFFSET0 ), allrecords AS ( SELECT jsonb, lower(f_unaccent(jsonb->>'title')) AS title FROM fs09000000_mod_inventory_storage.instance WHERE (to_tsvector('simple', f_unaccent(concat_space_sql(instance.jsonb->>'title' , concat_array_object_values(instance.jsonb->'contributors','name') , concat_array_object_values(instance.jsonb->'identifiers','value')))) @@ (to_tsquery('simple', f_unaccent('''aba''')))) AND (SELECTCOUNT(*) FROM headrecords) < 100 ) SELECT jsonb, title, 0AScountFROM headrecords WHERE (SELECTCOUNT(*) FROM headrecords) >= 100UNION (SELECT jsonb, title, (SELECTCOUNT(*) FROM allrecords) AScountFROM allrecords ORDERBY title LIMIT100OFFSET0 ) ORDERBY title

CPU Utilization


1 user5 users8 users20 users

Average %Range %Average %Range %Average %Range %Average %Range %
Okapi2.120.29-8.942.871.56-13.652.780.31-16.822.850.32-11.65
mod-inventory0.840.31-14.820.680.30-4.010.670.26-7.790.650.27-3.72
mod-inventory-storage1.590.33-8.171.870.56-9.251.810.24-9.151.780.25-23.28
mod-circulation0.670.24-4.120.820.48-4.440.960.26-4.040.820.28-4.12
mod-circulation-storage0.710.25-6.600.740.31-2.790.860.29-3.270.710.27-2.50
mod-source-record-storage0.340.23-1.430.500.26-1.860.530.31-2.410.430.29-1.92

...


1 user5 users8 users20 users

AverageAverageAverageAverage
Okapi40%42%40%40%
mod-inventory40%43%44%43%
mod-inventory-storage40%40%41%41%
mod-circulation72%75%72%74%
mod-circulation-storage32%32%32%32%
mod-source-record-storage53%53%53%53%


Appendix

See Attached FameFlower Performance Test Runs.xlsx for details