Load Testing
Load Testing is a type of Performance Testing used to determine a system's behavior under both normal and peak conditions. Load Testing is used to ensure that the application performs satisfactorily when many users access it at the same time.
A Load test is useful for:
- Assessing the current performance of the system under typical and peak load.
- Make sure the system continue to meet the performance standards as changes are made.
Ajaib DeX Backend Load Testing
For Ajaib DeX, we need to assess its performance by load testing because we do a lot of third-party API calls. While we believe that our server architecture is sufficient to handle our normal load, there are some concerns with regard to these third-party API calls. Therefore, we are going to load test our main endpoint (/wallet/{address}/returns
) that calls third-party API to get transaction history and to calculate return using this history.
Implementation
For the load testing, we are using Grafana k6 and its k6 cloud service. In order to use this tool, we need to define a testing script for the executor to run. Here is the script we need to define for our load testing:
// load-test-ajaib-k6.js
// Scenario: Load_Test (executor: ramping-vus)
import { sleep, check } from 'k6'
import http from 'k6/http'
export const options = {
ext: {
loadimpact: {
distribution: { 'amazon:us:ashburn': { loadZone: 'amazon:us:ashburn', percent: 100 } },
apm: [],
},
},
thresholds: {},
scenarios: {
Load_Test: {
executor: 'ramping-vus',
gracefulStop: '30s',
stages: [
{ target: 20, duration: '30s' },
{ target: 20, duration: '1m30s' },
{ target: 0, duration: '30s' },
],
gracefulRampDown: '30s',
exec: 'load_Test',
},
},
}
export function load_Test() {
let response
// Get Wallet Returns
response = http.get(
'https://staging.ajaib.me/wallet/0xD0c0697562274d81A64dCA58ca175e8A480bA0f7/returns'
)
const statusString = response.status.toString()
if (statusString === '500') {
console.error(response)
}
check(response, { 'status equals 200': response => statusString === '200' })
// Automatically added sleep
sleep(1)
}
As the code above illustrates, we are simply doing a GET request to the endpoint and checking its HTTP status code. The interesting part here is the gradual rampup to 20 virtual users as supplied by k6.
Result & Interpretation
As the results above show, the API endpoint we have now is problematic. As the second image show, the API can respond quite well for low amount of reqs/s but cannot go above 4/5 reqs/s.
After some investigation, we figured out that this is because of BSCScan API limit which limits the API call to 5 requests per seconds. Therefore, we are now currently evaluating solutions to solve this problem that our load testing shows.