Optimizing API Performance in PowerShell Universal

PowerShell Universal API Performance

October 9, 2023

quote Discuss this Article

PowerShell Universal allows for users to create APIs using PowerShell. These APIs can be used to create webhooks, integrate with other systems or provide a REST API for your PowerShell scripts. In this post, we’ll look at some improvements you can make to improve API performance.

In this post, we’ve used West Wind WebSurge to test API performance. This tool allows you to send a number of requests to a URL and measure the performance of the requests. We are running a 60 second test with 10 threads.

For this test, we are running an unlicensed version of PowerShell Universal with a single API endpoint. The API endpoint is a simple script that returns a string.

New-PSUEndpoint -Url "/hello" -Method @('GET') -Endpoint {
    "hello"
}

We are using LiteDB for persistence.

Update to 4.1.5 or later

The first thing you can do is update to PowerShell Universal 4.1.5 or later. This version includes a number of performance improvements to the API system. We see about a 300% improvement in API performance with this release with default settings.

Results

Adjust Logging Targets and System Log Settings

By default, PowerShell Universal has verbose logs configured. We will make the following changes to the logging configuration.

Disable Verbose System Logs

In appsettings.json, set the SystemLogLevel to Error rather than verbose.

{
    "SystemLogPath": "%ProgramData%\\PowerShellUniversal\\systemLog.txt",
    "SystemLogLevel": "Error"
}

Disable User Scope Logging for APIs

Rather than sending log messages to the database and file system, we will disable user scope logging for APIs. You can send log messages for specific features, such as Apps.

New-PSULoggingTarget -Type "Database" -Properties @{
} -Feature "App"

New-PSULoggingTarget -Type "File" -Properties @{
    path = "C:\ProgramData\PowerShellUniversal\log.txt"
} -Feature "App"

It’s also possible to reduce the log level for targets rather than disable them completely.

New-PSULoggingTarget -Type "Database" -Properties @{
} -Level "Error"

New-PSULoggingTarget -Type "File" -Properties @{
    path = "C:\ProgramData\PowerShellUniversal\log.txt"
} -Level "Error"

Results

Environment Settings

Certain features of PowerShell Universal environments can impact performance. We will make the following changes to the environment settings.

Persistent Runspaces

Resetting the runspace state takes time so avoiding this can improve performance. Note that persistent runspaces keep the value of variables, functions and aliases defined within the execution of the endpoint. Depending on the implementation of your endpoint, this may not be desirable.

Increase Max Runspaces

By default, PowerShell Universal will create 25 runspaces per environment. We will increase this to 100. This will increase memory usage but will slightly improve performance.

New-PSUEnvironment -Name "Integrated" -Version "7.3.6" -Path "Universal.Server" -Variables @('*') -PersistentRunspace -MaxRunspaces 100 -Description "An environment for running scripts directly in the PowerShell Universal server." 

Results

A note on external environments

Above, you may notice that we are using the Integrated environment. This is an environment that is built into PowerShell Universal. It is a PowerShell environment that runs directly in the PowerShell Universal process. Even if we were to adjust the endpoints to use an external environment, the results are similar. This is running within a PowerShell 7.3.7 environment.

Use SQL Persistence

SQL persistence can greatly improve API throughput. This test was performed against a local SQL database with all the above settings configured and only run on version 4.1.5.

Results

Conclusion

With these changes, we’ve improved the performance of our API by ~1,900%. We’ve gone from 150 requests a second to 3,000 requests a second. Using SQL persistence had the greatest increase on performance. Particularly combined with changes to the logging system, you can achieve a significant increase in performance.