Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

With the addition of new query param (i.e. requested_fields=profile_image) to discussion API GET endpoints for thread and comment; the discussion APIs got exposed to the possibility of performance degradation because this new param fetches and prepares the profile image related data of all the users that are participating in thread or comment.

We have gathered and compared two sets of load test results. The former results (i.e. with profile_image) are run on the latest changes and the later are run on older implementation (i.e. without profile_image).

There appears to be anomaly in the results below (highlighted 99%) where the new implementation is faster than the old. Where as, for other results the percentile of new implementation increases significantly with the increase in load. For example, the first pair of results where no. of clients = 48, the difference is in tens or hundrend and for the last pair of results where no. of clients = 610, the difference is in thousands.

Logically; there should only be increase in response time for GET endpoints, but we see in results that all other endpoints show differences too. This is because all PATCH, POST and DELETE endpoints first call GET endpoint to retrieve an 'id' of thread and/or comment and then make further processing on it.

New Relic:

Here is the new relic permaLink_without_profile and permaLink_with_profile where the average rpm for former is 1.55k and for later is 1.48k and 84.5% of requests are made for AccountViewSet.list (i.e. user accounts API for multiple usernames) for later.

 

...

With Profile Image

...

Without Profile Image

...

No. of clients = 
req/s = 
Methodsmedian response time95%99%
    

DELETE_comment

 

  

DELETE_thread

 

  

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s =
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%
DELETE_comment

 

  
DELETE_thread   
GET_comment_list   
GET_thread   
GET_thread_list   
PATCH_comment   
PATCH_thread   
POST_comment_comment   
POST_comment_response   
POST_thread   
auto_auth   
No. of clients = 
req/s = 
Methodsmedian response time95%99%
DELETE_comment   
DELETE_thread   
GET_comment_list   
GET_thread   
GET_thread_list   
PATCH_comment   
PATCH_thread   
POST_comment_comment   
POST_comment_response   
POST_thread   
auto_auth   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   
No. of clients = 
req/s = 
Methodsmedian response time95%99%

DELETE_comment

   

DELETE_thread

   

GET_comment_list

   

GET_thread

   

GET_thread_list

   

PATCH_comment

   

PATCH_thread

   

POST_comment_comment

   

POST_comment_response

   

POST_thread

   

auto_auth

   

Background:

In reference to 

