EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Increase SSH Window Size to Boost SFTP Performance

Posted: 04/19/2016 21:19:35
by John Buonassisi (Basic support level)
Joined: 04/19/2016
Posts: 3

My application uses TElSimpleSFTPClient to connect to an SFTP server to upload large files at a required rate of at least 19MB/sec. My client is a C++ application build with VS2013, using SBB, .NET 4.0. I only have the evaluation license.

My current test setup involves two Windows 2008R2 servers connected via 1Gbps LAN. One server runs Cerberus SFTP Server and the other runs my application. Unfortunately, I am only able to achieve 9MB/sec upload rate. I believe the performance could be improved by increasing the SSH window size to 2GB. For some reason, the SFTP connection between my app and the server is always initialized with a window size and max packet size of 32KB (as reported by the server). I have read the following links on how to tune SSH and SFTP properties to gain performance, but none of them seem to actually cause the window size to change.


I did test another SFTP client (Win-32 OpenSSH) and it automatically connected to Cerberus SFTP with a window size of 2GB and achieved 20MB/sec upload rate.

Am I missing something on how to change the window size? Is there any other course of action to improve SFTP upload rate? Any help would be greatly appreciated.
Posted: 04/20/2016 03:23:04
by Eugene Mayevski (Team)

If you are using the default evaluation key, it has some speed restrictions, so you might want to request the unrestricted evaluation key on https://www.eldos.com/sbb/keyreq/

As for the window size, TElSimpleSFTPClient has MaxSSHPacketSize, DefaultWindowSize and MinWindowSize properties. Did you try to change them?

However, there are buffers in the SSH classes to read and write the data and they are limited to 256 Kb (hard-coded). It is possible that we would need to change this somehow, if the above settings don't work for you. It will be possible to build a test application for you to test with increased buffers, but that will be the last resort - please try the above suggestions first.

Sincerely yours
Eugene Mayevski
Posted: 04/20/2016 07:31:35
by Ken Ivanov (Team)

Hi John,

Please note that insufficient window size itself is a fairly rare reason for significant transfer slowdowns. More important contributors on SSH layer are encryption algorithm (try AES as the fastest), and compression method employed. Please check if adjusting the encryption algorithm and enabling compression help speed up the upload stream. To adjust the window, follow Eugene's advice above.

SFTP-wise some tune-up is available too. Please try increasing the throughput by adjusting the following properties (this might not work with some servers):

UploadBlockSize: 32768
PipelineLength: 32
AutoAdjustTransferBlock: false

Posted: 04/20/2016 17:24:09
by John Buonassisi (Basic support level)
Joined: 04/19/2016
Posts: 3

Thank you both for your quick response!

Upon your suggestions, here are the things I have tried.

- I set my SFTP server to log debugging information and found that the SSH Window Size is actually changed when I change the DefaultWindowSize property of TElSimpleSFTPClient. Unfortunately, by increasing the window size I did not see any performance gain.

- I set the encryption algorithm to AES_128_CRT and saw a 10% increase in SFTP upload speed, ~10MB/sec. Previously it was using AES_256_CRT. Although this is a good start, I need a 100% increase in SFTP upload speed to meet my requirements. Is there anything else I can do to boost encryption performance?

client->SetEncryptionAlgorithms(16, true)
client->SetEncryptionAlgorithmPriority(16, 1000)

- I set compression to zlib but did not see any performance increase.

client->ForceCompression = true;
client->SetCompressionAlgorithms(1, true);
client->SetCompressionAlgorithmPriority(1, 1000);

- I requested and received the unrestricted license key, however it did not improve SFTP upload performance.

- I have tried increasing/decreasing the MaxSSHPacketSize, ensuring that the size is a multiple of the DefaultWindowSize but I did not see any performance gain. I also tried increasing MinWindowSize from its default of 2KB, but it seems that makes the performance worse.

- Similarly, I have tried changing UploadBlockSize (up to 2GB), PipelineLength (64, 100, 500, 1000), and AutoAdjustTransferBlock (false) but am not seeing any performance gain. Is there any relationship between the UploadBlockSize and the MaxSSHPacketSize or DefaultWindowSize?

Could the performance issue be caused by how my application writes to the file? My application first creates/opens a file on the SFTP server with WRITE, CREATE, and TRUNC modes. It then writes processed data in 0.7MB chunks to the file using TElSimpleSFTPClient::Write(). I am curious what Write() is actually doing with the buffer that it receives? I assume it packages the data contained within the buffer into SSH packets and sends them off to the SFTP server. Is there a way to optimize the size of the buffer I am passing to Write()?
Posted: 04/21/2016 05:45:36
by Eugene Mayevski (Team)

John Buonassisi wrote:
Could the performance issue be caused by how my application writes to the file? My application first creates/opens a file on the SFTP server with WRITE, CREATE, and TRUNC modes. It then writes processed data in 0.7MB chunks to the file using TElSimpleSFTPClient::Write()

To make the long story shorter - please try the speed of TElSimpleSFTPClient's UploadStream instead for speed measurements. Once you have the results, I will explain why it is important to test that particular component (rather than you Write approach), and we will decide how to proceed.

Sincerely yours
Eugene Mayevski
Posted: 04/21/2016 16:41:35
by John Buonassisi (Basic support level)
Joined: 04/19/2016
Posts: 3

Just to clarify, our application differs slightly from a typical SFTP client. Our application processes large amounts of data in real-time and typically uses FTP to transfer the processed buffers. We aren't just taking files stored on the local file system and uploading them to a server. Now, we are required to support SFTP using the same architecture. That being said, I was able to test UploadStream in the following two ways:

1. I created a System::IO::FileStream object from a 1GB file on the local server and uploaded it to SFTP server using UploadStream. After modifying some properties of TElSimpleSFTPClient I was able to achieve an upload rate of 15MB/sec.

2. I created a System::IO::MemoryStream object from each processed buffer that our application creates. Then use UploadStream to transfer these buffers one-by-one to the SFTP server. The upload performance was the same as if I used Write().

So clearly, there is a major difference between writing buffers of data vs. uploading an entire pre-existing file.
Posted: 04/22/2016 05:27:15
by Eugene Mayevski (Team)

Thank you for the confirmation.

What TElSimpleSFTPClient does is send several "write block" requests in a row without waiting for the first one(s) to be confirmed. This makes transfer much faster. The protocol to send blocks in a row is non-trivial - you need to track underlivered blocks, avoid sending too much (i.e. wait for the first block to be completed after you send the last block in a group) etc.

For writing blocks TElSimpleSFTPClient does not use its own synchronous Write method. Instead it uses asynchronous Write() method of the underlying TElSFTPClient class.

Due to the above there exist two options:
1) you can use TElSSHClient + TElSFTPClient + the socket class of your choice and basically re-create half of TElSimpleSFTPClient
2) we can discuss the ways to extend TElSimpleSFTPClient to match your particular needs, yet it would be a custom work for a separate fee.

Sincerely yours
Eugene Mayevski



Topic viewed 3309 times

Number of guests: 1, registered members: 0, in total hidden: 0


Back to top

As of July 15, 2016 EldoS business operates as a division of /n software, inc. For more information, please read the announcement.

Got it!