Performance Improvements in APIs
Case Study
1. Title:
Performance Improvements in APIs
2. Sub-Title:
Significant improvement in the API responses after effectively changing the query structure.
3. Client Background
DWP Global Corp, a pioneer in Legacy application modernization services worked closely with a UK based company who is a leader in ground penetration detection devices. The client had legacy applications build on Microsoft Technologies which also used non-relational databases like MongoDB along with Azure Active Directory.
4. Challenges:
- Modernizing the Legacy Applications
- Improving the Application performance through effectively querying the Data bases.
- Fetch the data from multiple databases.
Detailed Description of the Problem Statement:
Requirements:
In the client’s application User Interface, the list of all users is to be displayed in a grid with a default sorting option. License, First Name, Last Name, User Name, Role, Time/Date Filter, and Account Status were few fields on the filter. Based on the application of the selected filter elements, the system shall display the results in a gird format.
Description:
The legacy application deployed an API service that has to retrieve the data from the Database (i.e., MongoDB and Azure Active Directory). The requirement was to retrieve a list of users who are in both MongoDB and Azure Active Directory. As we have sorting and filters on User Interface, an endpoint with the POST method was implemented to retrieve data from the database. When tested for efficiency in local environment, the implemented endpoint POST method took 31.40 seconds to retrieve just 99 records. Thus making the application tedious and slow.
5. Solution
1. Bearer Token:
Every time the API made a call to the Microsoft endpoint to generate a new token. This token expires every one hour. Hence there was a need to call this endpoint and store the token in local variable to re-use it within 1 hour. This was we could reduce the Microsoft endpoint execution times in an hour for token generation.
Before changes: 3 seconds (each time execution)
After changes: 0 seconds
2. Calling the DB Multiple Times:
Multiple calls were made to MongoDB to get data specific records. This led to lower performance of APIs. Hence, instead of making multiple calls to the database, we could modify the query which would make just one single call to get all records from MongoDB / Azure AD and store it in a local variable. Used local variable whereverrequired with LINQ query on specific user id. A script “UsersValidFromAD“ was designed to frequently retrieve data from Azure AD. This wasconfigured in AppSetting file.
Before changes: 2 seconds (each time execution)
After changes: 0 seconds
3. To List ( ) in MongoDB query:
Once a query is properly built with all filters and sorting then we used ToList () on the query to retrieve a list of records.
Before changes: 7 seconds
After changes: 3 seconds
4. Find in LINQ query:
Indexing will not work for the Find method on MongoDB collection, so we preferred to use the Where Method.
Before changes: 4 seconds
After changes: 1 seconds
API Execution Times:
Environment | No. of Records | Before Code changes | |||||
First | Second | Third | Fourth | Fifth | Average | ||
Local | 99 | 51.96 | 31.4 | 34.8 | 31.08 | 32.07 | 36.262 |
Dev | 7.38 | 4.45 | 4.08 | 4.46 | 4.86 | 5.046 | |
QA | 245 | 9.36 | 8.05 | 8.12 | 7.88 | 8.18 | 8.318 |
Environment | After code changes | ||||||
No. of Records | Second | Third | Fourth | Fifth | Sixth | Average (from 2nd to 6th executions) | |
Local | 99 | 3.09 | 2.61 | 2.39 | 3.02 | 2.41 | 2.704 |
Dev | 1.314 | 1.44 | 1.06 | 1.7 | 1.79 | 1.4608 | |
QA | 245 | 1.4 | 1.09 | 0.855 | 0.814 | 0.85 | 1.0018 |
Load Test:
POST {{base_url}}/v1/API_ServiceName/users
Performance testing for above endpoint using JMeter and below are the Performance test results.
6. Key benefits:
- Bearer Token:
Before changes: 3 seconds (each time execution)
After changes: 0 seconds
- Calling the DB Multiple Times:
A single call was made to both MongoDB and Azure AD to retrieve and store the data in a local variable.
Before changes: 2 seconds (each time execution)
After changes: 0 seconds
- To List () in MongoDB query:
Before changes: 7 seconds
After changes: 3 seconds
- Find in LINQ query:
Before changes: 4 seconds
After changes: 1 seconds
7. Factors that contributed to Performance Improvement:
Below are the steps that were followed to improve the Performance
1. Logs: Implemented logs to find the code where it takes more time in execution.
2. In detailed Logs: Based on logs, we go into deep logs which methods take more time in execution.
3. Identifying a line of code that takes more time in execution: Identifying which line of code takes more time in execution ,to enhance the performance of those lines.
4. Alternative solution: Looking for alternative ways to improve performance on Identified lines.
5. Verify logs after changes: Need to check logs after code change whether execution time is reduced or not.