Jira Legacy
serverJIRA (openedx.atlassian.net)
serverId13fd1930-5608-3aac-a5dd-21b934d3a4b4
keyMA-2678
; we have changed forums implementation with following details (for reference; see PR#192):

  1. Changed post/response/comment behaviour to update post's 'last_activity_at' only at time of creation of post and creation of response/comment on a post. Previously post's 'last_activity_at' was being updated for both creation and update.
  2. To calculate 'read' status of a post, used 'last_acitvity_at' instead of 'updated_at'.
  3. To calculate 'unread comment count' for a post, used 'created_at' instead of 'updated_at'.

'unread comment count' was being calculate as:

unread_comment_count = Comment.collection.find(:comment_thread_id => t._id, :author_id => {"$ne" => user.id}, :updated_at => {"$gte" => read_dates[thread_key]}).count

and had a compound index against it
index({_type: 1, comment_thread_id: 1, author_id: 1, updated_at: 1})
 

With new implementation:

unread_comment_count = Comment.collection.find(:comment_thread_id => t._id, :author_id => {"$ne" => user.id}, :created_at => {"$gte" => read_dates[thread_key]}).count

So, we removed index
index({_type: 1, comment_thread_id: 1, author_id: 1, updated_at: 1})

and added a new one

index({comment_thread_id: 1, author_id: 1, created_at: 1})

Results:

The load tests were run on 4x c4.2xlarge instances for lms and 3x m4.large instances for forums.

The results of load tests below show differences between the old and new implementation. The two set of results looks quite similar except when it reaches "No. of clients = 336"; where there is huge difference between old and new percentiles as well as sudden rise in percentile for both old and new index with respect to "No. of clients = 224". For all the next tests (i.e. No. of clients = 460, No. of clients = 510, No. of clients = 578), the difference between old and new percentile is minimised and the new index results have lower percentile for most of the endpoints.

I have captured new relic charts too; permaLink_old_index with average rpm = 1.86k and permaLink_new_index with average rpm = 1.81k


                                                                                                                                                    list                                                                                                                                                                   POST                                 POST         

Old Index

New Index

No. of clients = 48
req/s = 9.4
Methodsmedian response time95%99%

DELETE_comment

 

250

 
310 1200

DELETE_thread

 

160

 
190 200

GET_comment_list

 150 190 310

GET_thread

 140 180 220

GET_thread_list

 160 370 520

PATCH_comment

 230 360 1200

PATCH_thread

 190 240 370

POST_comment_comment

 290 360 430

POST_comment_response

 250 310 450

POST_thread

 160 190 200

auto_auth

 200 250 250
No. of clients = 48
req/s =  8.9
          
Methodsmedian response timemedian response time95%95%99%99%

DELETE_comment

  

250270300470480520

DELETE_thread

  

170160210300230310

GET_comment_list

  

150160200260320350

GET_thread

  

150150190250280310

GET_thread_list

  

list

170190360370520530

PATCH_comment

  

220240320400410460

PATCH_thread

  

180190360300330330

POST_comment_comment

  290310340510490680

POST_comment_response

   

POST_thread

  

250260300450390520

POST_thread

160160200250370340

auto_auth

  

220210230230230230


No. of clients = 96
req/s = 18.5
Methodsmedian response time95%99%
DELETE_comment

270

340
390
DELETE_thread
170
230
330
GET_comment_list
170
210
330
GET_thread
160
200
250
GET_thread_list
190
440
610
PATCH_comment
240
330
360
PATCH_thread
200
260
350
POST_comment_comment
310
380
470
POST_comment_response
260
330
440
POST_thread
170
210
340
auto_auth
180
220
220


No. of clients = 96
req/s = 18.6
Methodsmedian response timemedian response time95%95%99%99%
DELETE_comment
  
270280340360360980
DELETE_thread
  
170170220230230290
GET_comment_list
  
160160210220340400
GET_thread
  
160160200210270340
GET_thread_list
  
190190460460600640
PATCH_comment
  
220230310310340460
PATCH_thread
  
1902002602803501000
POST_comment_comment
  
300310370410480680
POST_comment_response
  
260260330350420620
POST_thread
  
170170210210340330
auto_auth
  
180210230220230220


No. of clients = 162
req/s = 31
Methodsmedian response time95%99%

DELETE_comment

 320 400 490

DELETE_thread

 190 240 280

GET_comment_list

 190 250 370

GET_thread

 190 250 340

GET_thread_list

 220 520 660

PATCH_comment

 270 360 390

PATCH_thread

 230 310 370

POST_comment_comment

 350 450 540

OSTPOST_comment_response

 300 400 490

POST_thread

 190 240 340

auto_auth

 200 200 200


No. of clients = 162
req/s = 
Methods
31.6
OST
Methodsmedian response timemedian response time95%95%99%99%

DELETE_comment

   

310320410420590530

DELETE_thread

   

190190240230250250

GET_comment_list

   

190190250250380380

GET_thread

   

180180250250360340

GET_thread_list

   

220210530520670660

PATCH_comment

   

2602503803601400430

PATCH_thread

   

220230280310400370

POST_comment_comment

   

340340450470540620

POST_comment_response

   

290290400400510550

POST_thread

   

190190240230370360

auto_auth

   

210200220200220200


No. of clients = 240
req/s = 44.6
Methodsmedian response time95%99%

DELETE_comment

 400 600 700

DELETE_thread

 240 320 530

GET_comment_list

 240 350 480

GET_thread

 240 360 470

GET_thread_list

 270 630 800

PATCH_comment

 330 510 600

PATCH_thread

 290 420 530

POST_comment_comment

 420 640 820

POST_comment_response

 360 560 730

POST_thread

 240 310 440

auto_auth

 210 210 210


No. of clients = 240
req/s = 45.40
list
Methodsmedian response timemedian response time95%95%99%99%

DELETE_comment

   

39041065069013001100

DELETE_thread

   

240230370280430340

GET_comment_

   

list

230240350350500480

GET_thread

   

230240370370600520

GET_thread_list

   

270270640630850790

PATCH_comment

   3003104904801200610

PATCH_thread

   

280290460470640630

POST_comment_comment

   4104306706601000970

POST_comment_response

   

360360560600860850

POST_thread

   

230230300310500430

auto_auth

   

190210220220220220



No. of clients = 270
req/s = 51.1
Methodsmedian response time95%99%

DELETE_comment

560
7900
10000

DELETE_thread

280
620
5200

GET_comment_list

300
3100
4000

GET_thread

310
3400
5000

GET_thread_list

330
3000
4200

PATCH_comment

400
1700
6500

PATCH_thread

380
5100
6300

POST_comment_comment

560
7900
10000

POST_comment_response

470
6100
8200

POST_thread

290
2900
3900
auto_auth
320
320
320

No. of clients = 300
req/s = 48
Methodsmedian response time95%99%

DELETE_comment

1600
4600
5900

DELETE_thread

460
1600
2500

GET_comment_list

480
1300
1900

GET_thread

560
2100
2900

GET_thread_list

530
1700
2500

PATCH_comment

800
2800
3500

PATCH_thread

710
2700
3600

POST_comment_comment

1400
4300
5500

POST_comment_response

1000
3600
4800

POST_thread

430
1100
1700
auto_auth
240
250
250
No. of clients = 336
req/s = 53
Methodsmedian response time95%99%

DELETE_comment

2500
5500
6500

DELETE_thread

980
2300
2900

GET_comment_list

800
2100
2700

GET_thread

920
2700
3300

GET_thread_list

850
2400
3300

PATCH_comment

1500
3900
5000

PATCH_thread

1200
3400
4100

POST_comment_comment

2300
5400
7000

POST_comment_response

1700
4400
5900

POST_thread

740
2000
2700

auto_auth

330
1300
1300


No. of clients = 336
req/s =
 54.3
Methodsmedian response timemedian response time95%95%99%99%

DELETE_comment

  

15005300920096001200011000

DELETE_thread

  

47023004100460067005100

GET_comment_list

  

51018005000370068004500

GET_thread

  

59021006500480099005700

GET_thread_

  

list

58018004900390068004800

PATCH_comment

  

81035007600640011009700

PATCH_thread

  

79029005400630078007300

POST_comment_comment

  
13004800930093001200011000

POST_comment_response

  

1000370077007800100009600

POST_thread

  
47017004600350064004000

auto_auth

  

320710320830320830


No. of clients = 460
req/s = 44.5
Methodsmedian response time95%99%

DELETE_comment

5600
9800
12000

DELETE_thread

3700
6200
7900

GET_comment_list

3700
6100
8100

GET_thread

5200
9800
13000

GET_thread_list

3700
6800
8600

PATCH_comment

4800
7900
9500

PATCH_thread

4600
7300
9900

POST_comment_comment

5500
9300
11000

POST_comment_response

5000
8300
10000

POST_thread

3500
6000
9200

auto_auth

2000
2600
2600


No. of clients = 460
req/s = 49.1
Methodsmedian response time95%99%

DELETE_comment

6100
10000
11000

DELETE_thread

3500
5700
6400

GET_comment_list

3000
5000
5700

GET_thread

4200
7100
8700

GET_thread_list

3100
5300
6200

PATCH_comment

4400
7800
8600

PATCH_thread

4100
6900
7600

POST_comment_comment

5700
9900
11000

POST_comment_response

4800
8500
10000

POST_thread

3000
4800
5500

auto_auth

1700
2700
2700


No. of clients = 510
req/s = 32.4
Methodsmedian response time95%99%

DELETE_comment

7700
15000
27000

DELETE_thread

5400
12000
15000

GET_comment_list

6300
14000
31000

GET_thread

8600
19000
36000

GET_thread_list

6400
14000
32000

PATCH_comment

7000
14000
25000

PATCH_thread

6900
16000
35000

POST_comment_comment

7400
15000
36000

POST_comment_response

7000
14000
26000

POST_thread

6000
11000
32000

auto_auth

2900
4000
4400


No. of clients = 510
req/s = 33.9
Methodsmedian response time95%99%

DELETE_comment

7600
14000
19000

DELETE_thread

6700
11000
14000

GET_comment_list

6700
11000
16000

GET_thread

9400
16000
22000

GET_thread_list

7000
11000
17000

PATCH_comment

6900
12000
16000

PATCH_thread

6900
12000
21000

POST_comment_comment

7600
14000
19000

POST_comment_response

7200
13000
18000

POST_thread

6700
11000
15000

auto_auth

2400
3200
3300


No. of clients = 578
req/s = 26.70
Methodsmedian response time95%99%

DELETE_comment

9500
26000
32000

DELETE_thread

8700
25000
32000

GET_comment_list

8600
22000
31000

GET_thread

13000
27000
40000

GET_thread_list

8600
22000
32000

PATCH_comment

8800
22000
32000

PATCH_thread

8800
20000
29000

POST_comment_comment

9200
24000
31000

OST_comment_response

9300
24000
32000

POST_thread

8300
20000
32000

auto_auth

3600
5200
5500


No. of clients = 578
req/s = 40.2
Methodsmedian response time95%99%

DELETE_comment

9100
24000
32000

DELETE_thread

8500
22000
26000

GET_comment_list

8100
22000
32000

GET_thread

12000
26000
40000

GET_thread_list

8300
22000
32000

PATCH_comment

8300
23000
31000

PATCH_thread

8000
23000
28000

POST_comment_comment

9000
24000
32000

OST_comment_response

8500
23000
32000

POST_thread

8300
22000
32000

auto_auth

4100
5100
5400